Linux Audio

Check our new training course

Loading...
v3.1
   1/**
 
   2 * omap-usb-host.c - The USBHS core driver for OMAP EHCI & OHCI
   3 *
   4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com
   5 * Author: Keshava Munegowda <keshava_mgowda@ti.com>
   6 *
   7 * This program is free software: you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2  of
   9 * the License as published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19#include <linux/kernel.h>
  20#include <linux/module.h>
  21#include <linux/types.h>
  22#include <linux/slab.h>
  23#include <linux/delay.h>
  24#include <linux/platform_device.h>
  25#include <linux/clk.h>
  26#include <linux/dma-mapping.h>
  27#include <linux/spinlock.h>
  28#include <linux/gpio.h>
  29#include <plat/usb.h>
 
 
 
 
 
  30
  31#define USBHS_DRIVER_NAME	"usbhs-omap"
  32#define OMAP_EHCI_DEVICE	"ehci-omap"
  33#define OMAP_OHCI_DEVICE	"ohci-omap3"
  34
  35/* OMAP USBHOST Register addresses  */
  36
  37/* TLL Register Set */
  38#define	OMAP_USBTLL_REVISION				(0x00)
  39#define	OMAP_USBTLL_SYSCONFIG				(0x10)
  40#define	OMAP_USBTLL_SYSCONFIG_CACTIVITY			(1 << 8)
  41#define	OMAP_USBTLL_SYSCONFIG_SIDLEMODE			(1 << 3)
  42#define	OMAP_USBTLL_SYSCONFIG_ENAWAKEUP			(1 << 2)
  43#define	OMAP_USBTLL_SYSCONFIG_SOFTRESET			(1 << 1)
  44#define	OMAP_USBTLL_SYSCONFIG_AUTOIDLE			(1 << 0)
  45
  46#define	OMAP_USBTLL_SYSSTATUS				(0x14)
  47#define	OMAP_USBTLL_SYSSTATUS_RESETDONE			(1 << 0)
  48
  49#define	OMAP_USBTLL_IRQSTATUS				(0x18)
  50#define	OMAP_USBTLL_IRQENABLE				(0x1C)
  51
  52#define	OMAP_TLL_SHARED_CONF				(0x30)
  53#define	OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN		(1 << 6)
  54#define	OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN		(1 << 5)
  55#define	OMAP_TLL_SHARED_CONF_USB_DIVRATION		(1 << 2)
  56#define	OMAP_TLL_SHARED_CONF_FCLK_REQ			(1 << 1)
  57#define	OMAP_TLL_SHARED_CONF_FCLK_IS_ON			(1 << 0)
  58
  59#define	OMAP_TLL_CHANNEL_CONF(num)			(0x040 + 0x004 * num)
  60#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT		24
  61#define	OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF		(1 << 11)
  62#define	OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE		(1 << 10)
  63#define	OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE		(1 << 9)
  64#define	OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE		(1 << 8)
  65#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS		(1 << 1)
  66#define	OMAP_TLL_CHANNEL_CONF_CHANEN			(1 << 0)
  67
  68#define OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0		0x0
  69#define OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM		0x1
  70#define OMAP_TLL_FSLSMODE_3PIN_PHY			0x2
  71#define OMAP_TLL_FSLSMODE_4PIN_PHY			0x3
  72#define OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0		0x4
  73#define OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM		0x5
  74#define OMAP_TLL_FSLSMODE_3PIN_TLL			0x6
  75#define OMAP_TLL_FSLSMODE_4PIN_TLL			0x7
  76#define OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0		0xA
  77#define OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM		0xB
  78
  79#define	OMAP_TLL_ULPI_FUNCTION_CTRL(num)		(0x804 + 0x100 * num)
  80#define	OMAP_TLL_ULPI_INTERFACE_CTRL(num)		(0x807 + 0x100 * num)
  81#define	OMAP_TLL_ULPI_OTG_CTRL(num)			(0x80A + 0x100 * num)
  82#define	OMAP_TLL_ULPI_INT_EN_RISE(num)			(0x80D + 0x100 * num)
  83#define	OMAP_TLL_ULPI_INT_EN_FALL(num)			(0x810 + 0x100 * num)
  84#define	OMAP_TLL_ULPI_INT_STATUS(num)			(0x813 + 0x100 * num)
  85#define	OMAP_TLL_ULPI_INT_LATCH(num)			(0x814 + 0x100 * num)
  86#define	OMAP_TLL_ULPI_DEBUG(num)			(0x815 + 0x100 * num)
  87#define	OMAP_TLL_ULPI_SCRATCH_REGISTER(num)		(0x816 + 0x100 * num)
  88
  89#define OMAP_TLL_CHANNEL_COUNT				3
  90#define OMAP_TLL_CHANNEL_1_EN_MASK			(1 << 0)
  91#define OMAP_TLL_CHANNEL_2_EN_MASK			(1 << 1)
  92#define OMAP_TLL_CHANNEL_3_EN_MASK			(1 << 2)
  93
  94/* UHH Register Set */
  95#define	OMAP_UHH_REVISION				(0x00)
  96#define	OMAP_UHH_SYSCONFIG				(0x10)
  97#define	OMAP_UHH_SYSCONFIG_MIDLEMODE			(1 << 12)
  98#define	OMAP_UHH_SYSCONFIG_CACTIVITY			(1 << 8)
  99#define	OMAP_UHH_SYSCONFIG_SIDLEMODE			(1 << 3)
 100#define	OMAP_UHH_SYSCONFIG_ENAWAKEUP			(1 << 2)
 101#define	OMAP_UHH_SYSCONFIG_SOFTRESET			(1 << 1)
 102#define	OMAP_UHH_SYSCONFIG_AUTOIDLE			(1 << 0)
 103
 104#define	OMAP_UHH_SYSSTATUS				(0x14)
 105#define	OMAP_UHH_HOSTCONFIG				(0x40)
 106#define	OMAP_UHH_HOSTCONFIG_ULPI_BYPASS			(1 << 0)
 107#define	OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS		(1 << 0)
 108#define	OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS		(1 << 11)
 109#define	OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS		(1 << 12)
 110#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN		(1 << 2)
 111#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN		(1 << 3)
 112#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN		(1 << 4)
 113#define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN		(1 << 5)
 114#define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS		(1 << 8)
 115#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS		(1 << 9)
 116#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS		(1 << 10)
 117#define OMAP4_UHH_HOSTCONFIG_APP_START_CLK		(1 << 31)
 118
 119/* OMAP4-specific defines */
 120#define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR		(3 << 2)
 121#define OMAP4_UHH_SYSCONFIG_NOIDLE			(1 << 2)
 122#define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR		(3 << 4)
 123#define OMAP4_UHH_SYSCONFIG_NOSTDBY			(1 << 4)
 124#define OMAP4_UHH_SYSCONFIG_SOFTRESET			(1 << 0)
 125
 126#define OMAP4_P1_MODE_CLEAR				(3 << 16)
 127#define OMAP4_P1_MODE_TLL				(1 << 16)
 128#define OMAP4_P1_MODE_HSIC				(3 << 16)
 129#define OMAP4_P2_MODE_CLEAR				(3 << 18)
 130#define OMAP4_P2_MODE_TLL				(1 << 18)
 131#define OMAP4_P2_MODE_HSIC				(3 << 18)
 132
 133#define OMAP_REV2_TLL_CHANNEL_COUNT			2
 134
 135#define	OMAP_UHH_DEBUG_CSR				(0x44)
 136
 137/* Values of UHH_REVISION - Note: these are not given in the TRM */
 138#define OMAP_USBHS_REV1		0x00000010	/* OMAP3 */
 139#define OMAP_USBHS_REV2		0x50700100	/* OMAP4 */
 140
 141#define is_omap_usbhs_rev1(x)	(x->usbhs_rev == OMAP_USBHS_REV1)
 142#define is_omap_usbhs_rev2(x)	(x->usbhs_rev == OMAP_USBHS_REV2)
 143
 144#define is_ehci_phy_mode(x)	(x == OMAP_EHCI_PORT_MODE_PHY)
 145#define is_ehci_tll_mode(x)	(x == OMAP_EHCI_PORT_MODE_TLL)
 146#define is_ehci_hsic_mode(x)	(x == OMAP_EHCI_PORT_MODE_HSIC)
 147
 148
 149struct usbhs_hcd_omap {
 150	struct clk			*usbhost_ick;
 151	struct clk			*usbhost_hs_fck;
 152	struct clk			*usbhost_fs_fck;
 
 
 153	struct clk			*xclk60mhsp1_ck;
 154	struct clk			*xclk60mhsp2_ck;
 155	struct clk			*utmi_p1_fck;
 156	struct clk			*usbhost_p1_fck;
 157	struct clk			*usbtll_p1_fck;
 158	struct clk			*utmi_p2_fck;
 159	struct clk			*usbhost_p2_fck;
 160	struct clk			*usbtll_p2_fck;
 161	struct clk			*init_60m_fclk;
 162	struct clk			*usbtll_fck;
 163	struct clk			*usbtll_ick;
 164
 165	void __iomem			*uhh_base;
 166	void __iomem			*tll_base;
 167
 168	struct usbhs_omap_platform_data	platdata;
 169
 170	u32				usbhs_rev;
 171	spinlock_t			lock;
 172	int				count;
 173};
 174/*-------------------------------------------------------------------------*/
 175
 176const char usbhs_driver_name[] = USBHS_DRIVER_NAME;
 177static u64 usbhs_dmamask = ~(u32)0;
 178
 179/*-------------------------------------------------------------------------*/
 180
 181static inline void usbhs_write(void __iomem *base, u32 reg, u32 val)
 182{
 183	__raw_writel(val, base + reg);
 184}
 185
 186static inline u32 usbhs_read(void __iomem *base, u32 reg)
 187{
 188	return __raw_readl(base + reg);
 189}
 190
 191static inline void usbhs_writeb(void __iomem *base, u8 reg, u8 val)
 192{
 193	__raw_writeb(val, base + reg);
 194}
 195
 196static inline u8 usbhs_readb(void __iomem *base, u8 reg)
 197{
 198	return __raw_readb(base + reg);
 199}
 200
 201/*-------------------------------------------------------------------------*/
 202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 203static struct platform_device *omap_usbhs_alloc_child(const char *name,
 204			struct resource	*res, int num_resources, void *pdata,
 205			size_t pdata_size, struct device *dev)
 206{
 207	struct platform_device	*child;
 208	int			ret;
 209
 210	child = platform_device_alloc(name, 0);
 211
 212	if (!child) {
 213		dev_err(dev, "platform_device_alloc %s failed\n", name);
 214		goto err_end;
 215	}
 216
 217	ret = platform_device_add_resources(child, res, num_resources);
 218	if (ret) {
 219		dev_err(dev, "platform_device_add_resources failed\n");
 220		goto err_alloc;
 221	}
 222
 223	ret = platform_device_add_data(child, pdata, pdata_size);
 224	if (ret) {
 225		dev_err(dev, "platform_device_add_data failed\n");
 226		goto err_alloc;
 227	}
 228
 229	child->dev.dma_mask		= &usbhs_dmamask;
 230	child->dev.coherent_dma_mask	= 0xffffffff;
 231	child->dev.parent		= dev;
 232
 233	ret = platform_device_add(child);
 234	if (ret) {
 235		dev_err(dev, "platform_device_add failed\n");
 236		goto err_alloc;
 237	}
 238
 239	return child;
 240
 241err_alloc:
 242	platform_device_put(child);
 243
 244err_end:
 245	return NULL;
 246}
 247
 248static int omap_usbhs_alloc_children(struct platform_device *pdev)
 249{
 250	struct device				*dev = &pdev->dev;
 251	struct usbhs_hcd_omap			*omap;
 252	struct ehci_hcd_omap_platform_data	*ehci_data;
 253	struct ohci_hcd_omap_platform_data	*ohci_data;
 254	struct platform_device			*ehci;
 255	struct platform_device			*ohci;
 256	struct resource				*res;
 257	struct resource				resources[2];
 258	int					ret;
 259
 260	omap = platform_get_drvdata(pdev);
 261	ehci_data = omap->platdata.ehci_data;
 262	ohci_data = omap->platdata.ohci_data;
 263
 264	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci");
 265	if (!res) {
 266		dev_err(dev, "EHCI get resource IORESOURCE_MEM failed\n");
 267		ret = -ENODEV;
 268		goto err_end;
 269	}
 270	resources[0] = *res;
 271
 272	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ehci-irq");
 273	if (!res) {
 274		dev_err(dev, " EHCI get resource IORESOURCE_IRQ failed\n");
 275		ret = -ENODEV;
 276		goto err_end;
 277	}
 278	resources[1] = *res;
 279
 280	ehci = omap_usbhs_alloc_child(OMAP_EHCI_DEVICE, resources, 2, ehci_data,
 281		sizeof(*ehci_data), dev);
 282
 283	if (!ehci) {
 284		dev_err(dev, "omap_usbhs_alloc_child failed\n");
 285		ret = -ENOMEM;
 286		goto err_end;
 287	}
 288
 289	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ohci");
 290	if (!res) {
 291		dev_err(dev, "OHCI get resource IORESOURCE_MEM failed\n");
 292		ret = -ENODEV;
 293		goto err_ehci;
 294	}
 295	resources[0] = *res;
 296
 297	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ohci-irq");
 298	if (!res) {
 299		dev_err(dev, "OHCI get resource IORESOURCE_IRQ failed\n");
 300		ret = -ENODEV;
 301		goto err_ehci;
 302	}
 303	resources[1] = *res;
 304
 305	ohci = omap_usbhs_alloc_child(OMAP_OHCI_DEVICE, resources, 2, ohci_data,
 306		sizeof(*ohci_data), dev);
 307	if (!ohci) {
 308		dev_err(dev, "omap_usbhs_alloc_child failed\n");
 309		ret = -ENOMEM;
 310		goto err_ehci;
 311	}
 312
 313	return 0;
 314
 315err_ehci:
 316	platform_device_unregister(ehci);
 317
 318err_end:
 319	return ret;
 320}
 321
 322/**
 323 * usbhs_omap_probe - initialize TI-based HCDs
 324 *
 325 * Allocates basic resources for this USB host controller.
 326 */
 327static int __devinit usbhs_omap_probe(struct platform_device *pdev)
 328{
 329	struct device			*dev =  &pdev->dev;
 330	struct usbhs_omap_platform_data	*pdata = dev->platform_data;
 331	struct usbhs_hcd_omap		*omap;
 332	struct resource			*res;
 333	int				ret = 0;
 334	int				i;
 
 
 
 
 
 
 335
 336	if (!pdata) {
 337		dev_err(dev, "Missing platform data\n");
 338		ret = -ENOMEM;
 339		goto end_probe;
 340	}
 
 341
 342	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
 343	if (!omap) {
 344		dev_err(dev, "Memory allocation failed\n");
 345		ret = -ENOMEM;
 346		goto end_probe;
 347	}
 348
 349	spin_lock_init(&omap->lock);
 350
 351	for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
 352		omap->platdata.port_mode[i] = pdata->port_mode[i];
 353
 354	omap->platdata.ehci_data = pdata->ehci_data;
 355	omap->platdata.ohci_data = pdata->ohci_data;
 
 
 
 
 
 
 
 
 
 
 
 
 356
 357	omap->usbhost_ick = clk_get(dev, "usbhost_ick");
 358	if (IS_ERR(omap->usbhost_ick)) {
 359		ret =  PTR_ERR(omap->usbhost_ick);
 360		dev_err(dev, "usbhost_ick failed error:%d\n", ret);
 361		goto err_end;
 362	}
 
 
 
 363
 364	omap->usbhost_hs_fck = clk_get(dev, "hs_fck");
 365	if (IS_ERR(omap->usbhost_hs_fck)) {
 366		ret = PTR_ERR(omap->usbhost_hs_fck);
 367		dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret);
 368		goto err_usbhost_ick;
 
 
 
 
 
 
 
 
 369	}
 370
 371	omap->usbhost_fs_fck = clk_get(dev, "fs_fck");
 372	if (IS_ERR(omap->usbhost_fs_fck)) {
 373		ret = PTR_ERR(omap->usbhost_fs_fck);
 374		dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret);
 375		goto err_usbhost_hs_fck;
 376	}
 377
 378	omap->usbtll_fck = clk_get(dev, "usbtll_fck");
 379	if (IS_ERR(omap->usbtll_fck)) {
 380		ret = PTR_ERR(omap->usbtll_fck);
 381		dev_err(dev, "usbtll_fck failed error:%d\n", ret);
 382		goto err_usbhost_fs_fck;
 383	}
 384
 385	omap->usbtll_ick = clk_get(dev, "usbtll_ick");
 386	if (IS_ERR(omap->usbtll_ick)) {
 387		ret = PTR_ERR(omap->usbtll_ick);
 388		dev_err(dev, "usbtll_ick failed error:%d\n", ret);
 389		goto err_usbtll_fck;
 390	}
 391
 392	omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
 393	if (IS_ERR(omap->utmi_p1_fck)) {
 394		ret = PTR_ERR(omap->utmi_p1_fck);
 395		dev_err(dev, "utmi_p1_gfclk failed error:%d\n",	ret);
 396		goto err_usbtll_ick;
 
 
 
 
 
 
 
 
 
 
 
 
 397	}
 398
 399	omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
 400	if (IS_ERR(omap->xclk60mhsp1_ck)) {
 401		ret = PTR_ERR(omap->xclk60mhsp1_ck);
 402		dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
 403		goto err_utmi_p1_fck;
 404	}
 405
 406	omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
 407	if (IS_ERR(omap->utmi_p2_fck)) {
 408		ret = PTR_ERR(omap->utmi_p2_fck);
 409		dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
 410		goto err_xclk60mhsp1_ck;
 411	}
 412
 413	omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
 414	if (IS_ERR(omap->xclk60mhsp2_ck)) {
 415		ret = PTR_ERR(omap->xclk60mhsp2_ck);
 416		dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
 417		goto err_utmi_p2_fck;
 418	}
 419
 420	omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
 421	if (IS_ERR(omap->usbhost_p1_fck)) {
 422		ret = PTR_ERR(omap->usbhost_p1_fck);
 423		dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
 424		goto err_xclk60mhsp2_ck;
 425	}
 426
 427	omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
 428	if (IS_ERR(omap->usbtll_p1_fck)) {
 429		ret = PTR_ERR(omap->usbtll_p1_fck);
 430		dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
 431		goto err_usbhost_p1_fck;
 432	}
 433
 434	omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
 435	if (IS_ERR(omap->usbhost_p2_fck)) {
 436		ret = PTR_ERR(omap->usbhost_p2_fck);
 437		dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
 438		goto err_usbtll_p1_fck;
 439	}
 
 
 440
 441	omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
 442	if (IS_ERR(omap->usbtll_p2_fck)) {
 443		ret = PTR_ERR(omap->usbtll_p2_fck);
 444		dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
 445		goto err_usbhost_p2_fck;
 446	}
 
 
 
 447
 448	omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
 449	if (IS_ERR(omap->init_60m_fclk)) {
 450		ret = PTR_ERR(omap->init_60m_fclk);
 451		dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
 452		goto err_usbtll_p2_fck;
 
 
 453	}
 454
 455	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
 456	if (!res) {
 457		dev_err(dev, "UHH EHCI get resource failed\n");
 458		ret = -ENODEV;
 459		goto err_init_60m_fclk;
 460	}
 461
 462	omap->uhh_base = ioremap(res->start, resource_size(res));
 463	if (!omap->uhh_base) {
 464		dev_err(dev, "UHH ioremap failed\n");
 465		ret = -ENOMEM;
 466		goto err_init_60m_fclk;
 
 467	}
 468
 469	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
 470	if (!res) {
 471		dev_err(dev, "UHH EHCI get resource failed\n");
 472		ret = -ENODEV;
 473		goto err_tll;
 474	}
 475
 476	omap->tll_base = ioremap(res->start, resource_size(res));
 477	if (!omap->tll_base) {
 478		dev_err(dev, "TLL ioremap failed\n");
 479		ret = -ENOMEM;
 480		goto err_tll;
 481	}
 482
 483	platform_set_drvdata(pdev, omap);
 
 
 484
 485	ret = omap_usbhs_alloc_children(pdev);
 486	if (ret) {
 487		dev_err(dev, "omap_usbhs_alloc_children failed\n");
 488		goto err_alloc;
 
 489	}
 490
 491	goto end_probe;
 492
 493err_alloc:
 494	iounmap(omap->tll_base);
 495
 496err_tll:
 497	iounmap(omap->uhh_base);
 
 
 498
 499err_init_60m_fclk:
 500	clk_put(omap->init_60m_fclk);
 501
 502err_usbtll_p2_fck:
 503	clk_put(omap->usbtll_p2_fck);
 504
 505err_usbhost_p2_fck:
 506	clk_put(omap->usbhost_p2_fck);
 
 
 
 
 
 507
 508err_usbtll_p1_fck:
 509	clk_put(omap->usbtll_p1_fck);
 
 
 
 
 
 
 
 
 
 
 
 510
 511err_usbhost_p1_fck:
 512	clk_put(omap->usbhost_p1_fck);
 513
 514err_xclk60mhsp2_ck:
 515	clk_put(omap->xclk60mhsp2_ck);
 516
 517err_utmi_p2_fck:
 518	clk_put(omap->utmi_p2_fck);
 
 
 
 519
 520err_xclk60mhsp1_ck:
 521	clk_put(omap->xclk60mhsp1_ck);
 
 522
 523err_utmi_p1_fck:
 524	clk_put(omap->utmi_p1_fck);
 
 
 
 525
 526err_usbtll_ick:
 527	clk_put(omap->usbtll_ick);
 
 
 528
 529err_usbtll_fck:
 530	clk_put(omap->usbtll_fck);
 531
 532err_usbhost_fs_fck:
 533	clk_put(omap->usbhost_fs_fck);
 
 
 534
 535err_usbhost_hs_fck:
 536	clk_put(omap->usbhost_hs_fck);
 
 
 
 
 
 537
 538err_usbhost_ick:
 539	clk_put(omap->usbhost_ick);
 
 540
 541err_end:
 542	kfree(omap);
 
 543
 544end_probe:
 545	return ret;
 546}
 547
 
 
 
 
 
 
 548/**
 549 * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs
 550 * @pdev: USB Host Controller being removed
 551 *
 552 * Reverses the effect of usbhs_omap_probe().
 
 
 553 */
 554static int __devexit usbhs_omap_remove(struct platform_device *pdev)
 555{
 556	struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
 557
 558	if (omap->count != 0) {
 559		dev_err(&pdev->dev,
 560			"Either EHCI or OHCI is still using usbhs core\n");
 561		return -EBUSY;
 562	}
 563
 564	iounmap(omap->tll_base);
 565	iounmap(omap->uhh_base);
 566	clk_put(omap->init_60m_fclk);
 567	clk_put(omap->usbtll_p2_fck);
 568	clk_put(omap->usbhost_p2_fck);
 569	clk_put(omap->usbtll_p1_fck);
 570	clk_put(omap->usbhost_p1_fck);
 571	clk_put(omap->xclk60mhsp2_ck);
 572	clk_put(omap->utmi_p2_fck);
 573	clk_put(omap->xclk60mhsp1_ck);
 574	clk_put(omap->utmi_p1_fck);
 575	clk_put(omap->usbtll_ick);
 576	clk_put(omap->usbtll_fck);
 577	clk_put(omap->usbhost_fs_fck);
 578	clk_put(omap->usbhost_hs_fck);
 579	clk_put(omap->usbhost_ick);
 580	kfree(omap);
 581
 582	return 0;
 583}
 584
 585static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
 586{
 587	switch (pmode) {
 588	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
 589	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
 590	case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
 591	case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
 592	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
 593	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
 594	case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
 595	case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
 596	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
 597	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
 598		return true;
 599
 600	default:
 601		return false;
 602	}
 603}
 604
 605/*
 606 * convert the port-mode enum to a value we can use in the FSLSMODE
 607 * field of USBTLL_CHANNEL_CONF
 608 */
 609static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
 610{
 611	switch (mode) {
 612	case OMAP_USBHS_PORT_MODE_UNUSED:
 613	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
 614		return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
 615
 616	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
 617		return OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM;
 618
 619	case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
 620		return OMAP_TLL_FSLSMODE_3PIN_PHY;
 621
 622	case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
 623		return OMAP_TLL_FSLSMODE_4PIN_PHY;
 624
 625	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
 626		return OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0;
 627
 628	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
 629		return OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM;
 630
 631	case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
 632		return OMAP_TLL_FSLSMODE_3PIN_TLL;
 633
 634	case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
 635		return OMAP_TLL_FSLSMODE_4PIN_TLL;
 636
 637	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
 638		return OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0;
 639
 640	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
 641		return OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM;
 642	default:
 643		pr_warning("Invalid port mode, using default\n");
 644		return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
 645	}
 646}
 647
 648static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count)
 649{
 650	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
 651	struct usbhs_omap_platform_data	*pdata = dev->platform_data;
 652	unsigned			reg;
 653	int				i;
 654
 655	/* Program Common TLL register */
 656	reg = usbhs_read(omap->tll_base, OMAP_TLL_SHARED_CONF);
 657	reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON
 658		| OMAP_TLL_SHARED_CONF_USB_DIVRATION);
 659	reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN;
 660	reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN;
 661
 662	usbhs_write(omap->tll_base, OMAP_TLL_SHARED_CONF, reg);
 663
 664	/* Enable channels now */
 665	for (i = 0; i < tll_channel_count; i++) {
 666		reg = usbhs_read(omap->tll_base,
 667				OMAP_TLL_CHANNEL_CONF(i));
 668
 669		if (is_ohci_port(pdata->port_mode[i])) {
 670			reg |= ohci_omap3_fslsmode(pdata->port_mode[i])
 671				<< OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT;
 672			reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS;
 673		} else if (pdata->port_mode[i] == OMAP_EHCI_PORT_MODE_TLL) {
 674
 675			/* Disable AutoIdle, BitStuffing and use SDR Mode */
 676			reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
 677				| OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
 678				| OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
 679
 680		} else
 681			continue;
 682
 683		reg |= OMAP_TLL_CHANNEL_CONF_CHANEN;
 684		usbhs_write(omap->tll_base,
 685				OMAP_TLL_CHANNEL_CONF(i), reg);
 686
 687		usbhs_writeb(omap->tll_base,
 688				OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe);
 
 
 689	}
 690}
 691
 692static int usbhs_enable(struct device *dev)
 693{
 694	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
 695	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
 696	unsigned long			flags = 0;
 697	int				ret = 0;
 698	unsigned long			timeout;
 699	unsigned			reg;
 700
 701	dev_dbg(dev, "starting TI HSUSB Controller\n");
 702	if (!pdata) {
 703		dev_dbg(dev, "missing platform_data\n");
 704		return  -ENODEV;
 705	}
 706
 707	spin_lock_irqsave(&omap->lock, flags);
 708	if (omap->count > 0)
 709		goto end_count;
 710
 711	clk_enable(omap->usbhost_ick);
 712	clk_enable(omap->usbhost_hs_fck);
 713	clk_enable(omap->usbhost_fs_fck);
 714	clk_enable(omap->usbtll_fck);
 715	clk_enable(omap->usbtll_ick);
 716
 717	if (pdata->ehci_data->phy_reset) {
 718		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) {
 719			gpio_request(pdata->ehci_data->reset_gpio_port[0],
 720						"USB1 PHY reset");
 721			gpio_direction_output
 722				(pdata->ehci_data->reset_gpio_port[0], 0);
 723		}
 724
 725		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) {
 726			gpio_request(pdata->ehci_data->reset_gpio_port[1],
 727						"USB2 PHY reset");
 728			gpio_direction_output
 729				(pdata->ehci_data->reset_gpio_port[1], 0);
 730		}
 731
 732		/* Hold the PHY in RESET for enough time till DIR is high */
 733		udelay(10);
 734	}
 735
 736	omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
 737	dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
 738
 739	/* perform TLL soft reset, and wait until reset is complete */
 740	usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
 741			OMAP_USBTLL_SYSCONFIG_SOFTRESET);
 742
 743	/* Wait for TLL reset to complete */
 744	timeout = jiffies + msecs_to_jiffies(1000);
 745	while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
 746			& OMAP_USBTLL_SYSSTATUS_RESETDONE)) {
 747		cpu_relax();
 748
 749		if (time_after(jiffies, timeout)) {
 750			dev_dbg(dev, "operation timed out\n");
 751			ret = -EINVAL;
 752			goto err_tll;
 
 
 
 
 
 
 
 
 
 
 
 753		}
 
 754	}
 755
 756	dev_dbg(dev, "TLL RESET DONE\n");
 
 
 
 757
 758	/* (1<<3) = no idle mode only for initial debugging */
 759	usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
 760			OMAP_USBTLL_SYSCONFIG_ENAWAKEUP |
 761			OMAP_USBTLL_SYSCONFIG_SIDLEMODE |
 762			OMAP_USBTLL_SYSCONFIG_AUTOIDLE);
 763
 764	/* Put UHH in NoIdle/NoStandby mode */
 765	reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG);
 766	if (is_omap_usbhs_rev1(omap)) {
 767		reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP
 768				| OMAP_UHH_SYSCONFIG_SIDLEMODE
 769				| OMAP_UHH_SYSCONFIG_CACTIVITY
 770				| OMAP_UHH_SYSCONFIG_MIDLEMODE);
 771		reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE;
 772
 773
 774	} else if (is_omap_usbhs_rev2(omap)) {
 775		reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR;
 776		reg |= OMAP4_UHH_SYSCONFIG_NOIDLE;
 777		reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR;
 778		reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY;
 779	}
 780
 781	usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
 782
 783	reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
 784	/* setup ULPI bypass and burst configurations */
 785	reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
 786			| OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN
 787			| OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN);
 788	reg |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK;
 789	reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN;
 
 
 
 
 
 
 
 
 
 
 
 
 790
 791	if (is_omap_usbhs_rev1(omap)) {
 792		if (pdata->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED)
 793			reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS;
 794		if (pdata->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED)
 795			reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS;
 796		if (pdata->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED)
 797			reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS;
 798
 799		/* Bypass the TLL module for PHY mode operation */
 800		if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) {
 801			dev_dbg(dev, "OMAP3 ES version <= ES2.1\n");
 802			if (is_ehci_phy_mode(pdata->port_mode[0]) ||
 803				is_ehci_phy_mode(pdata->port_mode[1]) ||
 804					is_ehci_phy_mode(pdata->port_mode[2]))
 805				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
 806			else
 807				reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
 808		} else {
 809			dev_dbg(dev, "OMAP3 ES version > ES2.1\n");
 810			if (is_ehci_phy_mode(pdata->port_mode[0]))
 811				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
 812			else
 813				reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
 814			if (is_ehci_phy_mode(pdata->port_mode[1]))
 815				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
 816			else
 817				reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
 818			if (is_ehci_phy_mode(pdata->port_mode[2]))
 819				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
 820			else
 821				reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
 822		}
 823	} else if (is_omap_usbhs_rev2(omap)) {
 824		/* Clear port mode fields for PHY mode*/
 825		reg &= ~OMAP4_P1_MODE_CLEAR;
 826		reg &= ~OMAP4_P2_MODE_CLEAR;
 827
 828		if (is_ehci_phy_mode(pdata->port_mode[0])) {
 829			ret = clk_set_parent(omap->utmi_p1_fck,
 830						omap->xclk60mhsp1_ck);
 831			if (ret != 0) {
 832				dev_err(dev, "xclk60mhsp1_ck set parent"
 833				"failed error:%d\n", ret);
 834				goto err_tll;
 835			}
 836		} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
 837			ret = clk_set_parent(omap->utmi_p1_fck,
 838						omap->init_60m_fclk);
 839			if (ret != 0) {
 840				dev_err(dev, "init_60m_fclk set parent"
 841				"failed error:%d\n", ret);
 842				goto err_tll;
 843			}
 844			clk_enable(omap->usbhost_p1_fck);
 845			clk_enable(omap->usbtll_p1_fck);
 846		}
 847
 848		if (is_ehci_phy_mode(pdata->port_mode[1])) {
 849			ret = clk_set_parent(omap->utmi_p2_fck,
 850						omap->xclk60mhsp2_ck);
 851			if (ret != 0) {
 852				dev_err(dev, "xclk60mhsp1_ck set parent"
 853					"failed error:%d\n", ret);
 854				goto err_tll;
 855			}
 856		} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
 857			ret = clk_set_parent(omap->utmi_p2_fck,
 858						omap->init_60m_fclk);
 859			if (ret != 0) {
 860				dev_err(dev, "init_60m_fclk set parent"
 861				"failed error:%d\n", ret);
 862				goto err_tll;
 863			}
 864			clk_enable(omap->usbhost_p2_fck);
 865			clk_enable(omap->usbtll_p2_fck);
 866		}
 867
 868		clk_enable(omap->utmi_p1_fck);
 869		clk_enable(omap->utmi_p2_fck);
 870
 871		if (is_ehci_tll_mode(pdata->port_mode[0]) ||
 872			(is_ohci_port(pdata->port_mode[0])))
 873			reg |= OMAP4_P1_MODE_TLL;
 874		else if (is_ehci_hsic_mode(pdata->port_mode[0]))
 875			reg |= OMAP4_P1_MODE_HSIC;
 876
 877		if (is_ehci_tll_mode(pdata->port_mode[1]) ||
 878			(is_ohci_port(pdata->port_mode[1])))
 879			reg |= OMAP4_P2_MODE_TLL;
 880		else if (is_ehci_hsic_mode(pdata->port_mode[1]))
 881			reg |= OMAP4_P2_MODE_HSIC;
 882	}
 883
 884	usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
 885	dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
 886
 887	if (is_ehci_tll_mode(pdata->port_mode[0]) ||
 888		is_ehci_tll_mode(pdata->port_mode[1]) ||
 889		is_ehci_tll_mode(pdata->port_mode[2]) ||
 890		(is_ohci_port(pdata->port_mode[0])) ||
 891		(is_ohci_port(pdata->port_mode[1])) ||
 892		(is_ohci_port(pdata->port_mode[2]))) {
 893
 894		/* Enable UTMI mode for required TLL channels */
 895		if (is_omap_usbhs_rev2(omap))
 896			usbhs_omap_tll_init(dev, OMAP_REV2_TLL_CHANNEL_COUNT);
 897		else
 898			usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT);
 899	}
 900
 901	if (pdata->ehci_data->phy_reset) {
 902		/* Hold the PHY in RESET for enough time till
 903		 * PHY is settled and ready
 904		 */
 905		udelay(10);
 906
 907		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
 908			gpio_set_value
 909				(pdata->ehci_data->reset_gpio_port[0], 1);
 910
 911		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
 912			gpio_set_value
 913				(pdata->ehci_data->reset_gpio_port[1], 1);
 914	}
 915
 916end_count:
 917	omap->count++;
 918	spin_unlock_irqrestore(&omap->lock, flags);
 919	return 0;
 920
 921err_tll:
 922	if (pdata->ehci_data->phy_reset) {
 923		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
 924			gpio_free(pdata->ehci_data->reset_gpio_port[0]);
 925
 926		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
 927			gpio_free(pdata->ehci_data->reset_gpio_port[1]);
 928	}
 929
 930	clk_disable(omap->usbtll_ick);
 931	clk_disable(omap->usbtll_fck);
 932	clk_disable(omap->usbhost_fs_fck);
 933	clk_disable(omap->usbhost_hs_fck);
 934	clk_disable(omap->usbhost_ick);
 935	spin_unlock_irqrestore(&omap->lock, flags);
 936	return ret;
 937}
 938
 939static void usbhs_disable(struct device *dev)
 940{
 941	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
 942	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
 943	unsigned long			flags = 0;
 944	unsigned long			timeout;
 945
 946	dev_dbg(dev, "stopping TI HSUSB Controller\n");
 947
 948	spin_lock_irqsave(&omap->lock, flags);
 
 
 
 
 
 949
 950	if (omap->count == 0)
 951		goto end_disble;
 
 
 
 
 952
 953	omap->count--;
 
 954
 955	if (omap->count != 0)
 956		goto end_disble;
 
 957
 958	/* Reset OMAP modules for insmod/rmmod to work */
 959	usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG,
 960			is_omap_usbhs_rev2(omap) ?
 961			OMAP4_UHH_SYSCONFIG_SOFTRESET :
 962			OMAP_UHH_SYSCONFIG_SOFTRESET);
 
 
 
 
 
 
 963
 964	timeout = jiffies + msecs_to_jiffies(100);
 965	while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
 966				& (1 << 0))) {
 967		cpu_relax();
 
 
 
 
 
 968
 969		if (time_after(jiffies, timeout))
 970			dev_dbg(dev, "operation timed out\n");
 
 
 
 
 
 
 
 971	}
 972
 973	while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
 974				& (1 << 1))) {
 975		cpu_relax();
 976
 977		if (time_after(jiffies, timeout))
 978			dev_dbg(dev, "operation timed out\n");
 
 
 
 
 
 
 
 
 
 
 979	}
 980
 981	while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
 982				& (1 << 2))) {
 983		cpu_relax();
 984
 985		if (time_after(jiffies, timeout))
 986			dev_dbg(dev, "operation timed out\n");
 
 
 
 
 
 
 
 
 
 
 987	}
 988
 989	usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1));
 990
 991	while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
 992				& (1 << 0))) {
 993		cpu_relax();
 994
 995		if (time_after(jiffies, timeout))
 996			dev_dbg(dev, "operation timed out\n");
 997	}
 
 
 
 
 
 998
 999	if (is_omap_usbhs_rev2(omap)) {
1000		if (is_ehci_tll_mode(pdata->port_mode[0]))
1001			clk_disable(omap->usbtll_p1_fck);
1002		if (is_ehci_tll_mode(pdata->port_mode[1]))
1003			clk_disable(omap->usbtll_p2_fck);
1004		clk_disable(omap->utmi_p2_fck);
1005		clk_disable(omap->utmi_p1_fck);
1006	}
1007
1008	clk_disable(omap->usbtll_ick);
1009	clk_disable(omap->usbtll_fck);
1010	clk_disable(omap->usbhost_fs_fck);
1011	clk_disable(omap->usbhost_hs_fck);
1012	clk_disable(omap->usbhost_ick);
1013
1014	/* The gpio_free migh sleep; so unlock the spinlock */
1015	spin_unlock_irqrestore(&omap->lock, flags);
1016
1017	if (pdata->ehci_data->phy_reset) {
1018		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
1019			gpio_free(pdata->ehci_data->reset_gpio_port[0]);
1020
1021		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
1022			gpio_free(pdata->ehci_data->reset_gpio_port[1]);
1023	}
1024	return;
1025
1026end_disble:
1027	spin_unlock_irqrestore(&omap->lock, flags);
1028}
1029
1030int omap_usbhs_enable(struct device *dev)
1031{
1032	return  usbhs_enable(dev->parent);
 
 
1033}
1034EXPORT_SYMBOL_GPL(omap_usbhs_enable);
1035
1036void omap_usbhs_disable(struct device *dev)
 
 
 
 
 
 
1037{
1038	usbhs_disable(dev->parent);
 
 
 
1039}
1040EXPORT_SYMBOL_GPL(omap_usbhs_disable);
 
 
 
 
 
 
 
 
 
 
 
 
1041
1042static struct platform_driver usbhs_omap_driver = {
1043	.driver = {
1044		.name		= (char *)usbhs_driver_name,
1045		.owner		= THIS_MODULE,
 
1046	},
1047	.remove		= __exit_p(usbhs_omap_remove),
 
1048};
1049
1050MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
 
