1*be5e4bdcSMarek Vasut /* 2*be5e4bdcSMarek Vasut * drivers/usb/gadget/dwc2_udc_otg.c 3*be5e4bdcSMarek Vasut * Samsung S3C on-chip full/high speed USB OTG 2.0 device controllers 4*be5e4bdcSMarek Vasut * 5*be5e4bdcSMarek Vasut * Copyright (C) 2008 for Samsung Electronics 6*be5e4bdcSMarek Vasut * 7*be5e4bdcSMarek Vasut * BSP Support for Samsung's UDC driver 8*be5e4bdcSMarek Vasut * available at: 9*be5e4bdcSMarek Vasut * git://git.kernel.org/pub/scm/linux/kernel/git/kki_ap/linux-2.6-samsung.git 10*be5e4bdcSMarek Vasut * 11*be5e4bdcSMarek Vasut * State machine bugfixes: 12*be5e4bdcSMarek Vasut * Marek Szyprowski <m.szyprowski@samsung.com> 13*be5e4bdcSMarek Vasut * 14*be5e4bdcSMarek Vasut * Ported to u-boot: 15*be5e4bdcSMarek Vasut * Marek Szyprowski <m.szyprowski@samsung.com> 16*be5e4bdcSMarek Vasut * Lukasz Majewski <l.majewski@samsumg.com> 17*be5e4bdcSMarek Vasut * 18*be5e4bdcSMarek Vasut * SPDX-License-Identifier: GPL-2.0+ 19*be5e4bdcSMarek Vasut */ 20*be5e4bdcSMarek Vasut 21*be5e4bdcSMarek Vasut #include <common.h> 22*be5e4bdcSMarek Vasut #include <asm/errno.h> 23*be5e4bdcSMarek Vasut #include <linux/list.h> 24*be5e4bdcSMarek Vasut #include <malloc.h> 25*be5e4bdcSMarek Vasut 26*be5e4bdcSMarek Vasut #include <linux/usb/ch9.h> 27*be5e4bdcSMarek Vasut #include <linux/usb/gadget.h> 28*be5e4bdcSMarek Vasut 29*be5e4bdcSMarek Vasut #include <asm/byteorder.h> 30*be5e4bdcSMarek Vasut #include <asm/unaligned.h> 31*be5e4bdcSMarek Vasut #include <asm/io.h> 32*be5e4bdcSMarek Vasut 33*be5e4bdcSMarek Vasut #include <asm/mach-types.h> 34*be5e4bdcSMarek Vasut 35*be5e4bdcSMarek Vasut #include "dwc2_udc_otg_regs.h" 36*be5e4bdcSMarek Vasut #include "dwc2_udc_otg_priv.h" 37*be5e4bdcSMarek Vasut #include <usb/lin_gadget_compat.h> 38*be5e4bdcSMarek Vasut 39*be5e4bdcSMarek Vasut #include <usb/s3c_udc.h> 40*be5e4bdcSMarek Vasut 41*be5e4bdcSMarek Vasut void otg_phy_init(struct dwc2_udc *dev) 42*be5e4bdcSMarek Vasut { 43*be5e4bdcSMarek Vasut unsigned int usb_phy_ctrl = dev->pdata->usb_phy_ctrl; 44*be5e4bdcSMarek Vasut struct dwc2_usbotg_phy *phy = 45*be5e4bdcSMarek Vasut (struct dwc2_usbotg_phy *)dev->pdata->regs_phy; 46*be5e4bdcSMarek Vasut 47*be5e4bdcSMarek Vasut dev->pdata->phy_control(1); 48*be5e4bdcSMarek Vasut 49*be5e4bdcSMarek Vasut /* USB PHY0 Enable */ 50*be5e4bdcSMarek Vasut printf("USB PHY0 Enable\n"); 51*be5e4bdcSMarek Vasut 52*be5e4bdcSMarek Vasut /* Enable PHY */ 53*be5e4bdcSMarek Vasut writel(readl(usb_phy_ctrl) | USB_PHY_CTRL_EN0, usb_phy_ctrl); 54*be5e4bdcSMarek Vasut 55*be5e4bdcSMarek Vasut if (dev->pdata->usb_flags == PHY0_SLEEP) /* C210 Universal */ 56*be5e4bdcSMarek Vasut writel((readl(&phy->phypwr) 57*be5e4bdcSMarek Vasut &~(PHY_0_SLEEP | OTG_DISABLE_0 | ANALOG_PWRDOWN) 58*be5e4bdcSMarek Vasut &~FORCE_SUSPEND_0), &phy->phypwr); 59*be5e4bdcSMarek Vasut else /* C110 GONI */ 60*be5e4bdcSMarek Vasut writel((readl(&phy->phypwr) &~(OTG_DISABLE_0 | ANALOG_PWRDOWN) 61*be5e4bdcSMarek Vasut &~FORCE_SUSPEND_0), &phy->phypwr); 62*be5e4bdcSMarek Vasut 63*be5e4bdcSMarek Vasut if (s5p_cpu_id == 0x4412) 64*be5e4bdcSMarek Vasut writel((readl(&phy->phyclk) & ~(EXYNOS4X12_ID_PULLUP0 | 65*be5e4bdcSMarek Vasut EXYNOS4X12_COMMON_ON_N0)) | EXYNOS4X12_CLK_SEL_24MHZ, 66*be5e4bdcSMarek Vasut &phy->phyclk); /* PLL 24Mhz */ 67*be5e4bdcSMarek Vasut else 68*be5e4bdcSMarek Vasut writel((readl(&phy->phyclk) & ~(ID_PULLUP0 | COMMON_ON_N0)) | 69*be5e4bdcSMarek Vasut CLK_SEL_24MHZ, &phy->phyclk); /* PLL 24Mhz */ 70*be5e4bdcSMarek Vasut 71*be5e4bdcSMarek Vasut writel((readl(&phy->rstcon) &~(LINK_SW_RST | PHYLNK_SW_RST)) 72*be5e4bdcSMarek Vasut | PHY_SW_RST0, &phy->rstcon); 73*be5e4bdcSMarek Vasut udelay(10); 74*be5e4bdcSMarek Vasut writel(readl(&phy->rstcon) 75*be5e4bdcSMarek Vasut &~(PHY_SW_RST0 | LINK_SW_RST | PHYLNK_SW_RST), &phy->rstcon); 76*be5e4bdcSMarek Vasut udelay(10); 77*be5e4bdcSMarek Vasut } 78*be5e4bdcSMarek Vasut 79*be5e4bdcSMarek Vasut void otg_phy_off(struct dwc2_udc *dev) 80*be5e4bdcSMarek Vasut { 81*be5e4bdcSMarek Vasut unsigned int usb_phy_ctrl = dev->pdata->usb_phy_ctrl; 82*be5e4bdcSMarek Vasut struct dwc2_usbotg_phy *phy = 83*be5e4bdcSMarek Vasut (struct dwc2_usbotg_phy *)dev->pdata->regs_phy; 84*be5e4bdcSMarek Vasut 85*be5e4bdcSMarek Vasut /* reset controller just in case */ 86*be5e4bdcSMarek Vasut writel(PHY_SW_RST0, &phy->rstcon); 87*be5e4bdcSMarek Vasut udelay(20); 88*be5e4bdcSMarek Vasut writel(readl(&phy->phypwr) &~PHY_SW_RST0, &phy->rstcon); 89*be5e4bdcSMarek Vasut udelay(20); 90*be5e4bdcSMarek Vasut 91*be5e4bdcSMarek Vasut writel(readl(&phy->phypwr) | OTG_DISABLE_0 | ANALOG_PWRDOWN 92*be5e4bdcSMarek Vasut | FORCE_SUSPEND_0, &phy->phypwr); 93*be5e4bdcSMarek Vasut 94*be5e4bdcSMarek Vasut writel(readl(usb_phy_ctrl) &~USB_PHY_CTRL_EN0, usb_phy_ctrl); 95*be5e4bdcSMarek Vasut 96*be5e4bdcSMarek Vasut writel((readl(&phy->phyclk) & ~(ID_PULLUP0 | COMMON_ON_N0)), 97*be5e4bdcSMarek Vasut &phy->phyclk); 98*be5e4bdcSMarek Vasut 99*be5e4bdcSMarek Vasut udelay(10000); 100*be5e4bdcSMarek Vasut 101*be5e4bdcSMarek Vasut dev->pdata->phy_control(0); 102*be5e4bdcSMarek Vasut } 103