1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 2011
5 * Ben Gray <ben.r.gray@gmail.com>.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the company nor the name of the author may be used to
17 * endorse or promote products derived from this software without specific
18 * prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/kernel.h>
36
37 #include <vm/vm.h>
38 #include <vm/pmap.h>
39
40 #include <machine/bus.h>
41 #include <machine/vmparam.h>
42 #include <machine/fdt.h>
43
44 #include <arm/ti/omap4/omap4_reg.h>
45 #include <arm/ti/omap4/pandaboard/pandaboard.h>
46
47 /* Registers in the SCRM that control the AUX clocks */
48 #define SCRM_ALTCLKSRC (0x110)
49 #define SCRM_AUXCLK0 (0x0310)
50 #define SCRM_AUXCLK1 (0x0314)
51 #define SCRM_AUXCLK2 (0x0318)
52 #define SCRM_AUXCLK3 (0x031C)
53
54 /* Some of the GPIO register set */
55 #define GPIO1_OE (0x0134)
56 #define GPIO1_CLEARDATAOUT (0x0190)
57 #define GPIO1_SETDATAOUT (0x0194)
58 #define GPIO2_OE (0x0134)
59 #define GPIO2_CLEARDATAOUT (0x0190)
60 #define GPIO2_SETDATAOUT (0x0194)
61
62 /* Some of the PADCONF register set */
63 #define CONTROL_WKUP_PAD0_FREF_CLK3_OUT (0x058)
64 #define CONTROL_CORE_PAD1_KPD_COL2 (0x186)
65 #define CONTROL_CORE_PAD0_GPMC_WAIT1 (0x08C)
66
67 #define REG_WRITE32(r, x) *((volatile uint32_t*)(r)) = (uint32_t)(x)
68 #define REG_READ32(r) *((volatile uint32_t*)(r))
69
70 #define REG_WRITE16(r, x) *((volatile uint16_t*)(r)) = (uint16_t)(x)
71 #define REG_READ16(r) *((volatile uint16_t*)(r))
72
73 /**
74 * usb_hub_init - initialises and resets the external USB hub
75 *
76 * The USB hub needs to be held in reset while the power is being applied
77 * and the reference clock is enabled at 19.2MHz. The following is the
78 * layout of the USB hub taken from the Pandaboard reference manual.
79 *
80 *
81 * .-------------. .--------------. .----------------.
82 * | OMAP4430 | | USB3320C | | LAN9514 |
83 * | | | | | USB Hub / Eth |
84 * | CLK | <------ | CLKOUT | | |
85 * | STP | ------> | STP | | |
86 * | DIR | <------ | DIR | | |
87 * | NXT | <------ | NXT | | |
88 * | DAT0 | <-----> | DAT0 | | |
89 * | DAT1 | <-----> | DAT1 DP | <-----> | DP |
90 * | DAT2 | <-----> | DAT2 DM | <-----> | DM |
91 * | DAT3 | <-----> | DAT3 | | |
92 * | DAT4 | <-----> | DAT4 | | |
93 * | DAT5 | <-----> | DAT5 | +----> | N_RESET |
94 * | DAT6 | <-----> | DAT6 | | | |
95 * | DAT7 | <-----> | DAT7 | | | |
96 * | | | | | +-> | VDD33IO |
97 * | AUX_CLK3 | ------> | REFCLK | | +-> | VDD33A |
98 * | | | | | | | |
99 * | GPIO_62 | --+---> | RESET | | | | |
100 * | | | | | | | | |
101 * | | | '--------------' | | '----------------'
102 * | | | .--------------. | |
103 * | | '---->| VOLT CONVERT |--' |
104 * | | '--------------' |
105 * | | |
106 * | | .--------------. |
107 * | GPIO_1 | ------> | TPS73633 |-----'
108 * | | '--------------'
109 * '-------------'
110 *
111 *
112 * RETURNS:
113 * nothing.
114 */
115 void
pandaboard_usb_hub_init(void)116 pandaboard_usb_hub_init(void)
117 {
118 bus_space_handle_t scrm_addr, gpio1_addr, gpio2_addr, scm_addr;
119
120 if (bus_space_map(fdtbus_bs_tag, OMAP44XX_SCRM_HWBASE,
121 OMAP44XX_SCRM_SIZE, 0, &scrm_addr) != 0)
122 panic("Couldn't map SCRM registers");
123 if (bus_space_map(fdtbus_bs_tag, OMAP44XX_GPIO1_HWBASE,
124 OMAP44XX_GPIO1_SIZE, 0, &gpio1_addr) != 0)
125 panic("Couldn't map GPIO1 registers");
126 if (bus_space_map(fdtbus_bs_tag, OMAP44XX_GPIO2_HWBASE,
127 OMAP44XX_GPIO2_SIZE, 0, &gpio2_addr) != 0)
128 panic("Couldn't map GPIO2 registers");
129 if (bus_space_map(fdtbus_bs_tag, OMAP44XX_SCM_PADCONF_HWBASE,
130 OMAP44XX_SCM_PADCONF_SIZE, 0, &scm_addr) != 0)
131 panic("Couldn't map SCM Padconf registers");
132
133 /* Need to set FREF_CLK3_OUT to 19.2 MHz and pump it out on pin GPIO_WK31.
134 * We know the SYS_CLK is 38.4Mhz and therefore to get the needed 19.2Mhz,
135 * just use a 2x divider and ensure the SYS_CLK is used as the source.
136 */
137 REG_WRITE32(scrm_addr + SCRM_AUXCLK3, (1 << 16) | /* Divider of 2 */
138 (0 << 1) | /* Use the SYS_CLK as the source */
139 (1 << 8)); /* Enable the clock */
140
141 /* Enable the clock out to the pin (GPIO_WK31).
142 * muxmode=fref_clk3_out, pullup/down=disabled, input buffer=disabled,
143 * wakeup=disabled.
144 */
145 REG_WRITE16(scm_addr + CONTROL_WKUP_PAD0_FREF_CLK3_OUT, 0x0000);
146
147 /* Disable the power to the USB hub, drive GPIO1 low */
148 REG_WRITE32(gpio1_addr + GPIO1_OE, REG_READ32(gpio1_addr +
149 GPIO1_OE) & ~(1UL << 1));
150 REG_WRITE32(gpio1_addr + GPIO1_CLEARDATAOUT, (1UL << 1));
151 REG_WRITE16(scm_addr + CONTROL_CORE_PAD1_KPD_COL2, 0x0003);
152
153 /* Reset the USB PHY and Hub using GPIO_62 */
154 REG_WRITE32(gpio2_addr + GPIO2_OE,
155 REG_READ32(gpio2_addr + GPIO2_OE) & ~(1UL << 30));
156 REG_WRITE32(gpio2_addr + GPIO2_CLEARDATAOUT, (1UL << 30));
157 REG_WRITE16(scm_addr + CONTROL_CORE_PAD0_GPMC_WAIT1, 0x0003);
158 DELAY(10);
159 REG_WRITE32(gpio2_addr + GPIO2_SETDATAOUT, (1UL << 30));
160
161 /* Enable power to the hub (GPIO_1) */
162 REG_WRITE32(gpio1_addr + GPIO1_SETDATAOUT, (1UL << 1));
163 bus_space_unmap(fdtbus_bs_tag, scrm_addr, OMAP44XX_SCRM_SIZE);
164 bus_space_unmap(fdtbus_bs_tag, gpio1_addr, OMAP44XX_GPIO1_SIZE);
165 bus_space_unmap(fdtbus_bs_tag, gpio2_addr, OMAP44XX_GPIO2_SIZE);
166 bus_space_unmap(fdtbus_bs_tag, scm_addr, OMAP44XX_SCM_PADCONF_SIZE);
167 }
168