]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/genesi/mx51_efikamx/efikamx-usb.c
Merge git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / board / genesi / mx51_efikamx / efikamx-usb.c
1 /*
2  * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
3  *
4  * (C) Copyright 2009 Freescale Semiconductor, Inc.
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #include <common.h>
10 #include <usb.h>
11 #include <asm/io.h>
12 #include <asm/arch/imx-regs.h>
13 #include <asm/arch/iomux-mx51.h>
14 #include <asm/gpio.h>
15 #include <usb/ehci-fsl.h>
16 #include <usb/ulpi.h>
17 #include <errno.h>
18
19 #include "../../../drivers/usb/host/ehci.h"
20
21 /*
22  * Configure the USB H1 and USB H2 IOMUX
23  */
24 void setup_iomux_usb(void)
25 {
26         static const iomux_v3_cfg_t usb_h1_pads[] = {
27                 MX51_PAD_USBH1_CLK__USBH1_CLK,
28                 MX51_PAD_USBH1_DIR__USBH1_DIR,
29                 MX51_PAD_USBH1_STP__USBH1_STP,
30                 MX51_PAD_USBH1_NXT__USBH1_NXT,
31                 MX51_PAD_USBH1_DATA0__USBH1_DATA0,
32                 MX51_PAD_USBH1_DATA1__USBH1_DATA1,
33                 MX51_PAD_USBH1_DATA2__USBH1_DATA2,
34                 MX51_PAD_USBH1_DATA3__USBH1_DATA3,
35                 MX51_PAD_USBH1_DATA4__USBH1_DATA4,
36                 MX51_PAD_USBH1_DATA5__USBH1_DATA5,
37                 MX51_PAD_USBH1_DATA6__USBH1_DATA6,
38                 MX51_PAD_USBH1_DATA7__USBH1_DATA7,
39         };
40
41         static const iomux_v3_cfg_t usb_pads[] = {
42                 MX51_PAD_EIM_D27__GPIO2_9, /* USB PHY reset */
43                 MX51_PAD_GPIO1_5__GPIO1_5, /* USB HUB reset */
44                 NEW_PAD_CTRL(MX51_PAD_EIM_A22__GPIO2_16, 0), /* WIFI /EN */
45                 NEW_PAD_CTRL(MX51_PAD_EIM_A16__GPIO2_10, 0), /* WIFI RESET */
46                 NEW_PAD_CTRL(MX51_PAD_EIM_A17__GPIO2_11, 0), /* BT /EN */
47         };
48
49         imx_iomux_v3_setup_multiple_pads(usb_h1_pads, ARRAY_SIZE(usb_h1_pads));
50
51         if (machine_is_efikasb()) {
52                 static const iomux_v3_cfg_t usb_h2_pads[] = {
53                         MX51_PAD_EIM_A24__USBH2_CLK,
54                         MX51_PAD_EIM_A25__USBH2_DIR,
55                         MX51_PAD_EIM_A26__USBH2_STP,
56                         MX51_PAD_EIM_A27__USBH2_NXT,
57                         MX51_PAD_EIM_D16__USBH2_DATA0,
58                         MX51_PAD_EIM_D17__USBH2_DATA1,
59                         MX51_PAD_EIM_D18__USBH2_DATA2,
60                         MX51_PAD_EIM_D19__USBH2_DATA3,
61                         MX51_PAD_EIM_D20__USBH2_DATA4,
62                         MX51_PAD_EIM_D21__USBH2_DATA5,
63                         MX51_PAD_EIM_D22__USBH2_DATA6,
64                         MX51_PAD_EIM_D23__USBH2_DATA7,
65                 };
66
67                 imx_iomux_v3_setup_multiple_pads(usb_h2_pads,
68                                                  ARRAY_SIZE(usb_h2_pads));
69         }
70
71         imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
72 }
73
74 /*
75  * Enable devices connected to USB BUSes
76  */
77 static void efika_usb_enable_devices(void)
78 {
79         /* Enable Bluetooth */
80         gpio_direction_output(IMX_GPIO_NR(2, 11), 0);
81         udelay(10000);
82         gpio_set_value(IMX_GPIO_NR(2, 11), 1);
83
84         /* Enable WiFi */
85         gpio_direction_output(IMX_GPIO_NR(2, 16), 1);
86         udelay(10000);
87
88         /* Reset the WiFi chip */
89         gpio_direction_output(IMX_GPIO_NR(2, 10), 0);
90         udelay(10000);
91         gpio_set_value(IMX_GPIO_NR(2, 10), 1);
92 }
93
94 /*
95  * Reset USB HUB (or HUBs on EfikaSB)
96  */
97 static void efika_usb_hub_reset(void)
98 {
99         /* HUB reset */
100         gpio_direction_output(IMX_GPIO_NR(1, 5), 1);
101         udelay(1000);
102         gpio_set_value(IMX_GPIO_NR(1, 5), 0);
103         udelay(1000);
104         gpio_set_value(IMX_GPIO_NR(1, 5), 1);
105 }
106
107 /*
108  * Reset USB PHY (or PHYs on EfikaSB)
109  */
110 static void efika_usb_phy_reset(void)
111 {
112         /* SMSC 3317 PHY reset */
113         gpio_direction_output(IMX_GPIO_NR(2, 9), 0);
114         udelay(1000);
115         gpio_set_value(IMX_GPIO_NR(2, 9), 1);
116 }
117
118 static void efika_ehci_init(struct usb_ehci *ehci, uint32_t stp_gpio,
119                                 iomux_v3_cfg_t stp_pad_gpio,
120                                 iomux_v3_cfg_t stp_pad_usb)
121 {
122         int ret;
123         struct ulpi_regs *ulpi = (struct ulpi_regs *)0;
124         struct ulpi_viewport ulpi_vp;
125
126         imx_iomux_v3_setup_pad(stp_pad_gpio);
127         gpio_direction_output(stp_gpio, 0);
128         udelay(1000);
129         gpio_set_value(stp_gpio, 1);
130         udelay(1000);
131
132         imx_iomux_v3_setup_pad(stp_pad_usb);
133         udelay(10000);
134
135         ulpi_vp.viewport_addr = (u32)&ehci->ulpi_viewpoint;
136         ulpi_vp.port_num = 0;
137
138         ret = ulpi_init(&ulpi_vp);
139         if (ret) {
140                 printf("Efika USB ULPI initialization failed\n");
141                 return;
142         }
143
144         /* ULPI set flags */
145         ulpi_write(&ulpi_vp, &ulpi->otg_ctrl,
146                         ULPI_OTG_DP_PULLDOWN | ULPI_OTG_DM_PULLDOWN |
147                         ULPI_OTG_EXTVBUSIND);
148         ulpi_write(&ulpi_vp, &ulpi->function_ctrl,
149                         ULPI_FC_FULL_SPEED | ULPI_FC_OPMODE_NORMAL |
150                         ULPI_FC_SUSPENDM);
151         ulpi_write(&ulpi_vp, &ulpi->iface_ctrl, 0);
152
153         /* Set VBus */
154         ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set,
155                         ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
156
157         /*
158          * Set VBusChrg
159          *
160          * NOTE: This violates USB specification, but otherwise, USB on Efika
161          * doesn't work.
162          */
163         ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set, ULPI_OTG_CHRGVBUS);
164 }
165
166 int board_ehci_hcd_init(int port)
167 {
168         /* Init iMX51 EHCI */
169         efika_usb_phy_reset();
170         efika_usb_hub_reset();
171         efika_usb_enable_devices();
172
173         return 0;
174 }
175
176 void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
177 {
178         uint32_t port = OTG_BASE_ADDR + (0x200 * CONFIG_MXC_USB_PORT);
179         struct usb_ehci *ehci = (struct usb_ehci *)port;
180         struct ulpi_regs *ulpi = (struct ulpi_regs *)0;
181         struct ulpi_viewport ulpi_vp;
182
183         ulpi_vp.viewport_addr = (u32)&ehci->ulpi_viewpoint;
184         ulpi_vp.port_num = 0;
185
186         ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set, ULPI_OTG_CHRGVBUS);
187
188         mdelay(50);
189
190         /* terminate the reset */
191         *reg = ehci_readl(status_reg);
192         *reg |= EHCI_PS_PE;
193 }
194
195 void board_ehci_hcd_postinit(struct usb_ehci *ehci, int port)
196 {
197         uint32_t tmp;
198
199         if (port == 0) {
200                 /* Adjust UTMI PHY frequency to 24MHz */
201                 tmp = readl(OTG_BASE_ADDR + 0x80c);
202                 tmp = (tmp & ~0x3) | 0x01;
203                 writel(tmp, OTG_BASE_ADDR + 0x80c);
204         } else if (port == 1) {
205                 efika_ehci_init(ehci, IMX_GPIO_NR(1, 27),
206                                 MX51_PAD_USBH1_STP__GPIO1_27,
207                                 MX51_PAD_USBH1_STP__USBH1_STP);
208         } else if ((port == 2) && machine_is_efikasb()) {
209                 efika_ehci_init(ehci, IMX_GPIO_NR(2, 20),
210                                 MX51_PAD_EIM_A26__GPIO2_20,
211                                 MX51_PAD_EIM_A26__USBH2_STP);
212         }
213
214         if (port)
215                 mdelay(10);
216 }
217
218 /*
219  * Ethernet on the Smarttop is on the USB bus. Rather than give an error about
220  * "CPU Net Initialization Failed", just pass this test since no other settings
221  * are required. Smartbook doesn't have built-in Ethernet but we will let it
222  * pass anyway considering someone may have plugged in a USB stick and all
223  * they need to do is run "usb start".
224  */
225 int board_eth_init(bd_t *bis)
226 {
227         return 0;
228 }