1051MODULE_ALIAS("platform:" USBHS_DRIVER_NAME);
1052MODULE_LICENSE("GPL v2");
1053MODULE_DESCRIPTION("usb host common core driver for omap EHCI and OHCI");
1054
1055static int __init omap_usbhs_drvinit(void)
1056{
1057	return platform_driver_probe(&usbhs_omap_driver, usbhs_omap_probe);
1058}
1059
1060/*
1061 * init before ehci and ohci drivers;
1062 * The usbhs core driver should be initialized much before
1063 * the omap ehci and ohci probe functions are called.
 
 
1064 */
1065fs_initcall(omap_usbhs_drvinit);
1066
1067static void __exit omap_usbhs_drvexit(void)
1068{
1069	platform_driver_unregister(&usbhs_omap_driver);
1070}
1071module_exit(omap_usbhs_drvexit);
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * omap-usb-host.c - The USBHS core driver for OMAP EHCI & OHCI
  4 *
  5 * Copyright (C) 2011-2013 Texas Instruments Incorporated - https://www.ti.com
  6 * Author: Keshava Munegowda <keshava_mgowda@ti.com>
  7 * Author: Roger Quadros <rogerq@ti.com>
 
 
 
 
 
 
 
 
 
 
 
  8 */
  9#include <linux/kernel.h>
 10#include <linux/module.h>
 11#include <linux/types.h>
 12#include <linux/slab.h>
 13#include <linux/delay.h>
 
 14#include <linux/clk.h>
 15#include <linux/dma-mapping.h>
 16#include <linux/platform_device.h>
 17#include <linux/platform_data/usb-omap.h>
 18#include <linux/pm_runtime.h>
 19#include <linux/of.h>
 20#include <linux/of_platform.h>
 21#include <linux/err.h>
 22
 23#include "omap-usb.h"
 24
 25#define USBHS_DRIVER_NAME	"usbhs_omap"
 26#define OMAP_EHCI_DEVICE	"ehci-omap"
 27#define OMAP_OHCI_DEVICE	"ohci-omap3"
 28
 29/* OMAP USBHOST Register addresses  */
 30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 31/* UHH Register Set */
 32#define	OMAP_UHH_REVISION				(0x00)
 33#define	OMAP_UHH_SYSCONFIG				(0x10)
 34#define	OMAP_UHH_SYSCONFIG_MIDLEMODE			(1 << 12)
 35#define	OMAP_UHH_SYSCONFIG_CACTIVITY			(1 << 8)
 36#define	OMAP_UHH_SYSCONFIG_SIDLEMODE			(1 << 3)
 37#define	OMAP_UHH_SYSCONFIG_ENAWAKEUP			(1 << 2)
 38#define	OMAP_UHH_SYSCONFIG_SOFTRESET			(1 << 1)
 39#define	OMAP_UHH_SYSCONFIG_AUTOIDLE			(1 << 0)
 40
 41#define	OMAP_UHH_SYSSTATUS				(0x14)
 42#define	OMAP_UHH_HOSTCONFIG				(0x40)
 43#define	OMAP_UHH_HOSTCONFIG_ULPI_BYPASS			(1 << 0)
 44#define	OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS		(1 << 0)
 45#define	OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS		(1 << 11)
 46#define	OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS		(1 << 12)
 47#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN		(1 << 2)
 48#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN		(1 << 3)
 49#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN		(1 << 4)
 50#define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN		(1 << 5)
 51#define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS		(1 << 8)
 52#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS		(1 << 9)
 53#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS		(1 << 10)
 54#define OMAP4_UHH_HOSTCONFIG_APP_START_CLK		(1 << 31)
 55
 56/* OMAP4-specific defines */
 57#define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR		(3 << 2)
 58#define OMAP4_UHH_SYSCONFIG_NOIDLE			(1 << 2)
 59#define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR		(3 << 4)
 60#define OMAP4_UHH_SYSCONFIG_NOSTDBY			(1 << 4)
 61#define OMAP4_UHH_SYSCONFIG_SOFTRESET			(1 << 0)
 62
 63#define OMAP4_P1_MODE_CLEAR				(3 << 16)
 64#define OMAP4_P1_MODE_TLL				(1 << 16)
 65#define OMAP4_P1_MODE_HSIC				(3 << 16)
 66#define OMAP4_P2_MODE_CLEAR				(3 << 18)
 67#define OMAP4_P2_MODE_TLL				(1 << 18)
 68#define OMAP4_P2_MODE_HSIC				(3 << 18)
 69
 
 
 70#define	OMAP_UHH_DEBUG_CSR				(0x44)
 71
 72/* Values of UHH_REVISION - Note: these are not given in the TRM */
 73#define OMAP_USBHS_REV1		0x00000010	/* OMAP3 */
 74#define OMAP_USBHS_REV2		0x50700100	/* OMAP4 */
 75
 76#define is_omap_usbhs_rev1(x)	(x->usbhs_rev == OMAP_USBHS_REV1)
 77#define is_omap_usbhs_rev2(x)	(x->usbhs_rev == OMAP_USBHS_REV2)
 78
 79#define is_ehci_phy_mode(x)	(x == OMAP_EHCI_PORT_MODE_PHY)
 80#define is_ehci_tll_mode(x)	(x == OMAP_EHCI_PORT_MODE_TLL)
 81#define is_ehci_hsic_mode(x)	(x == OMAP_EHCI_PORT_MODE_HSIC)
 82
 83
 84struct usbhs_hcd_omap {
 85	int				nports;
 86	struct clk			**utmi_clk;
 87	struct clk			**hsic60m_clk;
 88	struct clk			**hsic480m_clk;
 89
 90	struct clk			*xclk60mhsp1_ck;
 91	struct clk			*xclk60mhsp2_ck;
 92	struct clk			*utmi_p1_gfclk;
 93	struct clk			*utmi_p2_gfclk;
 
 
 
 
 94	struct clk			*init_60m_fclk;
 95	struct clk			*ehci_logic_fck;
 
 96
 97	void __iomem			*uhh_base;
 
 98
 99	struct usbhs_omap_platform_data	*pdata;
100
101	u32				usbhs_rev;
 
 
102};
103/*-------------------------------------------------------------------------*/
104
105static const char usbhs_driver_name[] = USBHS_DRIVER_NAME;
106static u64 usbhs_dmamask = DMA_BIT_MASK(32);
107
108/*-------------------------------------------------------------------------*/
109
110static inline void usbhs_write(void __iomem *base, u32 reg, u32 val)
111{
112	writel_relaxed(val, base + reg);
113}
114
115static inline u32 usbhs_read(void __iomem *base, u32 reg)
116{
117	return readl_relaxed(base + reg);
 
 
 
 
 
 
 
 
 
 
118}
119
120/*-------------------------------------------------------------------------*/
121
122/*
123 * Map 'enum usbhs_omap_port_mode' found in <linux/platform_data/usb-omap.h>
124 * to the device tree binding portN-mode found in
125 * 'Documentation/devicetree/bindings/mfd/omap-usb-host.txt'
126 */
127static const char * const port_modes[] = {
128	[OMAP_USBHS_PORT_MODE_UNUSED]	= "",
129	[OMAP_EHCI_PORT_MODE_PHY]	= "ehci-phy",
130	[OMAP_EHCI_PORT_MODE_TLL]	= "ehci-tll",
131	[OMAP_EHCI_PORT_MODE_HSIC]	= "ehci-hsic",
132	[OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0]	= "ohci-phy-6pin-datse0",
133	[OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM]	= "ohci-phy-6pin-dpdm",
134	[OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0]	= "ohci-phy-3pin-datse0",
135	[OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM]	= "ohci-phy-4pin-dpdm",
136	[OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0]	= "ohci-tll-6pin-datse0",
137	[OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM]	= "ohci-tll-6pin-dpdm",
138	[OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0]	= "ohci-tll-3pin-datse0",
139	[OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM]	= "ohci-tll-4pin-dpdm",
140	[OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0]	= "ohci-tll-2pin-datse0",
141	[OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM]	= "ohci-tll-2pin-dpdm",
142};
143
144static struct platform_device *omap_usbhs_alloc_child(const char *name,
145			struct resource	*res, int num_resources, void *pdata,
146			size_t pdata_size, struct device *dev)
147{
148	struct platform_device	*child;
149	int			ret;
150
151	child = platform_device_alloc(name, 0);
152
153	if (!child) {
154		dev_err(dev, "platform_device_alloc %s failed\n", name);
155		goto err_end;
156	}
157
158	ret = platform_device_add_resources(child, res, num_resources);
159	if (ret) {
160		dev_err(dev, "platform_device_add_resources failed\n");
161		goto err_alloc;
162	}
163
164	ret = platform_device_add_data(child, pdata, pdata_size);
165	if (ret) {
166		dev_err(dev, "platform_device_add_data failed\n");
167		goto err_alloc;
168	}
169
170	child->dev.dma_mask		= &usbhs_dmamask;
171	dma_set_coherent_mask(&child->dev, DMA_BIT_MASK(32));
172	child->dev.parent		= dev;
173
174	ret = platform_device_add(child);
175	if (ret) {
176		dev_err(dev, "platform_device_add failed\n");
177		goto err_alloc;
178	}
179
180	return child;
181
182err_alloc:
183	platform_device_put(child);
184
185err_end:
186	return NULL;
187}
188
189static int omap_usbhs_alloc_children(struct platform_device *pdev)
190{
191	struct device				*dev = &pdev->dev;
192	struct usbhs_omap_platform_data		*pdata = dev_get_platdata(dev);
 
 
193	struct platform_device			*ehci;
194	struct platform_device			*ohci;
195	struct resource				*res;
196	struct resource				resources[2];
197	int					ret;
198
 
 
 
 
199	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci");
200	if (!res) {
201		dev_err(dev, "EHCI get resource IORESOURCE_MEM failed\n");
202		ret = -ENODEV;
203		goto err_end;
204	}
205	resources[0] = *res;
206
207	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ehci-irq");
208	if (!res) {
209		dev_err(dev, " EHCI get resource IORESOURCE_IRQ failed\n");
210		ret = -ENODEV;
211		goto err_end;
212	}
213	resources[1] = *res;
214
215	ehci = omap_usbhs_alloc_child(OMAP_EHCI_DEVICE, resources, 2, pdata,
216		sizeof(*pdata), dev);
217
218	if (!ehci) {
219		dev_err(dev, "omap_usbhs_alloc_child failed\n");
220		ret = -ENOMEM;
221		goto err_end;
222	}
223
224	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ohci");
225	if (!res) {
226		dev_err(dev, "OHCI get resource IORESOURCE_MEM failed\n");
227		ret = -ENODEV;
228		goto err_ehci;
229	}
230	resources[0] = *res;
231
232	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ohci-irq");
233	if (!res) {
234		dev_err(dev, "OHCI get resource IORESOURCE_IRQ failed\n");
235		ret = -ENODEV;
236		goto err_ehci;
237	}
238	resources[1] = *res;
239
240	ohci = omap_usbhs_alloc_child(OMAP_OHCI_DEVICE, resources, 2, pdata,
241		sizeof(*pdata), dev);
242	if (!ohci) {
243		dev_err(dev, "omap_usbhs_alloc_child failed\n");
244		ret = -ENOMEM;
245		goto err_ehci;
246	}
247
248	return 0;
249
250err_ehci:
251	platform_device_unregister(ehci);
252
253err_end:
254	return ret;
255}
256
257static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
 
 
 
 
 
