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 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/bus.h> 37 #include <sys/kernel.h> 38 39 #include <vm/vm.h> 40 #include <vm/pmap.h> 41 42 #include <machine/bus.h> 43 #include <machine/vmparam.h> 44 #include <machine/fdt.h> 45 46 #include <arm/ti/omap4/omap4_reg.h> 47 #include <arm/ti/omap4/pandaboard/pandaboard.h> 48 49 /* Registers in the SCRM that control the AUX clocks */ 50 #define SCRM_ALTCLKSRC (0x110) 51 #define SCRM_AUXCLK0 (0x0310) 52 #define SCRM_AUXCLK1 (0x0314) 53 #define SCRM_AUXCLK2 (0x0318) 54 #define SCRM_AUXCLK3 (0x031C) 55 56 /* Some of the GPIO register set */ 57 #define GPIO1_OE (0x0134) 58 #define GPIO1_CLEARDATAOUT (0x0190) 59 #define GPIO1_SETDATAOUT (0x0194) 60 #define GPIO2_OE (0x0134) 61 #define GPIO2_CLEARDATAOUT (0x0190) 62 #define GPIO2_SETDATAOUT (0x0194) 63 64 /* Some of the PADCONF register set */ 65 #define CONTROL_WKUP_PAD0_FREF_CLK3_OUT (0x058) 66 #define CONTROL_CORE_PAD1_KPD_COL2 (0x186) 67 #define CONTROL_CORE_PAD0_GPMC_WAIT1 (0x08C) 68 69 #define REG_WRITE32(r, x) *((volatile uint32_t*)(r)) = (uint32_t)(x) 70 #define REG_READ32(r) *((volatile uint32_t*)(r)) 71 72 #define REG_WRITE16(r, x) *((volatile uint16_t*)(r)) = (uint16_t)(x) 73 #define REG_READ16(r) *((volatile uint16_t*)(r)) 74 75 /** 76 * usb_hub_init - initialises and resets the external USB hub 77 * 78 * The USB hub needs to be held in reset while the power is being applied 79 * and the reference clock is enabled at 19.2MHz. The following is the 80 * layout of the USB hub taken from the Pandaboard reference manual. 81 * 82 * 83 * .-------------. .--------------. .----------------. 84 * | OMAP4430 | | USB3320C | | LAN9514 | 85 * | | | | | USB Hub / Eth | 86 * | CLK | <------ | CLKOUT | | | 87 * | STP | ------> | STP | | | 88 * | DIR | <------ | DIR | | | 89 * | NXT | <------ | NXT | | | 90 * | DAT0 | <-----> | DAT0 | | | 91 * | DAT1 | <-----> | DAT1 DP | <-----> | DP | 92 * | DAT2 | <-----> | DAT2 DM | <-----> | DM | 93 * | DAT3 | <-----> | DAT3 | | | 94 * | DAT4 | <-----> | DAT4 | | | 95 * | DAT5 | <-----> | DAT5 | +----> | N_RESET | 96 * | DAT6 | <-----> | DAT6 | | | | 97 * | DAT7 | <-----> | DAT7 | | | | 98 * | | | | | +-> | VDD33IO | 99 * | AUX_CLK3 | ------> | REFCLK | | +-> | VDD33A | 100 * | | | | | | | | 101 * | GPIO_62 | --+---> | RESET | | | | | 102 * | | | | | | | | | 103 * | | | '--------------' | | '----------------' 104 * | | | .--------------. | | 105 * | | '---->| VOLT CONVERT |--' | 106 * | | '--------------' | 107 * | | | 108 * | | .--------------. | 109 * | GPIO_1 | ------> | TPS73633 |-----' 110 * | | '--------------' 111 * '-------------' 112 * 113 * 114 * RETURNS: 115 * nothing. 116 */ 117 void 118 pandaboard_usb_hub_init(void) 119 { 120 bus_space_handle_t scrm_addr, gpio1_addr, gpio2_addr, scm_addr; 121 122 if (bus_space_map(fdtbus_bs_tag, OMAP44XX_SCRM_HWBASE, 123 OMAP44XX_SCRM_SIZE, 0, &scrm_addr) != 0) 124 panic("Couldn't map SCRM registers"); 125 if (bus_space_map(fdtbus_bs_tag, OMAP44XX_GPIO1_HWBASE, 126 OMAP44XX_GPIO1_SIZE, 0, &gpio1_addr) != 0) 127 panic("Couldn't map GPIO1 registers"); 128 if (bus_space_map(fdtbus_bs_tag, OMAP44XX_GPIO2_HWBASE, 129 OMAP44XX_GPIO2_SIZE, 0, &gpio2_addr) != 0) 130 panic("Couldn't map GPIO2 registers"); 131 if (bus_space_map(fdtbus_bs_tag, OMAP44XX_SCM_PADCONF_HWBASE, 132 OMAP44XX_SCM_PADCONF_SIZE, 0, &scm_addr) != 0) 133 panic("Couldn't map SCM Padconf registers"); 134 135 136 137 /* Need to set FREF_CLK3_OUT to 19.2 MHz and pump it out on pin GPIO_WK31. 138 * We know the SYS_CLK is 38.4Mhz and therefore to get the needed 19.2Mhz, 139 * just use a 2x divider and ensure the SYS_CLK is used as the source. 140 */ 141 REG_WRITE32(scrm_addr + SCRM_AUXCLK3, (1 << 16) | /* Divider of 2 */ 142 (0 << 1) | /* Use the SYS_CLK as the source */ 143 (1 << 8)); /* Enable the clock */ 144 145 /* Enable the clock out to the pin (GPIO_WK31). 146 * muxmode=fref_clk3_out, pullup/down=disabled, input buffer=disabled, 147 * wakeup=disabled. 148 */ 149 REG_WRITE16(scm_addr + CONTROL_WKUP_PAD0_FREF_CLK3_OUT, 0x0000); 150 151 152 /* Disable the power to the USB hub, drive GPIO1 low */ 153 REG_WRITE32(gpio1_addr + GPIO1_OE, REG_READ32(gpio1_addr + 154 GPIO1_OE) & ~(1UL << 1)); 155 REG_WRITE32(gpio1_addr + GPIO1_CLEARDATAOUT, (1UL << 1)); 156 REG_WRITE16(scm_addr + CONTROL_CORE_PAD1_KPD_COL2, 0x0003); 157 158 159 /* Reset the USB PHY and Hub using GPIO_62 */ 160 REG_WRITE32(gpio2_addr + GPIO2_OE, 161 REG_READ32(gpio2_addr + GPIO2_OE) & ~(1UL << 30)); 162 REG_WRITE32(gpio2_addr + GPIO2_CLEARDATAOUT, (1UL << 30)); 163 REG_WRITE16(scm_addr + CONTROL_CORE_PAD0_GPMC_WAIT1, 0x0003); 164 DELAY(10); 165 REG_WRITE32(gpio2_addr + GPIO2_SETDATAOUT, (1UL << 30)); 166 167 168 /* Enable power to the hub (GPIO_1) */ 169 REG_WRITE32(gpio1_addr + GPIO1_SETDATAOUT, (1UL << 1)); 170 bus_space_unmap(fdtbus_bs_tag, scrm_addr, OMAP44XX_SCRM_SIZE); 171 bus_space_unmap(fdtbus_bs_tag, gpio1_addr, OMAP44XX_GPIO1_SIZE); 172 bus_space_unmap(fdtbus_bs_tag, gpio2_addr, OMAP44XX_GPIO2_SIZE); 173 bus_space_unmap(fdtbus_bs_tag, scm_addr, OMAP44XX_SCM_PADCONF_SIZE); 174 } 175