aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy/phy-omap-usb3.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/phy/phy-omap-usb3.c')
-rw-r--r--drivers/usb/phy/phy-omap-usb3.c87
1 files changed, 38 insertions, 49 deletions
diff --git a/drivers/usb/phy/phy-omap-usb3.c b/drivers/usb/phy/phy-omap-usb3.c
index a2fb30bbb971..fc15694d3031 100644
--- a/drivers/usb/phy/phy-omap-usb3.c
+++ b/drivers/usb/phy/phy-omap-usb3.c
@@ -27,7 +27,6 @@
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/usb/omap_control_usb.h> 28#include <linux/usb/omap_control_usb.h>
29 29
30#define NUM_SYS_CLKS 6
31#define PLL_STATUS 0x00000004 30#define PLL_STATUS 0x00000004
32#define PLL_GO 0x00000008 31#define PLL_GO 0x00000008
33#define PLL_CONFIGURATION1 0x0000000C 32#define PLL_CONFIGURATION1 0x0000000C
@@ -57,26 +56,32 @@
57 */ 56 */
58# define PLL_IDLE_TIME 100; 57# define PLL_IDLE_TIME 100;
59 58
60enum sys_clk_rate { 59struct usb_dpll_map {
61 CLK_RATE_UNDEFINED = -1, 60 unsigned long rate;
62 CLK_RATE_12MHZ, 61 struct usb_dpll_params params;
63 CLK_RATE_16MHZ,
64 CLK_RATE_19MHZ,
65 CLK_RATE_20MHZ,
66 CLK_RATE_26MHZ,
67 CLK_RATE_38MHZ
68}; 62};
69 63
70static struct usb_dpll_params omap_usb3_dpll_params[NUM_SYS_CLKS] = { 64static struct usb_dpll_map dpll_map[] = {
71 {1250, 5, 4, 20, 0}, /* 12 MHz */ 65 {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */
72 {3125, 20, 4, 20, 0}, /* 16.8 MHz */ 66 {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */
73 {1172, 8, 4, 20, 65537}, /* 19.2 MHz */ 67 {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */
74 {1000, 7, 4, 10, 0}, /* 20 MHz */ 68 {20000000, {1000, 7, 4, 10, 0} }, /* 20 MHz */
75 {1250, 12, 4, 20, 0}, /* 26 MHz */ 69 {26000000, {1250, 12, 4, 20, 0} }, /* 26 MHz */
76 {3125, 47, 4, 20, 92843}, /* 38.4 MHz */ 70 {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */
77
78}; 71};
79 72
73static struct usb_dpll_params *omap_usb3_get_dpll_params(unsigned long rate)
74{
75 int i;
76
77 for (i = 0; i < ARRAY_SIZE(dpll_map); i++) {
78 if (rate == dpll_map[i].rate)
79 return &dpll_map[i].params;
80 }
81
82 return 0;
83}
84
80static int omap_usb3_suspend(struct usb_phy *x, int suspend) 85static int omap_usb3_suspend(struct usb_phy *x, int suspend)
81{ 86{
82 struct omap_usb *phy = phy_to_omapusb(x); 87 struct omap_usb *phy = phy_to_omapusb(x);
@@ -116,26 +121,6 @@ static int omap_usb3_suspend(struct usb_phy *x, int suspend)
116 return 0; 121 return 0;
117} 122}
118 123
119static inline enum sys_clk_rate __get_sys_clk_index(unsigned long rate)
120{
121 switch (rate) {
122 case 12000000:
123 return CLK_RATE_12MHZ;
124 case 16800000:
125 return CLK_RATE_16MHZ;
126 case 19200000:
127 return CLK_RATE_19MHZ;
128 case 20000000:
129 return CLK_RATE_20MHZ;
130 case 26000000:
131 return CLK_RATE_26MHZ;
132 case 38400000:
133 return CLK_RATE_38MHZ;
134 default:
135 return CLK_RATE_UNDEFINED;
136 }
137}
138
139static void omap_usb_dpll_relock(struct omap_usb *phy) 124static void omap_usb_dpll_relock(struct omap_usb *phy)
140{ 125{
141 u32 val; 126 u32 val;
@@ -155,39 +140,39 @@ static int omap_usb_dpll_lock(struct omap_usb *phy)
155{ 140{
156 u32 val; 141 u32 val;
157 unsigned long rate; 142 unsigned long rate;
158 enum sys_clk_rate clk_index; 143 struct usb_dpll_params *dpll_params;
159
160 rate = clk_get_rate(phy->sys_clk);
161 clk_index = __get_sys_clk_index(rate);
162 144
163 if (clk_index == CLK_RATE_UNDEFINED) { 145 rate = clk_get_rate(phy->sys_clk);
164 pr_err("dpll cannot be locked for sys clk freq:%luHz\n", rate); 146 dpll_params = omap_usb3_get_dpll_params(rate);
147 if (!dpll_params) {
148 dev_err(phy->dev,
149 "No DPLL configuration for %lu Hz SYS CLK\n", rate);
165 return -EINVAL; 150 return -EINVAL;
166 } 151 }
167 152
168 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); 153 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
169 val &= ~PLL_REGN_MASK; 154 val &= ~PLL_REGN_MASK;
170 val |= omap_usb3_dpll_params[clk_index].n << PLL_REGN_SHIFT; 155 val |= dpll_params->n << PLL_REGN_SHIFT;
171 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); 156 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
172 157
173 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); 158 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
174 val &= ~PLL_SELFREQDCO_MASK; 159 val &= ~PLL_SELFREQDCO_MASK;
175 val |= omap_usb3_dpll_params[clk_index].freq << PLL_SELFREQDCO_SHIFT; 160 val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT;
176 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); 161 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
177 162
178 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); 163 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
179 val &= ~PLL_REGM_MASK; 164 val &= ~PLL_REGM_MASK;
180 val |= omap_usb3_dpll_params[clk_index].m << PLL_REGM_SHIFT; 165 val |= dpll_params->m << PLL_REGM_SHIFT;
181 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); 166 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
182 167
183 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); 168 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
184 val &= ~PLL_REGM_F_MASK; 169 val &= ~PLL_REGM_F_MASK;
185 val |= omap_usb3_dpll_params[clk_index].mf << PLL_REGM_F_SHIFT; 170 val |= dpll_params->mf << PLL_REGM_F_SHIFT;
186 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); 171 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
187 172
188 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); 173 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
189 val &= ~PLL_SD_MASK; 174 val &= ~PLL_SD_MASK;
190 val |= omap_usb3_dpll_params[clk_index].sd << PLL_SD_SHIFT; 175 val |= dpll_params->sd << PLL_SD_SHIFT;
191 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); 176 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
192 177
193 omap_usb_dpll_relock(phy); 178 omap_usb_dpll_relock(phy);
@@ -198,8 +183,12 @@ static int omap_usb_dpll_lock(struct omap_usb *phy)
198static int omap_usb3_init(struct usb_phy *x) 183static int omap_usb3_init(struct usb_phy *x)
199{ 184{
200 struct omap_usb *phy = phy_to_omapusb(x); 185 struct omap_usb *phy = phy_to_omapusb(x);
186 int ret;
187
188 ret = omap_usb_dpll_lock(phy);
189 if (ret)
190 return ret;
201 191
202 omap_usb_dpll_lock(phy);
203 omap_control_usb3_phy_power(phy->control_dev, 1); 192 omap_control_usb3_phy_power(phy->control_dev, 1);
204 193
205 return 0; 194 return 0;