258{
259	switch (pmode) {
260	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
261	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
262	case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
263	case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
264	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
265	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
266	case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
267	case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
268	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
269	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
270		return true;
271
272	default:
273		return false;
 
 
274	}
275}
276
277static int usbhs_runtime_resume(struct device *dev)
278{
279	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
280	struct usbhs_omap_platform_data	*pdata = omap->pdata;
281	int i, r;
 
282
283	dev_dbg(dev, "usbhs_runtime_resume\n");
284
285	omap_tll_enable(pdata);
 
286
287	if (!IS_ERR(omap->ehci_logic_fck))
288		clk_prepare_enable(omap->ehci_logic_fck);
289
290	for (i = 0; i < omap->nports; i++) {
291		switch (pdata->port_mode[i]) {
292		case OMAP_EHCI_PORT_MODE_HSIC:
293			if (!IS_ERR(omap->hsic60m_clk[i])) {
294				r = clk_prepare_enable(omap->hsic60m_clk[i]);
295				if (r) {
296					dev_err(dev,
297					 "Can't enable port %d hsic60m clk:%d\n",
298					 i, r);
299				}
300			}
301
302			if (!IS_ERR(omap->hsic480m_clk[i])) {
303				r = clk_prepare_enable(omap->hsic480m_clk[i]);
304				if (r) {
305					dev_err(dev,
306					 "Can't enable port %d hsic480m clk:%d\n",
307					 i, r);
308				}
309			}
310			fallthrough;	/* as HSIC mode needs utmi_clk */
311
312		case OMAP_EHCI_PORT_MODE_TLL:
313			if (!IS_ERR(omap->utmi_clk[i])) {
314				r = clk_prepare_enable(omap->utmi_clk[i]);
315				if (r) {
316					dev_err(dev,
317					 "Can't enable port %d clk : %d\n",
318					 i, r);
319				}
320			}
321			break;
322		default:
323			break;
324		}
325	}
326
327	return 0;
328}
 
 
 
 
329
330static int usbhs_runtime_suspend(struct device *dev)
331{
332	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
333	struct usbhs_omap_platform_data	*pdata = omap->pdata;
334	int i;
 
335
336	dev_dbg(dev, "usbhs_runtime_suspend\n");
 
 
 
 
 
337
338	for (i = 0; i < omap->nports; i++) {
339		switch (pdata->port_mode[i]) {
340		case OMAP_EHCI_PORT_MODE_HSIC:
341			if (!IS_ERR(omap->hsic60m_clk[i]))
342				clk_disable_unprepare(omap->hsic60m_clk[i]);
343
344			if (!IS_ERR(omap->hsic480m_clk[i]))
345				clk_disable_unprepare(omap->hsic480m_clk[i]);
346			fallthrough;	/* as utmi_clks were used in HSIC mode */
347
348		case OMAP_EHCI_PORT_MODE_TLL:
349			if (!IS_ERR(omap->utmi_clk[i]))
350				clk_disable_unprepare(omap->utmi_clk[i]);
351			break;
352		default:
353			break;
354		}
355	}
356
357	if (!IS_ERR(omap->ehci_logic_fck))
358		clk_disable_unprepare(omap->ehci_logic_fck);
 
 
 
 
359
360	omap_tll_disable(pdata);
 
 
 
 
 
361
362	return 0;
363}
 
 
 
 
 
 
 
 
 
 
 
