blob: c7eea7b34421ad9bde86d42334852d2f21a133e8 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Marek Vasute64a3372014-11-04 04:13:57 +01002/*
Marek Vasutf8995db2015-12-04 02:34:46 +01003 * drivers/usb/gadget/dwc2_udc_otg.c
Marek Vasut4a7629a2015-12-04 02:55:37 +01004 * Designware DWC2 on-chip full/high speed USB OTG 2.0 device controllers
Marek Vasute64a3372014-11-04 04:13:57 +01005 *
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@samsung.com>
14 *
15 * Ported to u-boot:
16 * Marek Szyprowski <m.szyprowski@samsung.com>
17 * Lukasz Majewski <l.majewski@samsumg.com>
Marek Vasute64a3372014-11-04 04:13:57 +010018 */
19
Simon Glassdbd79542020-05-10 11:40:11 -060020#include <linux/delay.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090021#include <linux/errno.h>
Marek Vasute64a3372014-11-04 04:13:57 +010022#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
Marek Vasut4811c662015-12-04 02:32:22 +010034#include "dwc2_udc_otg_regs.h"
35#include "dwc2_udc_otg_priv.h"
Marek Vasute64a3372014-11-04 04:13:57 +010036
Marek Vasutf1be9cb2015-12-04 02:51:20 +010037#include <usb/dwc2_udc.h>
Marek Vasute64a3372014-11-04 04:13:57 +010038
Marek Vasut1a639ff2015-12-04 00:57:58 +010039void otg_phy_init(struct dwc2_udc *dev)
Marek Vasute64a3372014-11-04 04:13:57 +010040{
41 unsigned int usb_phy_ctrl = dev->pdata->usb_phy_ctrl;
Marek Vasut9d4701d2015-12-04 01:44:41 +010042 struct dwc2_usbotg_phy *phy =
43 (struct dwc2_usbotg_phy *)dev->pdata->regs_phy;
Marek Vasute64a3372014-11-04 04:13:57 +010044
45 dev->pdata->phy_control(1);
46
47 /* USB PHY0 Enable */
48 printf("USB PHY0 Enable\n");
49
50 /* Enable PHY */
51 writel(readl(usb_phy_ctrl) | USB_PHY_CTRL_EN0, usb_phy_ctrl);
52
53 if (dev->pdata->usb_flags == PHY0_SLEEP) /* C210 Universal */
54 writel((readl(&phy->phypwr)
55 &~(PHY_0_SLEEP | OTG_DISABLE_0 | ANALOG_PWRDOWN)
56 &~FORCE_SUSPEND_0), &phy->phypwr);
57 else /* C110 GONI */
58 writel((readl(&phy->phypwr) &~(OTG_DISABLE_0 | ANALOG_PWRDOWN)
59 &~FORCE_SUSPEND_0), &phy->phypwr);
60
61 if (s5p_cpu_id == 0x4412)
62 writel((readl(&phy->phyclk) & ~(EXYNOS4X12_ID_PULLUP0 |
63 EXYNOS4X12_COMMON_ON_N0)) | EXYNOS4X12_CLK_SEL_24MHZ,
64 &phy->phyclk); /* PLL 24Mhz */
65 else
66 writel((readl(&phy->phyclk) & ~(ID_PULLUP0 | COMMON_ON_N0)) |
67 CLK_SEL_24MHZ, &phy->phyclk); /* PLL 24Mhz */
68
69 writel((readl(&phy->rstcon) &~(LINK_SW_RST | PHYLNK_SW_RST))
70 | PHY_SW_RST0, &phy->rstcon);
71 udelay(10);
72 writel(readl(&phy->rstcon)
73 &~(PHY_SW_RST0 | LINK_SW_RST | PHYLNK_SW_RST), &phy->rstcon);
74 udelay(10);
75}
76
Marek Vasut1a639ff2015-12-04 00:57:58 +010077void otg_phy_off(struct dwc2_udc *dev)
Marek Vasute64a3372014-11-04 04:13:57 +010078{
79 unsigned int usb_phy_ctrl = dev->pdata->usb_phy_ctrl;
Marek Vasut9d4701d2015-12-04 01:44:41 +010080 struct dwc2_usbotg_phy *phy =
81 (struct dwc2_usbotg_phy *)dev->pdata->regs_phy;
Marek Vasute64a3372014-11-04 04:13:57 +010082
83 /* reset controller just in case */
84 writel(PHY_SW_RST0, &phy->rstcon);
85 udelay(20);
86 writel(readl(&phy->phypwr) &~PHY_SW_RST0, &phy->rstcon);
87 udelay(20);
88
89 writel(readl(&phy->phypwr) | OTG_DISABLE_0 | ANALOG_PWRDOWN
90 | FORCE_SUSPEND_0, &phy->phypwr);
91
92 writel(readl(usb_phy_ctrl) &~USB_PHY_CTRL_EN0, usb_phy_ctrl);
93
94 writel((readl(&phy->phyclk) & ~(ID_PULLUP0 | COMMON_ON_N0)),
95 &phy->phyclk);
96
97 udelay(10000);
98
99 dev->pdata->phy_control(0);
100}