blob: cabad70af4bad511db88b3863e54c952a1eceafe [file] [log] [blame]
Marek Vasutd98d8bc2011-06-24 21:46:07 +02001/*
2 * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
3 *
4 * (C) Copyright 2009 Freescale Semiconductor, Inc.
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 */
24
25#include <common.h>
26#include <usb.h>
27#include <asm/io.h>
28#include <asm/arch/imx-regs.h>
Benoît Thébaudeau3426a622013-05-03 10:32:28 +000029#include <asm/arch/iomux-mx51.h>
Marek Vasutd98d8bc2011-06-24 21:46:07 +020030#include <asm/gpio.h>
31#include <usb/ehci-fsl.h>
32#include <usb/ulpi.h>
33#include <errno.h>
34
Matt Sealey4ee80c62012-08-22 09:25:38 +000035#include "../../../drivers/usb/host/ehci.h"
Marek Vasutd98d8bc2011-06-24 21:46:07 +020036
Marek Vasutd98d8bc2011-06-24 21:46:07 +020037/*
38 * Configure the USB H1 and USB H2 IOMUX
39 */
40void setup_iomux_usb(void)
41{
Benoît Thébaudeau3426a622013-05-03 10:32:28 +000042 static const iomux_v3_cfg_t usb_h1_pads[] = {
43 MX51_PAD_USBH1_CLK__USBH1_CLK,
44 MX51_PAD_USBH1_DIR__USBH1_DIR,
45 MX51_PAD_USBH1_STP__USBH1_STP,
46 MX51_PAD_USBH1_NXT__USBH1_NXT,
47 MX51_PAD_USBH1_DATA0__USBH1_DATA0,
48 MX51_PAD_USBH1_DATA1__USBH1_DATA1,
49 MX51_PAD_USBH1_DATA2__USBH1_DATA2,
50 MX51_PAD_USBH1_DATA3__USBH1_DATA3,
51 MX51_PAD_USBH1_DATA4__USBH1_DATA4,
52 MX51_PAD_USBH1_DATA5__USBH1_DATA5,
53 MX51_PAD_USBH1_DATA6__USBH1_DATA6,
54 MX51_PAD_USBH1_DATA7__USBH1_DATA7,
55 };
Marek Vasutd98d8bc2011-06-24 21:46:07 +020056
Benoît Thébaudeau3426a622013-05-03 10:32:28 +000057 static const iomux_v3_cfg_t usb_pads[] = {
58 MX51_PAD_EIM_D27__GPIO2_9, /* USB PHY reset */
59 MX51_PAD_GPIO1_5__GPIO1_5, /* USB HUB reset */
60 NEW_PAD_CTRL(MX51_PAD_EIM_A22__GPIO2_16, 0), /* WIFI /EN */
61 NEW_PAD_CTRL(MX51_PAD_EIM_A16__GPIO2_10, 0), /* WIFI RESET */
62 NEW_PAD_CTRL(MX51_PAD_EIM_A17__GPIO2_11, 0), /* BT /EN */
63 };
Marek Vasutd98d8bc2011-06-24 21:46:07 +020064
Benoît Thébaudeau3426a622013-05-03 10:32:28 +000065 imx_iomux_v3_setup_multiple_pads(usb_h1_pads, ARRAY_SIZE(usb_h1_pads));
Marek Vasutd98d8bc2011-06-24 21:46:07 +020066
Benoît Thébaudeau3426a622013-05-03 10:32:28 +000067 if (machine_is_efikasb()) {
68 static const iomux_v3_cfg_t usb_h2_pads[] = {
69 MX51_PAD_EIM_A24__USBH2_CLK,
70 MX51_PAD_EIM_A25__USBH2_DIR,
71 MX51_PAD_EIM_A26__USBH2_STP,
72 MX51_PAD_EIM_A27__USBH2_NXT,
73 MX51_PAD_EIM_D16__USBH2_DATA0,
74 MX51_PAD_EIM_D17__USBH2_DATA1,
75 MX51_PAD_EIM_D18__USBH2_DATA2,
76 MX51_PAD_EIM_D19__USBH2_DATA3,
77 MX51_PAD_EIM_D20__USBH2_DATA4,
78 MX51_PAD_EIM_D21__USBH2_DATA5,
79 MX51_PAD_EIM_D22__USBH2_DATA6,
80 MX51_PAD_EIM_D23__USBH2_DATA7,
81 };
Marek Vasutd98d8bc2011-06-24 21:46:07 +020082
Benoît Thébaudeau3426a622013-05-03 10:32:28 +000083 imx_iomux_v3_setup_multiple_pads(usb_h2_pads,
84 ARRAY_SIZE(usb_h2_pads));
85 }
86
87 imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
Marek Vasutd98d8bc2011-06-24 21:46:07 +020088}
89
90/*
91 * Enable devices connected to USB BUSes
92 */
93static void efika_usb_enable_devices(void)
94{
95 /* Enable Bluetooth */
Benoît Thébaudeau3426a622013-05-03 10:32:28 +000096 gpio_direction_output(IMX_GPIO_NR(2, 11), 0);
Marek Vasutd98d8bc2011-06-24 21:46:07 +020097 udelay(10000);
Benoît Thébaudeau3426a622013-05-03 10:32:28 +000098 gpio_set_value(IMX_GPIO_NR(2, 11), 1);
Marek Vasutd98d8bc2011-06-24 21:46:07 +020099
100 /* Enable WiFi */
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000101 gpio_direction_output(IMX_GPIO_NR(2, 16), 1);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200102 udelay(10000);
103
104 /* Reset the WiFi chip */
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000105 gpio_direction_output(IMX_GPIO_NR(2, 10), 0);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200106 udelay(10000);
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000107 gpio_set_value(IMX_GPIO_NR(2, 10), 1);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200108}
109
110/*
111 * Reset USB HUB (or HUBs on EfikaSB)
112 */
113static void efika_usb_hub_reset(void)
114{
115 /* HUB reset */
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000116 gpio_direction_output(IMX_GPIO_NR(1, 5), 1);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200117 udelay(1000);
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000118 gpio_set_value(IMX_GPIO_NR(1, 5), 0);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200119 udelay(1000);
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000120 gpio_set_value(IMX_GPIO_NR(1, 5), 1);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200121}
122
123/*
124 * Reset USB PHY (or PHYs on EfikaSB)
125 */
126static void efika_usb_phy_reset(void)
127{
128 /* SMSC 3317 PHY reset */
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000129 gpio_direction_output(IMX_GPIO_NR(2, 9), 0);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200130 udelay(1000);
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000131 gpio_set_value(IMX_GPIO_NR(2, 9), 1);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200132}
133
134static void efika_ehci_init(struct usb_ehci *ehci, uint32_t stp_gpio,
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000135 iomux_v3_cfg_t stp_pad_gpio,
136 iomux_v3_cfg_t stp_pad_usb)
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200137{
138 int ret;
139 struct ulpi_regs *ulpi = (struct ulpi_regs *)0;
Govindraj.R3e6e8092012-02-06 03:55:31 +0000140 struct ulpi_viewport ulpi_vp;
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200141
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000142 imx_iomux_v3_setup_pad(stp_pad_gpio);
143 gpio_direction_output(stp_gpio, 0);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200144 udelay(1000);
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000145 gpio_set_value(stp_gpio, 1);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200146 udelay(1000);
147
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000148 imx_iomux_v3_setup_pad(stp_pad_usb);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200149 udelay(10000);
150
Govindraj.R3e6e8092012-02-06 03:55:31 +0000151 ulpi_vp.viewport_addr = (u32)&ehci->ulpi_viewpoint;
152 ulpi_vp.port_num = 0;
153
154 ret = ulpi_init(&ulpi_vp);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200155 if (ret) {
156 printf("Efika USB ULPI initialization failed\n");
157 return;
158 }
159
160 /* ULPI set flags */
Govindraj.R3e6e8092012-02-06 03:55:31 +0000161 ulpi_write(&ulpi_vp, &ulpi->otg_ctrl,
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200162 ULPI_OTG_DP_PULLDOWN | ULPI_OTG_DM_PULLDOWN |
163 ULPI_OTG_EXTVBUSIND);
Govindraj.R3e6e8092012-02-06 03:55:31 +0000164 ulpi_write(&ulpi_vp, &ulpi->function_ctrl,
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200165 ULPI_FC_FULL_SPEED | ULPI_FC_OPMODE_NORMAL |
166 ULPI_FC_SUSPENDM);
Govindraj.R3e6e8092012-02-06 03:55:31 +0000167 ulpi_write(&ulpi_vp, &ulpi->iface_ctrl, 0);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200168
169 /* Set VBus */
Govindraj.R3e6e8092012-02-06 03:55:31 +0000170 ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set,
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200171 ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
172
173 /*
174 * Set VBusChrg
175 *
176 * NOTE: This violates USB specification, but otherwise, USB on Efika
177 * doesn't work.
178 */
Govindraj.R3e6e8092012-02-06 03:55:31 +0000179 ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set, ULPI_OTG_CHRGVBUS);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200180}
181
182int board_ehci_hcd_init(int port)
183{
184 /* Init iMX51 EHCI */
185 efika_usb_phy_reset();
186 efika_usb_hub_reset();
187 efika_usb_enable_devices();
188
189 return 0;
190}
191
192void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
193{
194 uint32_t port = OTG_BASE_ADDR + (0x200 * CONFIG_MXC_USB_PORT);
195 struct usb_ehci *ehci = (struct usb_ehci *)port;
196 struct ulpi_regs *ulpi = (struct ulpi_regs *)0;
Govindraj.R3e6e8092012-02-06 03:55:31 +0000197 struct ulpi_viewport ulpi_vp;
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200198
Govindraj.R3e6e8092012-02-06 03:55:31 +0000199 ulpi_vp.viewport_addr = (u32)&ehci->ulpi_viewpoint;
200 ulpi_vp.port_num = 0;
201
202 ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set, ULPI_OTG_CHRGVBUS);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200203
Mike Frysinger5b84dd62012-03-05 13:47:00 +0000204 mdelay(50);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200205
206 /* terminate the reset */
207 *reg = ehci_readl(status_reg);
208 *reg |= EHCI_PS_PE;
209}
210
211void board_ehci_hcd_postinit(struct usb_ehci *ehci, int port)
212{
213 uint32_t tmp;
214
215 if (port == 0) {
216 /* Adjust UTMI PHY frequency to 24MHz */
217 tmp = readl(OTG_BASE_ADDR + 0x80c);
218 tmp = (tmp & ~0x3) | 0x01;
219 writel(tmp, OTG_BASE_ADDR + 0x80c);
220 } else if (port == 1) {
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000221 efika_ehci_init(ehci, IMX_GPIO_NR(1, 27),
222 MX51_PAD_USBH1_STP__GPIO1_27,
223 MX51_PAD_USBH1_STP__USBH1_STP);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200224 } else if ((port == 2) && machine_is_efikasb()) {
Benoît Thébaudeau3426a622013-05-03 10:32:28 +0000225 efika_ehci_init(ehci, IMX_GPIO_NR(2, 20),
226 MX51_PAD_EIM_A26__GPIO2_20,
227 MX51_PAD_EIM_A26__USBH2_STP);
Marek Vasutd98d8bc2011-06-24 21:46:07 +0200228 }
229
230 if (port)
231 mdelay(10);
232}
Matt Sealey0d7d3832012-08-23 04:52:33 +0000233
234/*
235 * Ethernet on the Smarttop is on the USB bus. Rather than give an error about
236 * "CPU Net Initialization Failed", just pass this test since no other settings
237 * are required. Smartbook doesn't have built-in Ethernet but we will let it
238 * pass anyway considering someone may have plugged in a USB stick and all
239 * they need to do is run "usb start".
240 */
241int board_eth_init(bd_t *bis)
242{
243 return 0;
244}