364
365static unsigned omap_usbhs_rev1_hostconfig(struct usbhs_hcd_omap *omap,
366						unsigned reg)
367{
368	struct usbhs_omap_platform_data	*pdata = omap->pdata;
369	int i;
 
370
371	for (i = 0; i < omap->nports; i++) {
372		switch (pdata->port_mode[i]) {
373		case OMAP_USBHS_PORT_MODE_UNUSED:
374			reg &= ~(OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS << i);
375			break;
376		case OMAP_EHCI_PORT_MODE_PHY:
377			if (pdata->single_ulpi_bypass)
378				break;
379
380			if (i == 0)
381				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
382			else
383				reg &= ~(OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS
384								<< (i-1));
385			break;
386		default:
387			if (pdata->single_ulpi_bypass)
388				break;
389
390			if (i == 0)
391				reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
392			else
393				reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS
394								<< (i-1);
395			break;
396		}
397	}
398
399	if (pdata->single_ulpi_bypass) {
400		/* bypass ULPI only if none of the ports use PHY mode */
401		reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
 
 
 
402
403		for (i = 0; i < omap->nports; i++) {
404			if (is_ehci_phy_mode(pdata->port_mode[i])) {
405				reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
406				break;
407			}
408		}
409	}
410
411	return reg;
412}
 
 
 
 
413
414static unsigned omap_usbhs_rev2_hostconfig(struct usbhs_hcd_omap *omap,
415						unsigned reg)
416{
417	struct usbhs_omap_platform_data	*pdata = omap->pdata;
418	int i;
 
419
420	for (i = 0; i < omap->nports; i++) {
421		/* Clear port mode fields for PHY mode */
422		reg &= ~(OMAP4_P1_MODE_CLEAR << 2 * i);
423
424		if (is_ehci_tll_mode(pdata->port_mode[i]) ||
425				(is_ohci_port(pdata->port_mode[i])))
426			reg |= OMAP4_P1_MODE_TLL << 2 * i;
427		else if (is_ehci_hsic_mode(pdata->port_mode[i]))
428			reg |= OMAP4_P1_MODE_HSIC << 2 * i;
429	}
430
431	return reg;
432}
 
 
433
434static void omap_usbhs_init(struct device *dev)
435{
436	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
437	unsigned			reg;
438
439	dev_dbg(dev, "starting TI HSUSB Controller\n");
 
440
441	pm_runtime_get_sync(dev);
 
442
443	reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
444	/* setup ULPI bypass and burst configurations */
445	reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
446			| OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN
447			| OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN);
448	reg |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK;
449	reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN;
450
451	switch (omap->usbhs_rev) {
452	case OMAP_USBHS_REV1:
453		reg = omap_usbhs_rev1_hostconfig(omap, reg);
454		break;
455
456	case OMAP_USBHS_REV2:
457		reg = omap_usbhs_rev2_hostconfig(omap, reg);
458		break;
459
460	default:	/* newer revisions */
461		reg = omap_usbhs_rev2_hostconfig(omap, reg);
462		break;
463	}
464
465	usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
466	dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
467
468	pm_runtime_put_sync(dev);
469}
470
471static int usbhs_omap_get_dt_pdata(struct device *dev,
472					struct usbhs_omap_platform_data *pdata)
473{
474	int ret, i;
475	struct device_node *node = dev->of_node;
476
477	ret = of_property_read_u32(node, "num-ports", &pdata->nports);
478	if (ret)
479		pdata->nports = 0;
480
481	if (pdata->nports > OMAP3_HS_USB_PORTS) {
482		dev_warn(dev, "Too many num_ports <%d> in device tree. Max %d\n",
483				pdata->nports, OMAP3_HS_USB_PORTS);
484		return -ENODEV;
485	}
486
487	/* get port modes */
488	for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
489		char prop[11];
490		const char *mode;
491
492		pdata->port_mode[i] = OMAP_USBHS_PORT_MODE_UNUSED;
 
493
494		snprintf(prop, sizeof(prop), "port%d-mode", i + 1);
495		ret = of_property_read_string(node, prop, &mode);
496		if (ret < 0)
497			continue;
498
499		/* get 'enum usbhs_omap_port_mode' from port mode string */
500		ret = match_string(port_modes, ARRAY_SIZE(port_modes), mode);
501		if (ret < 0) {
502			dev_warn(dev, "Invalid port%d-mode \"%s\" in device tree\n",
503					i, mode);
504			return -ENODEV;
505		}
506
507		dev_dbg(dev, "port%d-mode: %s -> %d\n", i, mode, ret);
508		pdata->port_mode[i] = ret;
509	}
510
511	/* get flags */
512	pdata->single_ulpi_bypass = of_property_read_bool(node,
513						"single-ulpi-bypass");
514
515	return 0;
 
