1 /** 2 * ti_usb_phy.c - USB3 and USB3 PHY programming for dwc3 3 * 4 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com 5 * 6 * Author: Kishon Vijay Abraham I <kishon@ti.com> 7 * 8 * Taken from Linux Kernel v3.16 (drivers/phy/phy-ti-pipe3.c and 9 * drivers/phy/phy-omap-usb2.c) and ported to uboot. 10 * 11 * "commit 56042e : phy: ti-pipe3: Fix suspend/resume and module reload" for 12 * phy-ti-pipe3.c 13 * 14 * "commit eb82a3 : phy: omap-usb2: Balance pm_runtime_enable() on probe failure 15 * and remove" for phy-omap-usb2.c 16 * 17 * SPDX-License-Identifier: GPL-2.0+ 18 */ 19 20 #include <common.h> 21 #include <malloc.h> 22 #include <ti-usb-phy-uboot.h> 23 #include <usb/lin_gadget_compat.h> 24 #include <linux/ioport.h> 25 #include <asm/io.h> 26 #include <asm/arch/sys_proto.h> 27 #include <dm.h> 28 29 #include "linux-compat.h" 30 31 #define PLL_STATUS 0x00000004 32 #define PLL_GO 0x00000008 33 #define PLL_CONFIGURATION1 0x0000000C 34 #define PLL_CONFIGURATION2 0x00000010 35 #define PLL_CONFIGURATION3 0x00000014 36 #define PLL_CONFIGURATION4 0x00000020 37 38 #define PLL_REGM_MASK 0x001FFE00 39 #define PLL_REGM_SHIFT 0x9 40 #define PLL_REGM_F_MASK 0x0003FFFF 41 #define PLL_REGM_F_SHIFT 0x0 42 #define PLL_REGN_MASK 0x000001FE 43 #define PLL_REGN_SHIFT 0x1 44 #define PLL_SELFREQDCO_MASK 0x0000000E 45 #define PLL_SELFREQDCO_SHIFT 0x1 46 #define PLL_SD_MASK 0x0003FC00 47 #define PLL_SD_SHIFT 10 48 #define SET_PLL_GO 0x1 49 #define PLL_LDOPWDN BIT(15) 50 #define PLL_TICOPWDN BIT(16) 51 #define PLL_LOCK 0x2 52 #define PLL_IDLE 0x1 53 54 #define OMAP_CTRL_DEV_PHY_PD BIT(0) 55 #define OMAP_CTRL_USB3_PHY_PWRCTL_CLK_CMD_MASK 0x003FC000 56 #define OMAP_CTRL_USB3_PHY_PWRCTL_CLK_CMD_SHIFT 0xE 57 58 #define OMAP_CTRL_USB3_PHY_PWRCTL_CLK_FREQ_MASK 0xFFC00000 59 #define OMAP_CTRL_USB3_PHY_PWRCTL_CLK_FREQ_SHIFT 0x16 60 61 #define OMAP_CTRL_USB3_PHY_TX_RX_POWERON 0x3 62 #define OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF 0x0 63 64 #define OMAP_CTRL_USB2_PHY_PD BIT(28) 65 66 #define AM437X_CTRL_USB2_PHY_PD BIT(0) 67 #define AM437X_CTRL_USB2_OTG_PD BIT(1) 68 #define AM437X_CTRL_USB2_OTGVDET_EN BIT(19) 69 #define AM437X_CTRL_USB2_OTGSESSEND_EN BIT(20) 70 71 static LIST_HEAD(ti_usb_phy_list); 72 typedef unsigned int u32; 73 74 struct usb3_dpll_params { 75 u16 m; 76 u8 n; 77 u8 freq:3; 78 u8 sd; 79 u32 mf; 80 }; 81 82 struct usb3_dpll_map { 83 unsigned long rate; 84 struct usb3_dpll_params params; 85 struct usb3_dpll_map *dpll_map; 86 }; 87 88 struct ti_usb_phy { 89 void __iomem *pll_ctrl_base; 90 void __iomem *usb2_phy_power; 91 void __iomem *usb3_phy_power; 92 struct usb3_dpll_map *dpll_map; 93 struct list_head list; 94 int index; 95 }; 96 97 static struct usb3_dpll_map dpll_map_usb[] = { 98 {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */ 99 {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */ 100 {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */ 101 {20000000, {1000, 7, 4, 10, 0} }, /* 20 MHz */ 102 {26000000, {1250, 12, 4, 20, 0} }, /* 26 MHz */ 103 {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */ 104 { }, /* Terminator */ 105 }; 106 107 static inline unsigned int ti_usb3_readl(void __iomem *base, u32 offset) 108 { 109 return readl(base + offset); 110 } 111 112 static inline void ti_usb3_writel(void __iomem *base, u32 offset, u32 value) 113 { 114 writel(value, base + offset); 115 } 116 117 #ifndef CONFIG_AM43XX 118 static struct usb3_dpll_params *ti_usb3_get_dpll_params(struct ti_usb_phy *phy) 119 { 120 unsigned long rate; 121 struct usb3_dpll_map *dpll_map = phy->dpll_map; 122 123 rate = get_sys_clk_freq(); 124 125 for (; dpll_map->rate; dpll_map++) { 126 if (rate == dpll_map->rate) 127 return &dpll_map->params; 128 } 129 130 dev_err(phy->dev, "No DPLL configuration for %lu Hz SYS CLK\n", rate); 131 132 return NULL; 133 } 134 135 static int ti_usb3_dpll_wait_lock(struct ti_usb_phy *phy) 136 { 137 u32 val; 138 do { 139 val = ti_usb3_readl(phy->pll_ctrl_base, PLL_STATUS); 140 if (val & PLL_LOCK) 141 break; 142 } while (1); 143 144 return 0; 145 } 146 147 static int ti_usb3_dpll_program(struct ti_usb_phy *phy) 148 { 149 u32 val; 150 struct usb3_dpll_params *dpll_params; 151 152 if (!phy->pll_ctrl_base) 153 return -EINVAL; 154 155 dpll_params = ti_usb3_get_dpll_params(phy); 156 if (!dpll_params) 157 return -EINVAL; 158 159 val = ti_usb3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); 160 val &= ~PLL_REGN_MASK; 161 val |= dpll_params->n << PLL_REGN_SHIFT; 162 ti_usb3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); 163 164 val = ti_usb3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); 165 val &= ~PLL_SELFREQDCO_MASK; 166 val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT; 167 ti_usb3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); 168 169 val = ti_usb3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); 170 val &= ~PLL_REGM_MASK; 171 val |= dpll_params->m << PLL_REGM_SHIFT; 172 ti_usb3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); 173 174 val = ti_usb3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); 175 val &= ~PLL_REGM_F_MASK; 176 val |= dpll_params->mf << PLL_REGM_F_SHIFT; 177 ti_usb3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); 178 179 val = ti_usb3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); 180 val &= ~PLL_SD_MASK; 181 val |= dpll_params->sd << PLL_SD_SHIFT; 182 ti_usb3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); 183 184 ti_usb3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO); 185 186 return ti_usb3_dpll_wait_lock(phy); 187 } 188 #endif 189 190 void ti_usb2_phy_power(struct ti_usb_phy *phy, int on) 191 { 192 u32 val; 193 194 val = readl(phy->usb2_phy_power); 195 196 if (on) { 197 #if defined(CONFIG_DRA7XX) 198 if (phy->index == 1) 199 val &= ~OMAP_CTRL_USB2_PHY_PD; 200 else 201 val &= ~OMAP_CTRL_DEV_PHY_PD; 202 #elif defined(CONFIG_AM43XX) 203 val &= ~(AM437X_CTRL_USB2_PHY_PD | 204 AM437X_CTRL_USB2_OTG_PD); 205 val |= (AM437X_CTRL_USB2_OTGVDET_EN | 206 AM437X_CTRL_USB2_OTGSESSEND_EN); 207 #endif 208 } else { 209 #if defined(CONFIG_DRA7XX) 210 if (phy->index == 1) 211 val |= OMAP_CTRL_USB2_PHY_PD; 212 else 213 val |= OMAP_CTRL_DEV_PHY_PD; 214 215 #elif defined(CONFIG_AM43XX) 216 val &= ~(AM437X_CTRL_USB2_OTGVDET_EN | 217 AM437X_CTRL_USB2_OTGSESSEND_EN); 218 val |= (AM437X_CTRL_USB2_PHY_PD | 219 AM437X_CTRL_USB2_OTG_PD); 220 #endif 221 } 222 writel(val, phy->usb2_phy_power); 223 } 224 225 #ifndef CONFIG_AM43XX 226 void ti_usb3_phy_power(struct ti_usb_phy *phy, int on) 227 { 228 u32 val; 229 u32 rate; 230 rate = get_sys_clk_freq(); 231 rate = rate/1000000; 232 233 if (!phy->usb3_phy_power) 234 return; 235 236 val = readl(phy->usb3_phy_power); 237 if (on) { 238 val &= ~(OMAP_CTRL_USB3_PHY_PWRCTL_CLK_CMD_MASK | 239 OMAP_CTRL_USB3_PHY_PWRCTL_CLK_FREQ_MASK); 240 val |= (OMAP_CTRL_USB3_PHY_TX_RX_POWERON) << 241 OMAP_CTRL_USB3_PHY_PWRCTL_CLK_CMD_SHIFT; 242 val |= rate << 243 OMAP_CTRL_USB3_PHY_PWRCTL_CLK_FREQ_SHIFT; 244 } else { 245 val &= ~OMAP_CTRL_USB3_PHY_PWRCTL_CLK_CMD_MASK; 246 val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF << 247 OMAP_CTRL_USB3_PHY_PWRCTL_CLK_CMD_SHIFT; 248 } 249 writel(val, phy->usb3_phy_power); 250 } 251 #endif 252 253 /** 254 * ti_usb_phy_uboot_init - usb phy uboot initialization code 255 * @dev: struct ti_usb_phy_device containing initialization data 256 * 257 * Entry point for ti usb phy driver. This driver handles initialization 258 * of both usb2 phy and usb3 phy. Pointer to ti_usb_phy_device should be 259 * passed containing base address and other initialization data. 260 * Returns '0' on success and a negative value on failure. 261 * 262 * Generally called from board_usb_init() implemented in board file. 263 */ 264 int ti_usb_phy_uboot_init(struct ti_usb_phy_device *dev) 265 { 266 struct ti_usb_phy *phy; 267 268 phy = devm_kzalloc(NULL, sizeof(*phy), GFP_KERNEL); 269 if (!phy) { 270 dev_err(NULL, "unable to alloc mem for TI USB3 PHY\n"); 271 return -ENOMEM; 272 } 273 274 phy->dpll_map = dpll_map_usb; 275 phy->index = dev->index; 276 phy->pll_ctrl_base = dev->pll_ctrl_base; 277 phy->usb2_phy_power = dev->usb2_phy_power; 278 phy->usb3_phy_power = dev->usb3_phy_power; 279 280 #ifndef CONFIG_AM43XX 281 ti_usb3_dpll_program(phy); 282 ti_usb3_phy_power(phy, 1); 283 #endif 284 ti_usb2_phy_power(phy, 1); 285 mdelay(150); 286 list_add_tail(&phy->list, &ti_usb_phy_list); 287 288 return 0; 289 } 290 291 /** 292 * ti_usb_phy_uboot_exit - usb phy uboot cleanup code 293 * @index: index of this controller 294 * 295 * Performs cleanup of memory allocated in ti_usb_phy_uboot_init. 296 * index of _this_ controller should be passed and should match with 297 * the index passed in ti_usb_phy_device during init. 298 * 299 * Generally called from board file. 300 */ 301 void ti_usb_phy_uboot_exit(int index) 302 { 303 struct ti_usb_phy *phy = NULL; 304 305 list_for_each_entry(phy, &ti_usb_phy_list, list) { 306 if (phy->index != index) 307 continue; 308 309 ti_usb2_phy_power(phy, 0); 310 #ifndef CONFIG_AM43XX 311 ti_usb3_phy_power(phy, 0); 312 #endif 313 list_del(&phy->list); 314 kfree(phy); 315 break; 316 } 317 } 318