blob: c484fa7755e75a37c8de669600591e44515b2771 [file] [log] [blame]
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +05301/*
Rajeshwari Shinde7590d3c2012-05-21 16:38:03 +05302 * SAMSUNG EXYNOS USB HOST EHCI Controller
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +05303 *
4 * Copyright (C) 2012 Samsung Electronics Co.Ltd
5 * Vivek Gautam <gautam.vivek@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * MA 02110-1301 USA
21 */
22
23#include <common.h>
24#include <usb.h>
25#include <asm/arch/cpu.h>
Rajeshwari Shinde7590d3c2012-05-21 16:38:03 +053026#include <asm/arch/ehci.h>
Rajeshwari Shinde71045da2012-05-14 05:52:02 +000027#include <asm/arch/system.h>
Rajeshwari Shindec48ac112012-05-14 05:52:03 +000028#include <asm/arch/power.h>
Inderpal Singh63cbf0c2012-11-12 09:25:08 +053029#include <asm/arch/gpio.h>
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +053030#include "ehci.h"
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +053031
32/* Setup the EHCI host controller. */
Rajeshwari Shinde7590d3c2012-05-21 16:38:03 +053033static void setup_usb_phy(struct exynos_usb_phy *usb)
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +053034{
Inderpal Singh63cbf0c2012-11-12 09:25:08 +053035 u32 hsic_ctrl;
36
Rajeshwari Shinde71045da2012-05-14 05:52:02 +000037 set_usbhost_mode(USB20_PHY_CFG_HOST_LINK_EN);
38
Rajeshwari Shindec48ac112012-05-14 05:52:03 +000039 set_usbhost_phy_ctrl(POWER_USB_HOST_PHY_CTRL_EN);
40
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +053041 clrbits_le32(&usb->usbphyctrl0,
42 HOST_CTRL0_FSEL_MASK |
43 HOST_CTRL0_COMMONON_N |
44 /* HOST Phy setting */
45 HOST_CTRL0_PHYSWRST |
46 HOST_CTRL0_PHYSWRSTALL |
47 HOST_CTRL0_SIDDQ |
48 HOST_CTRL0_FORCESUSPEND |
49 HOST_CTRL0_FORCESLEEP);
50
51 setbits_le32(&usb->usbphyctrl0,
52 /* Setting up the ref freq */
53 (CLK_24MHZ << 16) |
54 /* HOST Phy setting */
55 HOST_CTRL0_LINKSWRST |
56 HOST_CTRL0_UTMISWRST);
57 udelay(10);
58 clrbits_le32(&usb->usbphyctrl0,
59 HOST_CTRL0_LINKSWRST |
60 HOST_CTRL0_UTMISWRST);
61 udelay(20);
62
Inderpal Singh63cbf0c2012-11-12 09:25:08 +053063 /* HSIC phy reset */
64 clrbits_le32(&usb->hsicphyctrl1,
65 HSIC_CTRL_FORCESUSPEND |
66 HSIC_CTRL_FORCESLEEP |
67 HSIC_CTRL_SIDDQ);
68
69 clrbits_le32(&usb->hsicphyctrl2,
70 HSIC_CTRL_FORCESUSPEND |
71 HSIC_CTRL_FORCESLEEP |
72 HSIC_CTRL_SIDDQ);
73
74 hsic_ctrl = (((HSIC_CTRL_REFCLKDIV_12 & HSIC_CTRL_REFCLKDIV_MASK)
75 << HSIC_CTRL_REFCLKDIV_SHIFT)
76 | ((HSIC_CTRL_REFCLKSEL & HSIC_CTRL_REFCLKSEL_MASK)
77 << HSIC_CTRL_REFCLKSEL_SHIFT)
78 | HSIC_CTRL_PHYSWRST);
79
80 setbits_le32(&usb->hsicphyctrl1, hsic_ctrl);
81 setbits_le32(&usb->hsicphyctrl2, hsic_ctrl);
82
83 udelay(10);
84
85 clrbits_le32(&usb->hsicphyctrl1, HSIC_CTRL_PHYSWRST);
86 clrbits_le32(&usb->hsicphyctrl2, HSIC_CTRL_PHYSWRST);
87
88 udelay(80);
89
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +053090 /* EHCI Ctrl setting */
91 setbits_le32(&usb->ehcictrl,
92 EHCICTRL_ENAINCRXALIGN |
93 EHCICTRL_ENAINCR4 |
94 EHCICTRL_ENAINCR8 |
95 EHCICTRL_ENAINCR16);
96}
97
98/* Reset the EHCI host controller. */
Rajeshwari Shinde7590d3c2012-05-21 16:38:03 +053099static void reset_usb_phy(struct exynos_usb_phy *usb)
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +0530100{
101 /* HOST_PHY reset */
102 setbits_le32(&usb->usbphyctrl0,
103 HOST_CTRL0_PHYSWRST |
104 HOST_CTRL0_PHYSWRSTALL |
105 HOST_CTRL0_SIDDQ |
106 HOST_CTRL0_FORCESUSPEND |
107 HOST_CTRL0_FORCESLEEP);
Rajeshwari Shindec48ac112012-05-14 05:52:03 +0000108
109 set_usbhost_phy_ctrl(POWER_USB_HOST_PHY_CTRL_DISABLE);
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +0530110}
111
Inderpal Singh63cbf0c2012-11-12 09:25:08 +0530112struct exynos5_gpio_part1 *gpio;
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +0530113/*
114 * EHCI-initialization
115 * Create the appropriate control structures to manage
116 * a new EHCI host controller.
117 */
Lucas Stach676ae062012-09-26 00:14:35 +0200118int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +0530119{
Rajeshwari Shinde7590d3c2012-05-21 16:38:03 +0530120 struct exynos_usb_phy *usb;
Inderpal Singh63cbf0c2012-11-12 09:25:08 +0530121 gpio = (struct exynos5_gpio_part1 *) EXYNOS5_GPIO_PART1_BASE;
Rajeshwari Shinde7590d3c2012-05-21 16:38:03 +0530122 usb = (struct exynos_usb_phy *)samsung_get_base_usb_phy();
Inderpal Singh63cbf0c2012-11-12 09:25:08 +0530123
124 s5p_gpio_direction_output(&gpio->x3, 5, 0);
125 s5p_gpio_direction_output(&gpio->d1, 7, 0);
126
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +0530127 setup_usb_phy(usb);
128
Inderpal Singh63cbf0c2012-11-12 09:25:08 +0530129 s5p_gpio_direction_output(&gpio->x3, 5, 1);
130 s5p_gpio_direction_output(&gpio->d1, 7, 1);
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +0530131
Inderpal Singh63cbf0c2012-11-12 09:25:08 +0530132 *hccr = (struct ehci_hccr *)samsung_get_base_usb_ehci();
John Rigbycf2e09a2013-01-23 13:54:53 -0700133 *hcor = (struct ehci_hcor *)((uint32_t) *hccr
Inderpal Singh63cbf0c2012-11-12 09:25:08 +0530134 + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +0530135 debug("Exynos5-ehci: init hccr %x and hcor %x hc_length %d\n",
Lucas Stach676ae062012-09-26 00:14:35 +0200136 (uint32_t)*hccr, (uint32_t)*hcor,
137 (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +0530138
139 return 0;
140}
141
142/*
143 * Destroy the appropriate control structures corresponding
144 * the EHCI host controller.
145 */
Lucas Stach676ae062012-09-26 00:14:35 +0200146int ehci_hcd_stop(int index)
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +0530147{
Rajeshwari Shinde7590d3c2012-05-21 16:38:03 +0530148 struct exynos_usb_phy *usb;
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +0530149
Rajeshwari Shinde7590d3c2012-05-21 16:38:03 +0530150 usb = (struct exynos_usb_phy *)samsung_get_base_usb_phy();
Rajeshwari Shinde5f0ffea2012-05-02 19:18:51 +0530151 reset_usb_phy(usb);
152
153 return 0;
154}