Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+67 −47
Original line number Diff line number Diff line
@@ -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;
+7 −0
Original line number Diff line number Diff line
@@ -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);
+7 −1
Original line number Diff line number Diff line
@@ -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
+5 −1
Original line number Diff line number Diff line
@@ -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