516}
517
518static const struct of_device_id usbhs_child_match_table[] = {
519	{ .compatible = "ti,ehci-omap", },
520	{ .compatible = "ti,ohci-omap3", },
521	{ }
522};
523
524/**
525 * usbhs_omap_probe - initialize TI-based HCDs
 
526 *
527 * Allocates basic resources for this USB host controller.
528 *
529 * @pdev: Pointer to this device's platform device structure
530 */
531static int usbhs_omap_probe(struct platform_device *pdev)
532{
533	struct device			*dev =  &pdev->dev;
534	struct usbhs_omap_platform_data	*pdata = dev_get_platdata(dev);
535	struct usbhs_hcd_omap		*omap;
536	int				ret = 0;
537	int				i;
538	bool				need_logic_fck;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
539
540	if (dev->of_node) {
541		/* For DT boot we populate platform data from OF node */
542		pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
543		if (!pdata)
544			return -ENOMEM;
545
546		ret = usbhs_omap_get_dt_pdata(dev, pdata);
547		if (ret)
548			return ret;
 
 
 
 
 
549
550		dev->platform_data = pdata;
 
551	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552
553	if (!pdata) {
554		dev_err(dev, "Missing platform data\n");
555		return -ENODEV;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
556	}
 
557
558	if (pdata->nports > OMAP3_HS_USB_PORTS) {
559		dev_info(dev, "Too many num_ports <%d> in platform_data. Max %d\n",
560				pdata->nports, OMAP3_HS_USB_PORTS);
561		return -ENODEV;
562	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
563
564	omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL);
565	if (!omap) {
566		dev_err(dev, "Memory allocation failed\n");
567		return -ENOMEM;
568	}
 
569
570	omap->uhh_base = devm_platform_ioremap_resource(pdev, 0);
571	if (IS_ERR(omap->uhh_base))
572		return PTR_ERR(omap->uhh_base);
 
 
 
 
 
573
574	omap->pdata = pdata;
 
 
 
 
575
576	/* Initialize the TLL subsystem */
577	omap_tll_init(pdata);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
578
579	pm_runtime_enable(dev);
 
 
 
 
 
580
581	platform_set_drvdata(pdev, omap);
582	pm_runtime_get_sync(dev);
 
583
584	omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
 
585
586	/* we need to call runtime suspend before we update omap->nports
587	 * to prevent unbalanced clk_disable()
588	 */
589	pm_runtime_put_sync(dev);
590
591	/*
592	 * If platform data contains nports then use that
593	 * else make out number of ports from USBHS revision
594	 */
595	if (pdata->nports) {
596		omap->nports = pdata->nports;
597	} else {
598		switch (omap->usbhs_rev) {
599		case OMAP_USBHS_REV1:
600			omap->nports = 3;
601			break;
602		case OMAP_USBHS_REV2:
603			omap->nports = 2;
604			break;
605		default:
606			omap->nports = OMAP3_HS_USB_PORTS;
607			dev_dbg(dev,
608			 "USB HOST Rev:0x%x not recognized, assuming %d ports\n",
609			 omap->usbhs_rev, omap->nports);
610			break;
611		}
612		pdata->nports = omap->nports;
613	}
614
615	i = sizeof(struct clk *) * omap->nports;
616	omap->utmi_clk = devm_kzalloc(dev, i, GFP_KERNEL);
617	omap->hsic480m_clk = devm_kzalloc(dev, i, GFP_KERNEL);
618	omap->hsic60m_clk = devm_kzalloc(dev, i, GFP_KERNEL);
619
620	if (!omap->utmi_clk || !omap->hsic480m_clk || !omap->hsic60m_clk) {
621		dev_err(dev, "Memory allocation failed\n");
622		ret = -ENOMEM;
623		goto err_mem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
624	}
625
626	/* Set all clocks as invalid to begin with */
627	omap->ehci_logic_fck = ERR_PTR(-ENODEV);
628	omap->init_60m_fclk = ERR_PTR(-ENODEV);
629	omap->utmi_p1_gfclk = ERR_PTR(-ENODEV);
630	omap->utmi_p2_gfclk = ERR_PTR(-ENODEV);
631	omap->xclk60mhsp1_ck = ERR_PTR(-ENODEV);
632	omap->xclk60mhsp2_ck = ERR_PTR(-ENODEV);
633
634	for (i = 0; i < omap->nports; i++) {
635		omap->utmi_clk[i] = ERR_PTR(-ENODEV);
636		omap->hsic480m_clk[i] = ERR_PTR(-ENODEV);
637		omap->hsic60m_clk[i] = ERR_PTR(-ENODEV);
638	}
639
640	/* for OMAP3 i.e. USBHS REV1 */
641	if (omap->usbhs_rev == OMAP_USBHS_REV1) {
642		need_logic_fck = false;
643		for (i = 0; i < omap->nports; i++) {
644			if (is_ehci_phy_mode(pdata->port_mode[i]) ||
645			    is_ehci_tll_mode(pdata->port_mode[i]) ||
646			    is_ehci_hsic_mode(pdata->port_mode[i]))
647
648				need_logic_fck |= true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
649		}
650
651		if (need_logic_fck) {
652			omap->ehci_logic_fck = devm_clk_get(dev,
653							    "usbhost_120m_fck");
654			if (IS_ERR(omap->ehci_logic_fck)) {
655				ret = PTR_ERR(omap->ehci_logic_fck);
656				dev_err(dev, "usbhost_120m_fck failed:%d\n",
657					ret);
658				goto err_mem;
 
 
 
 
 
 
 
659			}
 
 
660		}
661		goto initialize;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
662	}
663
664	/* for OMAP4+ i.e. USBHS REV2+ */
665	omap->utmi_p1_gfclk = devm_clk_get(dev, "utmi_p1_gfclk");
666	if (IS_ERR(omap->utmi_p1_gfclk)) {
667		ret = PTR_ERR(omap->utmi_p1_gfclk);
668		dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
669		goto err_mem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
670	}
671
672	omap->utmi_p2_gfclk = devm_clk_get(dev, "utmi_p2_gfclk");
673	if (IS_ERR(omap->utmi_p2_gfclk)) {
674		ret = PTR_ERR(omap->utmi_p2_gfclk);
675		dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
676		goto err_mem;
 
 
 
 
 
 
 
677	}
678
679	omap->xclk60mhsp1_ck = devm_clk_get(dev, "refclk_60m_ext_p1");
680	if (IS_ERR(omap->xclk60mhsp1_ck)) {
681		ret = PTR_ERR(omap->xclk60mhsp1_ck);
682		dev_err(dev, "refclk_60m_ext_p1 failed error:%d\n", ret);
683		goto err_mem;
684	}
 
 
 
 
 
 
 
 
 
 
 
685
686	omap->xclk60mhsp2_ck = devm_clk_get(dev, "refclk_60m_ext_p2");
687	if (IS_ERR(omap->xclk60mhsp2_ck)) {
688		ret = PTR_ERR(omap->xclk60mhsp2_ck);
689		dev_err(dev, "refclk_60m_ext_p2 failed error:%d\n", ret);
690		goto err_mem;
691	}
692
693	omap->init_60m_fclk = devm_clk_get(dev, "refclk_60m_int");
694	if (IS_ERR(omap->init_60m_fclk)) {
695		ret = PTR_ERR(omap->init_60m_fclk);
696		dev_err(dev, "refclk_60m_int failed error:%d\n", ret);
697		goto err_mem;
698	}
699
700	for (i = 0; i < omap->nports; i++) {
701		char clkname[40];
702
703		/* clock names are indexed from 1*/
704		snprintf(clkname, sizeof(clkname),
705				"usb_host_hs_utmi_p%d_clk", i + 1);
706
707		/* If a clock is not found we won't bail out as not all
708		 * platforms have all clocks and we can function without
709		 * them
710		 */
711		omap->utmi_clk[i] = devm_clk_get(dev, clkname);
712		if (IS_ERR(omap->utmi_clk[i])) {
713			ret = PTR_ERR(omap->utmi_clk[i]);
714			dev_err(dev, "Failed to get clock : %s : %d\n",
715				clkname, ret);
716			goto err_mem;
717		}
718
719		snprintf(clkname, sizeof(clkname),
720				"usb_host_hs_hsic480m_p%d_clk", i + 1);
721		omap->hsic480m_clk[i] = devm_clk_get(dev, clkname);
722		if (IS_ERR(omap->hsic480m_clk[i])) {
723			ret = PTR_ERR(omap->hsic480m_clk[i]);
724			dev_err(dev, "Failed to get clock : %s : %d\n",
725				clkname, ret);
726			goto err_mem;
727		}
728
729		snprintf(clkname, sizeof(clkname),
730				"usb_host_hs_hsic60m_p%d_clk", i + 1);
731		omap->hsic60m_clk[i] = devm_clk_get(dev, clkname);
732		if (IS_ERR(omap->hsic60m_clk[i])) {
733			ret = PTR_ERR(omap->hsic60m_clk[i]);
734			dev_err(dev, "Failed to get clock : %s : %d\n",
735				clkname, ret);
736			goto err_mem;
737		}
738	}
739
740	if (is_ehci_phy_mode(pdata->port_mode[0])) {
741		ret = clk_set_parent(omap->utmi_p1_gfclk,
742					omap->xclk60mhsp1_ck);
743		if (ret != 0) {
744			dev_err(dev, "xclk60mhsp1_ck set parent failed: %d\n",
745				ret);
746			goto err_mem;
747		}
748	} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
749		ret = clk_set_parent(omap->utmi_p1_gfclk,
750					omap->init_60m_fclk);
751		if (ret != 0) {
752			dev_err(dev, "P0 init_60m_fclk set parent failed: %d\n",
753				ret);
754			goto err_mem;
755		}
756	}
757
758	if (is_ehci_phy_mode(pdata->port_mode[1])) {
759		ret = clk_set_parent(omap->utmi_p2_gfclk,
760					omap->xclk60mhsp2_ck);
761		if (ret != 0) {
762			dev_err(dev, "xclk60mhsp2_ck set parent failed: %d\n",
763				ret);
764			goto err_mem;
765		}
766	} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
767		ret = clk_set_parent(omap->utmi_p2_gfclk,
768						omap->init_60m_fclk);
769		if (ret != 0) {
770			dev_err(dev, "P1 init_60m_fclk set parent failed: %d\n",
771				ret);
772			goto err_mem;
773		}
774	}
775
776initialize:
777	omap_usbhs_init(dev);
 
 
 
