aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTomasz Figa <t.figa@samsung.com>2013-05-16 05:57:08 -0400
committerFelipe Balbi <balbi@ti.com>2013-05-28 13:06:39 -0400
commit0aa823a2ca02cd21c587713e8195a2ffb8bd7872 (patch)
tree74f6e7bdbc4a60f899d0bb504593fe1dab7cc8a3 /drivers
parent87331b069761a292c7d832fc3bb34cde56418982 (diff)
usb: phy: samsung: Consolidate reference clock rate handling
This patch cleans up handling of reference clock rate in Samsung USB PHY drivers. It is mostly a cosmetic change but improves error handling in case of failing to get reference clock or invalid clock rate. Signed-off-by: Tomasz Figa <t.figa@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/phy/phy-samsung-usb.c114
-rw-r--r--drivers/usb/phy/phy-samsung-usb.h7
-rw-r--r--drivers/usb/phy/phy-samsung-usb2.c8
-rw-r--r--drivers/usb/phy/phy-samsung-usb3.c6
4 files changed, 86 insertions, 49 deletions
diff --git a/drivers/usb/phy/phy-samsung-usb.c b/drivers/usb/phy/phy-samsung-usb.c
index 62cdb7e13d97..c40ea321ae46 100644
--- a/drivers/usb/phy/phy-samsung-usb.c
+++ b/drivers/usb/phy/phy-samsung-usb.c
@@ -162,13 +162,76 @@ int samsung_usbphy_set_type(struct usb_phy *phy,
162} 162}
163EXPORT_SYMBOL_GPL(samsung_usbphy_set_type); 163EXPORT_SYMBOL_GPL(samsung_usbphy_set_type);
164 164
165int samsung_usbphy_rate_to_clksel_64xx(struct samsung_usbphy *sphy,
166 unsigned long rate)
167{
168 unsigned int clksel;
169
170 switch (rate) {
171 case 12 * MHZ:
172 clksel = PHYCLK_CLKSEL_12M;
173 break;
174 case 24 * MHZ:
175 clksel = PHYCLK_CLKSEL_24M;
176 break;
177 case 48 * MHZ:
178 clksel = PHYCLK_CLKSEL_48M;
179 break;
180 default:
181 dev_err(sphy->dev,
182 "Invalid reference clock frequency: %lu\n", rate);
183 return -EINVAL;
184 }
185
186 return clksel;
187}
188EXPORT_SYMBOL_GPL(samsung_usbphy_rate_to_clksel_64xx);
189
190int samsung_usbphy_rate_to_clksel_4x12(struct samsung_usbphy *sphy,
191 unsigned long rate)
192{
193 unsigned int clksel;
194
195 switch (rate) {
196 case 9600 * KHZ:
197 clksel = FSEL_CLKSEL_9600K;
198 break;
199 case 10 * MHZ:
200 clksel = FSEL_CLKSEL_10M;
201 break;
202 case 12 * MHZ:
203 clksel = FSEL_CLKSEL_12M;
204 break;
205 case 19200 * KHZ:
206 clksel = FSEL_CLKSEL_19200K;
207 break;
208 case 20 * MHZ:
209 clksel = FSEL_CLKSEL_20M;
210 break;
211 case 24 * MHZ:
212 clksel = FSEL_CLKSEL_24M;
213 break;
214 case 50 * MHZ:
215 clksel = FSEL_CLKSEL_50M;
216 break;
217 default:
218 dev_err(sphy->dev,
219 "Invalid reference clock frequency: %lu\n", rate);
220 return -EINVAL;
221 }
222
223 return clksel;
224}
225EXPORT_SYMBOL_GPL(samsung_usbphy_rate_to_clksel_4x12);
226
165/* 227/*
166 * Returns reference clock frequency selection value 228 * Returns reference clock frequency selection value
167 */ 229 */
168int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy) 230int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
169{ 231{
170 struct clk *ref_clk; 232 struct clk *ref_clk;
171 int refclk_freq = 0; 233 unsigned long rate;
234 int refclk_freq;
172 235
173 /* 236 /*
174 * In exynos5250 USB host and device PHY use 237 * In exynos5250 USB host and device PHY use
@@ -183,52 +246,9 @@ int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
183 return PTR_ERR(ref_clk); 246 return PTR_ERR(ref_clk);
184 } 247 }
185 248
186 if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) { 249 rate = clk_get_rate(ref_clk);
187 /* set clock frequency for PLL */ 250 refclk_freq = sphy->drv_data->rate_to_clksel(sphy, rate);
188 switch (clk_get_rate(ref_clk)) { 251
189 case 9600 * KHZ:
190 refclk_freq = FSEL_CLKSEL_9600K;
191 break;
192 case 10 * MHZ:
193 refclk_freq = FSEL_CLKSEL_10M;
194 break;
195 case 12 * MHZ:
196 refclk_freq = FSEL_CLKSEL_12M;
197 break;
198 case 19200 * KHZ:
199 refclk_freq = FSEL_CLKSEL_19200K;
200 break;
201 case 20 * MHZ:
202 refclk_freq = FSEL_CLKSEL_20M;
203 break;
204 case 50 * MHZ:
205 refclk_freq = FSEL_CLKSEL_50M;
206 break;
207 case 24 * MHZ:
208 default:
209 /* default reference clock */
210 refclk_freq = FSEL_CLKSEL_24M;
211 break;
212 }
213 } else {
214 switch (clk_get_rate(ref_clk)) {
215 case 12 * MHZ:
216 refclk_freq = PHYCLK_CLKSEL_12M;
217 break;
218 case 24 * MHZ:
219 refclk_freq = PHYCLK_CLKSEL_24M;
220 break;
221 case 48 * MHZ:
222 refclk_freq = PHYCLK_CLKSEL_48M;
223 break;
224 default:
225 if (sphy->drv_data->cpu_type == TYPE_S3C64XX)
226 refclk_freq = PHYCLK_CLKSEL_48M;
227 else
228 refclk_freq = PHYCLK_CLKSEL_24M;
229 break;
230 }
231 }
232 clk_put(ref_clk); 252 clk_put(ref_clk);
233 253
234 return refclk_freq; 254 return refclk_freq;
diff --git a/drivers/usb/phy/phy-samsung-usb.h b/drivers/usb/phy/phy-samsung-usb.h
index 70a9cae5e37f..0336f6b02bc4 100644
--- a/drivers/usb/phy/phy-samsung-usb.h
+++ b/drivers/usb/phy/phy-samsung-usb.h
@@ -244,6 +244,8 @@ enum samsung_cpu_type {
244 TYPE_EXYNOS5250, 244 TYPE_EXYNOS5250,
245}; 245};
246 246
247struct samsung_usbphy;
248
247/* 249/*
248 * struct samsung_usbphy_drvdata - driver data for various SoC variants 250 * struct samsung_usbphy_drvdata - driver data for various SoC variants
249 * @cpu_type: machine identifier 251 * @cpu_type: machine identifier
@@ -268,6 +270,7 @@ struct samsung_usbphy_drvdata {
268 int hostphy_en_mask; 270 int hostphy_en_mask;
269 u32 devphy_reg_offset; 271 u32 devphy_reg_offset;
270 u32 hostphy_reg_offset; 272 u32 hostphy_reg_offset;
273 int (*rate_to_clksel)(struct samsung_usbphy *, unsigned long);
271}; 274};
272 275
273/* 276/*
@@ -325,3 +328,7 @@ extern void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy);
325extern int samsung_usbphy_set_type(struct usb_phy *phy, 328extern int samsung_usbphy_set_type(struct usb_phy *phy,
326 enum samsung_usb_phy_type phy_type); 329 enum samsung_usb_phy_type phy_type);
327extern int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy); 330extern int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy);
331extern int samsung_usbphy_rate_to_clksel_64xx(struct samsung_usbphy *sphy,
332 unsigned long rate);
333extern int samsung_usbphy_rate_to_clksel_4x12(struct samsung_usbphy *sphy,
334 unsigned long rate);
diff --git a/drivers/usb/phy/phy-samsung-usb2.c b/drivers/usb/phy/phy-samsung-usb2.c
index 9d5e273abcc7..be6031d50a6d 100644
--- a/drivers/usb/phy/phy-samsung-usb2.c
+++ b/drivers/usb/phy/phy-samsung-usb2.c
@@ -408,7 +408,10 @@ static int samsung_usb2phy_probe(struct platform_device *pdev)
408 sphy->phy.label = "samsung-usb2phy"; 408 sphy->phy.label = "samsung-usb2phy";
409 sphy->phy.init = samsung_usb2phy_init; 409 sphy->phy.init = samsung_usb2phy_init;
410 sphy->phy.shutdown = samsung_usb2phy_shutdown; 410 sphy->phy.shutdown = samsung_usb2phy_shutdown;
411 sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy); 411
412 sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy);
413 if (sphy->ref_clk_freq < 0)
414 return -EINVAL;
412 415
413 sphy->phy.otg = otg; 416 sphy->phy.otg = otg;
414 sphy->phy.otg->phy = &sphy->phy; 417 sphy->phy.otg->phy = &sphy->phy;
@@ -438,18 +441,21 @@ static int samsung_usb2phy_remove(struct platform_device *pdev)
438static const struct samsung_usbphy_drvdata usb2phy_s3c64xx = { 441static const struct samsung_usbphy_drvdata usb2phy_s3c64xx = {
439 .cpu_type = TYPE_S3C64XX, 442 .cpu_type = TYPE_S3C64XX,
440 .devphy_en_mask = S3C64XX_USBPHY_ENABLE, 443 .devphy_en_mask = S3C64XX_USBPHY_ENABLE,
444 .rate_to_clksel = samsung_usbphy_rate_to_clksel_64xx,
441}; 445};
442 446
443static const struct samsung_usbphy_drvdata usb2phy_exynos4 = { 447static const struct samsung_usbphy_drvdata usb2phy_exynos4 = {
444 .cpu_type = TYPE_EXYNOS4210, 448 .cpu_type = TYPE_EXYNOS4210,
445 .devphy_en_mask = EXYNOS_USBPHY_ENABLE, 449 .devphy_en_mask = EXYNOS_USBPHY_ENABLE,
446 .hostphy_en_mask = EXYNOS_USBPHY_ENABLE, 450 .hostphy_en_mask = EXYNOS_USBPHY_ENABLE,
451 .rate_to_clksel = samsung_usbphy_rate_to_clksel_64xx,
447}; 452};
448 453
449static struct samsung_usbphy_drvdata usb2phy_exynos5 = { 454static struct samsung_usbphy_drvdata usb2phy_exynos5 = {
450 .cpu_type = TYPE_EXYNOS5250, 455 .cpu_type = TYPE_EXYNOS5250,
451 .hostphy_en_mask = EXYNOS_USBPHY_ENABLE, 456 .hostphy_en_mask = EXYNOS_USBPHY_ENABLE,
452 .hostphy_reg_offset = EXYNOS_USBHOST_PHY_CTRL_OFFSET, 457 .hostphy_reg_offset = EXYNOS_USBHOST_PHY_CTRL_OFFSET,
458 .rate_to_clksel = samsung_usbphy_rate_to_clksel_4x12,
453}; 459};
454 460
455#ifdef CONFIG_OF 461#ifdef CONFIG_OF
diff --git a/drivers/usb/phy/phy-samsung-usb3.c b/drivers/usb/phy/phy-samsung-usb3.c
index 5a9efcbcb532..ec44b35fb24a 100644
--- a/drivers/usb/phy/phy-samsung-usb3.c
+++ b/drivers/usb/phy/phy-samsung-usb3.c
@@ -274,7 +274,10 @@ static int samsung_usb3phy_probe(struct platform_device *pdev)
274 sphy->phy.init = samsung_usb3phy_init; 274 sphy->phy.init = samsung_usb3phy_init;
275 sphy->phy.shutdown = samsung_usb3phy_shutdown; 275 sphy->phy.shutdown = samsung_usb3phy_shutdown;
276 sphy->drv_data = samsung_usbphy_get_driver_data(pdev); 276 sphy->drv_data = samsung_usbphy_get_driver_data(pdev);
277 sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy); 277
278 sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy);
279 if (sphy->ref_clk_freq < 0)
280 return -EINVAL;
278 281
279 spin_lock_init(&sphy->lock); 282 spin_lock_init(&sphy->lock);
280 283
@@ -300,6 +303,7 @@ static int samsung_usb3phy_remove(struct platform_device *pdev)
300static struct samsung_usbphy_drvdata usb3phy_exynos5 = { 303static struct samsung_usbphy_drvdata usb3phy_exynos5 = {
301 .cpu_type = TYPE_EXYNOS5250, 304 .cpu_type = TYPE_EXYNOS5250,
302 .devphy_en_mask = EXYNOS_USBPHY_ENABLE, 305 .devphy_en_mask = EXYNOS_USBPHY_ENABLE,
306 .rate_to_clksel = samsung_usbphy_rate_to_clksel_4x12,
303}; 307};
304 308
305#ifdef CONFIG_OF 309#ifdef CONFIG_OF