Commit 0aa823a2 authored by Tomasz Figa's avatar Tomasz Figa Committed by Felipe Balbi

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: default avatarTomasz Figa <t.figa@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 87331b06
......@@ -162,73 +162,93 @@ int samsung_usbphy_set_type(struct usb_phy *phy,
}
EXPORT_SYMBOL_GPL(samsung_usbphy_set_type);
/*
* Returns reference clock frequency selection value
*/
int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
int samsung_usbphy_rate_to_clksel_64xx(struct samsung_usbphy *sphy,
unsigned long rate)
{
struct clk *ref_clk;
int refclk_freq = 0;
unsigned int clksel;
/*
* In exynos5250 USB host and device PHY use
* external crystal clock XXTI
*/
if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250)
ref_clk = clk_get(sphy->dev, "ext_xtal");
else
ref_clk = clk_get(sphy->dev, "xusbxti");
if (IS_ERR(ref_clk)) {
dev_err(sphy->dev, "Failed to get reference clock\n");
return PTR_ERR(ref_clk);
switch (rate) {
case 12 * MHZ:
clksel = PHYCLK_CLKSEL_12M;
break;
case 24 * MHZ:
clksel = PHYCLK_CLKSEL_24M;
break;
case 48 * MHZ:
clksel = PHYCLK_CLKSEL_48M;
break;
default:
dev_err(sphy->dev,
"Invalid reference clock frequency: %lu\n", rate);
return -EINVAL;
}
if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) {
/* set clock frequency for PLL */
switch (clk_get_rate(ref_clk)) {
return clksel;
}
EXPORT_SYMBOL_GPL(samsung_usbphy_rate_to_clksel_64xx);
int samsung_usbphy_rate_to_clksel_4x12(struct samsung_usbphy *sphy,
unsigned long rate)
{
unsigned int clksel;
switch (rate) {
case 9600 * KHZ:
refclk_freq = FSEL_CLKSEL_9600K;
clksel = FSEL_CLKSEL_9600K;
break;
case 10 * MHZ:
refclk_freq = FSEL_CLKSEL_10M;
clksel = FSEL_CLKSEL_10M;
break;
case 12 * MHZ:
refclk_freq = FSEL_CLKSEL_12M;
clksel = FSEL_CLKSEL_12M;
break;
case 19200 * KHZ:
refclk_freq = FSEL_CLKSEL_19200K;
clksel = FSEL_CLKSEL_19200K;
break;
case 20 * MHZ:
refclk_freq = FSEL_CLKSEL_20M;
break;
case 50 * MHZ:
refclk_freq = FSEL_CLKSEL_50M;
break;
case 24 * MHZ:
default:
/* default reference clock */
refclk_freq = FSEL_CLKSEL_24M;
break;
}
} else {
switch (clk_get_rate(ref_clk)) {
case 12 * MHZ:
refclk_freq = PHYCLK_CLKSEL_12M;
clksel = FSEL_CLKSEL_20M;
break;
case 24 * MHZ:
refclk_freq = PHYCLK_CLKSEL_24M;
clksel = FSEL_CLKSEL_24M;
break;
case 48 * MHZ:
refclk_freq = PHYCLK_CLKSEL_48M;
case 50 * MHZ:
clksel = FSEL_CLKSEL_50M;
break;
default:
if (sphy->drv_data->cpu_type == TYPE_S3C64XX)
refclk_freq = PHYCLK_CLKSEL_48M;
else
refclk_freq = PHYCLK_CLKSEL_24M;
break;
dev_err(sphy->dev,
"Invalid reference clock frequency: %lu\n", rate);
return -EINVAL;
}
return clksel;
}
EXPORT_SYMBOL_GPL(samsung_usbphy_rate_to_clksel_4x12);
/*
* Returns reference clock frequency selection value
*/
int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
{
struct clk *ref_clk;
unsigned long rate;
int refclk_freq;
/*
* In exynos5250 USB host and device PHY use
* external crystal clock XXTI
*/
if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250)
ref_clk = clk_get(sphy->dev, "ext_xtal");
else
ref_clk = clk_get(sphy->dev, "xusbxti");
if (IS_ERR(ref_clk)) {
dev_err(sphy->dev, "Failed to get reference clock\n");
return PTR_ERR(ref_clk);
}
rate = clk_get_rate(ref_clk);
refclk_freq = sphy->drv_data->rate_to_clksel(sphy, rate);
clk_put(ref_clk);
return refclk_freq;
......
......@@ -244,6 +244,8 @@ enum samsung_cpu_type {
TYPE_EXYNOS5250,
};
struct samsung_usbphy;
/*
* struct samsung_usbphy_drvdata - driver data for various SoC variants
* @cpu_type: machine identifier
......@@ -268,6 +270,7 @@ struct samsung_usbphy_drvdata {
int hostphy_en_mask;
u32 devphy_reg_offset;
u32 hostphy_reg_offset;
int (*rate_to_clksel)(struct samsung_usbphy *, unsigned long);
};
/*
......@@ -325,3 +328,7 @@ extern void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy);
extern int samsung_usbphy_set_type(struct usb_phy *phy,
enum samsung_usb_phy_type phy_type);
extern int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy);
extern int samsung_usbphy_rate_to_clksel_64xx(struct samsung_usbphy *sphy,
unsigned long rate);
extern int samsung_usbphy_rate_to_clksel_4x12(struct samsung_usbphy *sphy,
unsigned long rate);
......@@ -408,7 +408,10 @@ static int samsung_usb2phy_probe(struct platform_device *pdev)
sphy->phy.label = "samsung-usb2phy";
sphy->phy.init = samsung_usb2phy_init;
sphy->phy.shutdown = samsung_usb2phy_shutdown;
sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy);
if (sphy->ref_clk_freq < 0)
return -EINVAL;
sphy->phy.otg = otg;
sphy->phy.otg->phy = &sphy->phy;
......@@ -438,18 +441,21 @@ static int samsung_usb2phy_remove(struct platform_device *pdev)
static const struct samsung_usbphy_drvdata usb2phy_s3c64xx = {
.cpu_type = TYPE_S3C64XX,
.devphy_en_mask = S3C64XX_USBPHY_ENABLE,
.rate_to_clksel = samsung_usbphy_rate_to_clksel_64xx,
};
static const struct samsung_usbphy_drvdata usb2phy_exynos4 = {
.cpu_type = TYPE_EXYNOS4210,
.devphy_en_mask = EXYNOS_USBPHY_ENABLE,
.hostphy_en_mask = EXYNOS_USBPHY_ENABLE,
.rate_to_clksel = samsung_usbphy_rate_to_clksel_64xx,
};
static struct samsung_usbphy_drvdata usb2phy_exynos5 = {
.cpu_type = TYPE_EXYNOS5250,
.hostphy_en_mask = EXYNOS_USBPHY_ENABLE,
.hostphy_reg_offset = EXYNOS_USBHOST_PHY_CTRL_OFFSET,
.rate_to_clksel = samsung_usbphy_rate_to_clksel_4x12,
};
#ifdef CONFIG_OF
......
......@@ -274,7 +274,10 @@ static int samsung_usb3phy_probe(struct platform_device *pdev)
sphy->phy.init = samsung_usb3phy_init;
sphy->phy.shutdown = samsung_usb3phy_shutdown;
sphy->drv_data = samsung_usbphy_get_driver_data(pdev);
sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy);
if (sphy->ref_clk_freq < 0)
return -EINVAL;
spin_lock_init(&sphy->lock);
......@@ -300,6 +303,7 @@ static int samsung_usb3phy_remove(struct platform_device *pdev)
static struct samsung_usbphy_drvdata usb3phy_exynos5 = {
.cpu_type = TYPE_EXYNOS5250,
.devphy_en_mask = EXYNOS_USBPHY_ENABLE,
.rate_to_clksel = samsung_usbphy_rate_to_clksel_4x12,
};
#ifdef CONFIG_OF
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment