diff options
| author | Tomasz Figa <t.figa@samsung.com> | 2013-05-16 05:57:08 -0400 |
|---|---|---|
| committer | Felipe Balbi <balbi@ti.com> | 2013-05-28 13:06:39 -0400 |
| commit | 0aa823a2ca02cd21c587713e8195a2ffb8bd7872 (patch) | |
| tree | 74f6e7bdbc4a60f899d0bb504593fe1dab7cc8a3 /drivers/usb/phy | |
| parent | 87331b069761a292c7d832fc3bb34cde56418982 (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/usb/phy')
| -rw-r--r-- | drivers/usb/phy/phy-samsung-usb.c | 114 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-samsung-usb.h | 7 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-samsung-usb2.c | 8 | ||||
| -rw-r--r-- | drivers/usb/phy/phy-samsung-usb3.c | 6 |
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 | } |
| 163 | EXPORT_SYMBOL_GPL(samsung_usbphy_set_type); | 163 | EXPORT_SYMBOL_GPL(samsung_usbphy_set_type); |
| 164 | 164 | ||
| 165 | int 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 | } | ||
| 188 | EXPORT_SYMBOL_GPL(samsung_usbphy_rate_to_clksel_64xx); | ||
| 189 | |||
| 190 | int 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 | } | ||
| 225 | EXPORT_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 | */ |
| 168 | int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy) | 230 | int 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 | ||
| 247 | struct 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); | |||
| 325 | extern int samsung_usbphy_set_type(struct usb_phy *phy, | 328 | extern 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); |
| 327 | extern int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy); | 330 | extern int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy); |
| 331 | extern int samsung_usbphy_rate_to_clksel_64xx(struct samsung_usbphy *sphy, | ||
| 332 | unsigned long rate); | ||
| 333 | extern 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) | |||
| 438 | static const struct samsung_usbphy_drvdata usb2phy_s3c64xx = { | 441 | static 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 | ||
| 443 | static const struct samsung_usbphy_drvdata usb2phy_exynos4 = { | 447 | static 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 | ||
| 449 | static struct samsung_usbphy_drvdata usb2phy_exynos5 = { | 454 | static 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) | |||
| 300 | static struct samsung_usbphy_drvdata usb3phy_exynos5 = { | 303 | static 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 |