778
779	if (dev->of_node) {
780		ret = of_platform_populate(dev->of_node,
781				usbhs_child_match_table, NULL, dev);
782
783		if (ret) {
784			dev_err(dev, "Failed to create DT children: %d\n", ret);
785			goto err_mem;
786		}
787
788	} else {
789		ret = omap_usbhs_alloc_children(pdev);
790		if (ret) {
791			dev_err(dev, "omap_usbhs_alloc_children failed: %d\n",
792						ret);
793			goto err_mem;
794		}
795	}
796
797	return 0;
 
 
 
 
 
 
 
 
 
 
 
798
799err_mem:
800	pm_runtime_disable(dev);
 
 
801
802	return ret;
 
803}
804
805static int usbhs_omap_remove_child(struct device *dev, void *data)
806{
807	dev_info(dev, "unregistering\n");
808	platform_device_unregister(to_platform_device(dev));
809	return 0;
810}
 
811
812/**
813 * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs
814 * @pdev: USB Host Controller being removed
815 *
816 * Reverses the effect of usbhs_omap_probe().
817 */
818static void usbhs_omap_remove(struct platform_device *pdev)
819{
820	pm_runtime_disable(&pdev->dev);
821
822	/* remove children */
823	device_for_each_child(&pdev->dev, NULL, usbhs_omap_remove_child);
824}
825
826static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
827	.runtime_suspend	= usbhs_runtime_suspend,
828	.runtime_resume		= usbhs_runtime_resume,
829};
830
831static const struct of_device_id usbhs_omap_dt_ids[] = {
832	{ .compatible = "ti,usbhs-host" },
833	{ }
834};
835
836MODULE_DEVICE_TABLE(of, usbhs_omap_dt_ids);
837
838
839static struct platform_driver usbhs_omap_driver = {
840	.driver = {
841		.name		= usbhs_driver_name,
842		.pm		= &usbhsomap_dev_pm_ops,
843		.of_match_table = usbhs_omap_dt_ids,
844	},
845	.probe		= usbhs_omap_probe,
846	.remove		= usbhs_omap_remove,
847};
848
849MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
850MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>");
851MODULE_ALIAS("platform:" USBHS_DRIVER_NAME);
 
852MODULE_DESCRIPTION("usb host common core driver for omap EHCI and OHCI");
853
854static int omap_usbhs_drvinit(void)
855{
856	return platform_driver_register(&usbhs_omap_driver);
857}
858
859/*
860 * init before ehci and ohci drivers;
861 * The usbhs core driver should be initialized much before
862 * the omap ehci and ohci probe functions are called.
863 * This usbhs core driver should be initialized after
864 * usb tll driver
865 */
866fs_initcall_sync(omap_usbhs_drvinit);
867
868static void omap_usbhs_drvexit(void)
869{
870	platform_driver_unregister(&usbhs_omap_driver);
871}
872module_exit(omap_usbhs_drvexit);