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