6b0166a1e0603388c4bdce369d7b1b1ce44f05d9
[oweals/u-boot.git] / drivers / usb / dwc3 / ti_usb_phy.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /**
3  * ti_usb_phy.c - USB3 and USB3 PHY programming for dwc3
4  *
5  * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
6  *
7  * Author: Kishon Vijay Abraham I <kishon@ti.com>
8  *
9  * Taken from Linux Kernel v3.16 (drivers/phy/phy-ti-pipe3.c and
10  * drivers/phy/phy-omap-usb2.c) and ported to uboot.
11  *
12  * "commit 56042e : phy: ti-pipe3: Fix suspend/resume and module reload" for
13  * phy-ti-pipe3.c
14  *
15  * "commit eb82a3 : phy: omap-usb2: Balance pm_runtime_enable() on probe failure
16  * and remove" for phy-omap-usb2.c
17  */
18
19 #include <common.h>
20 #include <malloc.h>
21 #include <ti-usb-phy-uboot.h>
22 #include <dm/device_compat.h>
23 #include <dm/devres.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 }