17359273dSAjay Kumar Gupta /*
27359273dSAjay Kumar Gupta * da8xx.c - TI's DA8xx platform specific usb wrapper functions.
37359273dSAjay Kumar Gupta *
47359273dSAjay Kumar Gupta * Author: Ajay Kumar Gupta <ajay.gupta@ti.com>
57359273dSAjay Kumar Gupta *
67359273dSAjay Kumar Gupta * Based on drivers/usb/musb/davinci.c
77359273dSAjay Kumar Gupta *
87359273dSAjay Kumar Gupta * Copyright (C) 2009 Texas Instruments Incorporated
97359273dSAjay Kumar Gupta *
10*1a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
117359273dSAjay Kumar Gupta */
127359273dSAjay Kumar Gupta #include <common.h>
137359273dSAjay Kumar Gupta
1425f8bf6eSSughosh Ganu #include "musb_core.h"
1525f8bf6eSSughosh Ganu #include <asm/arch/da8xx-usb.h>
167359273dSAjay Kumar Gupta
177359273dSAjay Kumar Gupta /* MUSB platform configuration */
187359273dSAjay Kumar Gupta struct musb_config musb_cfg = {
19bbf4c01eSAjay Kumar Gupta .regs = (struct musb_regs *)DA8XX_USB_OTG_CORE_BASE,
20bbf4c01eSAjay Kumar Gupta .timeout = DA8XX_USB_OTG_TIMEOUT,
21bbf4c01eSAjay Kumar Gupta .musb_speed = 0,
227359273dSAjay Kumar Gupta };
237359273dSAjay Kumar Gupta
247359273dSAjay Kumar Gupta /*
257359273dSAjay Kumar Gupta * This function enables VBUS by driving the GPIO Bank4 Pin 15 high.
267359273dSAjay Kumar Gupta */
enable_vbus(void)277359273dSAjay Kumar Gupta static void enable_vbus(void)
287359273dSAjay Kumar Gupta {
297359273dSAjay Kumar Gupta u32 value;
307359273dSAjay Kumar Gupta
317359273dSAjay Kumar Gupta /* configure GPIO bank4 pin 15 in output direction */
327359273dSAjay Kumar Gupta value = readl(&davinci_gpio_bank45->dir);
337359273dSAjay Kumar Gupta writel((value & (~DA8XX_USB_VBUS_GPIO)), &davinci_gpio_bank45->dir);
347359273dSAjay Kumar Gupta
357359273dSAjay Kumar Gupta /* set GPIO bank4 pin 15 high to drive VBUS */
367359273dSAjay Kumar Gupta value = readl(&davinci_gpio_bank45->set_data);
377359273dSAjay Kumar Gupta writel((value | DA8XX_USB_VBUS_GPIO), &davinci_gpio_bank45->set_data);
387359273dSAjay Kumar Gupta }
397359273dSAjay Kumar Gupta
407359273dSAjay Kumar Gupta /*
417359273dSAjay Kumar Gupta * Enable the usb0 phy. This initialization procedure is explained in
427359273dSAjay Kumar Gupta * the DA8xx USB user guide document.
437359273dSAjay Kumar Gupta */
phy_on(void)447359273dSAjay Kumar Gupta static u8 phy_on(void)
457359273dSAjay Kumar Gupta {
467359273dSAjay Kumar Gupta u32 timeout;
477359273dSAjay Kumar Gupta u32 cfgchip2;
487359273dSAjay Kumar Gupta
497359273dSAjay Kumar Gupta cfgchip2 = readl(&davinci_syscfg_regs->cfgchip2);
507359273dSAjay Kumar Gupta
517359273dSAjay Kumar Gupta cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN |
527359273dSAjay Kumar Gupta CFGCHIP2_OTGMODE | CFGCHIP2_REFFREQ);
537359273dSAjay Kumar Gupta cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN | CFGCHIP2_PHY_PLLON |
547359273dSAjay Kumar Gupta CFGCHIP2_REFFREQ_24MHZ;
557359273dSAjay Kumar Gupta
567359273dSAjay Kumar Gupta writel(cfgchip2, &davinci_syscfg_regs->cfgchip2);
577359273dSAjay Kumar Gupta
587359273dSAjay Kumar Gupta /* wait until the usb phy pll locks */
597359273dSAjay Kumar Gupta timeout = musb_cfg.timeout;
607359273dSAjay Kumar Gupta while (timeout--)
617359273dSAjay Kumar Gupta if (readl(&davinci_syscfg_regs->cfgchip2) & CFGCHIP2_PHYCLKGD)
627359273dSAjay Kumar Gupta return 1;
637359273dSAjay Kumar Gupta
647359273dSAjay Kumar Gupta /* USB phy was not turned on */
657359273dSAjay Kumar Gupta return 0;
667359273dSAjay Kumar Gupta }
677359273dSAjay Kumar Gupta
687359273dSAjay Kumar Gupta /*
697359273dSAjay Kumar Gupta * Disable the usb phy
707359273dSAjay Kumar Gupta */
phy_off(void)717359273dSAjay Kumar Gupta static void phy_off(void)
727359273dSAjay Kumar Gupta {
737359273dSAjay Kumar Gupta u32 cfgchip2;
747359273dSAjay Kumar Gupta
757359273dSAjay Kumar Gupta /*
767359273dSAjay Kumar Gupta * Power down the on-chip PHY.
777359273dSAjay Kumar Gupta */
787359273dSAjay Kumar Gupta cfgchip2 = readl(&davinci_syscfg_regs->cfgchip2);
797359273dSAjay Kumar Gupta cfgchip2 &= ~CFGCHIP2_PHY_PLLON;
807359273dSAjay Kumar Gupta cfgchip2 |= CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN;
817359273dSAjay Kumar Gupta writel(cfgchip2, &davinci_syscfg_regs->cfgchip2);
827359273dSAjay Kumar Gupta }
837359273dSAjay Kumar Gupta
847359273dSAjay Kumar Gupta /*
857359273dSAjay Kumar Gupta * This function performs DA8xx platform specific initialization for usb0.
867359273dSAjay Kumar Gupta */
musb_platform_init(void)877359273dSAjay Kumar Gupta int musb_platform_init(void)
887359273dSAjay Kumar Gupta {
897359273dSAjay Kumar Gupta u32 revision;
907359273dSAjay Kumar Gupta
917359273dSAjay Kumar Gupta /* enable psc for usb2.0 */
927359273dSAjay Kumar Gupta lpsc_on(33);
937359273dSAjay Kumar Gupta
947359273dSAjay Kumar Gupta /* enable usb vbus */
957359273dSAjay Kumar Gupta enable_vbus();
967359273dSAjay Kumar Gupta
977359273dSAjay Kumar Gupta /* reset the controller */
987359273dSAjay Kumar Gupta writel(0x1, &da8xx_usb_regs->control);
997359273dSAjay Kumar Gupta udelay(5000);
1007359273dSAjay Kumar Gupta
1017359273dSAjay Kumar Gupta /* start the on-chip usb phy and its pll */
1027359273dSAjay Kumar Gupta if (phy_on() == 0)
1037359273dSAjay Kumar Gupta return -1;
1047359273dSAjay Kumar Gupta
1057359273dSAjay Kumar Gupta /* Returns zero if e.g. not clocked */
1067359273dSAjay Kumar Gupta revision = readl(&da8xx_usb_regs->revision);
1077359273dSAjay Kumar Gupta if (revision == 0)
1087359273dSAjay Kumar Gupta return -1;
1097359273dSAjay Kumar Gupta
1107359273dSAjay Kumar Gupta /* Disable all interrupts */
1117359273dSAjay Kumar Gupta writel((DA8XX_USB_USBINT_MASK | DA8XX_USB_TXINT_MASK |
1127359273dSAjay Kumar Gupta DA8XX_USB_RXINT_MASK), &da8xx_usb_regs->intmsk_set);
1137359273dSAjay Kumar Gupta return 0;
1147359273dSAjay Kumar Gupta }
1157359273dSAjay Kumar Gupta
1167359273dSAjay Kumar Gupta /*
1177359273dSAjay Kumar Gupta * This function performs DA8xx platform specific deinitialization for usb0.
1187359273dSAjay Kumar Gupta */
musb_platform_deinit(void)1197359273dSAjay Kumar Gupta void musb_platform_deinit(void)
1207359273dSAjay Kumar Gupta {
1217359273dSAjay Kumar Gupta /* Turn of the phy */
1227359273dSAjay Kumar Gupta phy_off();
1237359273dSAjay Kumar Gupta
1247359273dSAjay Kumar Gupta /* flush any interrupts */
1257359273dSAjay Kumar Gupta writel((DA8XX_USB_USBINT_MASK | DA8XX_USB_TXINT_MASK |
1267359273dSAjay Kumar Gupta DA8XX_USB_RXINT_MASK), &da8xx_usb_regs->intmsk_clr);
1277359273dSAjay Kumar Gupta writel(0, &da8xx_usb_regs->eoi);
1287359273dSAjay Kumar Gupta }
129