RE: [PATCH v7 07/10] phy: samsung-ufs: add UFS PHY driver for samsung SoC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Kishon,
Thanks for review.

> -----Original Message-----
> From: Kishon Vijay Abraham I <kishon@xxxxxx>
> Sent: 07 May 2020 10:49
> To: Alim Akhtar <alim.akhtar@xxxxxxxxxxx>; robh@xxxxxxxxxx
> Cc: devicetree@xxxxxxxxxxxxxxx; linux-scsi@xxxxxxxxxxxxxxx; krzk@xxxxxxxxxx;
> avri.altman@xxxxxxx; martin.petersen@xxxxxxxxxx;
> kwmad.kim@xxxxxxxxxxx; stanley.chu@xxxxxxxxxxxx;
> cang@xxxxxxxxxxxxxx; linux-samsung-soc@xxxxxxxxxxxxxxx; linux-arm-
> kernel@xxxxxxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; Vinod Koul
> <vkoul@xxxxxxxxxx>
> Subject: Re: [PATCH v7 07/10] phy: samsung-ufs: add UFS PHY driver for
> samsung SoC
> 
.
.
.
> Okay, here you are using a state machine for the PHY configuration because of
> the way the PHY is integrated with the UFS. Would be nice to have the state
> machine documented somewhere. I only have the PHY patch in my inbox.
Ok, will document in the driver file as well as in the header file.

> > +
> > +	if (ufs_phy->ufs_phy_state == CFG_POST_PWR_HS)
> > +		err = samsung_ufs_phy_wait_for_lock_acq(phy);
> > +out:
> > +	return err;
> > +}
> > +
> > +static int samsung_ufs_phy_symbol_clk_init(struct samsung_ufs_phy
> > +*phy) {
> > +	struct clk *clk;
> > +	int ret = 0;
> > +
> > +	clk = devm_clk_get(phy->dev, "tx0_symbol_clk");
> 
> There is no "exit" callback in phy_ops which means if there are multiple phy_init
> calls, this clock will not be freed. This could be moved to "probe" IMO.

Ok, will add exit callback.

> > +	if (IS_ERR(clk)) {
> > +		dev_err(phy->dev, "failed to get tx0_symbol_clk clock\n");
> > +		goto out;
> > +	} else {
> 
> "else" here and below is not required. Something like below
> 
Ack
> 	clk = devm_clk_get(phy->dev, "tx0_symbol_clk");
> 	if (IS_ERR(clk)) {
> 		dev_err(phy->dev, "failed to get tx0_symbol_clk clock\n");
> 		goto out;
> 	}
> 	phy->tx0_symbol_clk = clk;
> 
> > +		phy->tx0_symbol_clk = clk;
> > +	}
> > +
> > +	clk = devm_clk_get(phy->dev, "rx0_symbol_clk");
> > +	if (IS_ERR(clk)) {
> > +		dev_err(phy->dev, "failed to get rx0_symbol_clk clock\n");
> > +		goto out;
> > +	} else {
> > +		phy->rx0_symbol_clk = clk;
> > +	}
> > +
> > +	clk = devm_clk_get(phy->dev, "rx1_symbol_clk");
> > +	if (IS_ERR(clk)) {
> > +		dev_err(phy->dev, "failed to get rx1_symbol_clk clock\n");
> > +		goto out;
> > +	} else {
> > +		phy->rx1_symbol_clk = clk;
> > +	}
> > +
> > +	ret = clk_prepare_enable(phy->tx0_symbol_clk);
> > +	if (ret) {
> > +		dev_err(phy->dev, "%s: tx0_symbol_clk enable failed %d\n",
> > +				__func__, ret);
> > +		goto out;
> > +	}
> > +	ret = clk_prepare_enable(phy->rx0_symbol_clk);
> > +	if (ret) {
> > +		dev_err(phy->dev, "%s: rx0_symbol_clk enable failed %d\n",
> > +				__func__, ret);
> > +		goto out;
> > +	}
> > +	ret = clk_prepare_enable(phy->rx1_symbol_clk);
> > +	if (ret) {
> > +		dev_err(phy->dev, "%s: rx1_symbol_clk enable failed %d\n",
> > +				__func__, ret);
> > +		goto out;
> > +	}
> 
> All these clocks are never disabled?
Sure, will add disabling of clocks in exit callback 

> > +out:
> > +	return ret;
> > +}
> > +
> > +static int samsung_ufs_phy_clks_init(struct samsung_ufs_phy *phy) {
> > +	struct clk *phy_ref_clk;
> > +	int ret;
> > +
> > +	phy_ref_clk = devm_clk_get(phy->dev, "ref_clk");
> > +	if (IS_ERR(phy_ref_clk))
> > +		dev_err(phy->dev, "failed to get ref_clk clock\n");
> > +	else
> > +		phy->ref_clk = phy_ref_clk;
> > +
> > +	ret = clk_prepare_enable(phy->ref_clk);
> > +	if (ret) {
> > +		dev_err(phy->dev, "%s: ref_clk enable failed %d\n",
> > +				__func__, ret);
> > +		return ret;
> > +	}
> > +
> > +	dev_info(phy->dev, "UFS MPHY ref_clk_rate = %ld\n",
> > +clk_get_rate(phy_ref_clk));
> > +
> > +	return 0;
> > +}
> > +
> > +static int samsung_ufs_phy_init(struct phy *phy) {
> > +	struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(phy);
> > +	int ret;
> > +
> > +	_phy->lane_cnt = phy->attrs.bus_width;
> > +	_phy->ufs_phy_state = CFG_PRE_INIT;
> > +
> > +	_phy->is_pre_init = true;
> > +	_phy->is_post_init = false;
> > +	_phy->is_pre_pmc = false;
> > +	_phy->is_post_pmc = false;
> > +
> > +
> > +	if (of_device_is_compatible(_phy->dev->of_node,
> > +				"samsung,exynos7-ufs-phy")) {
> 
> Can't it be added in driver data for this compatible?
Sure, will handle via driver data.

> > +		ret = samsung_ufs_phy_symbol_clk_init(_phy);
> > +		if (ret)
> > +			dev_err(_phy->dev,
> > +				"failed to set ufs phy symbol clocks\n");
> > +	}
> > +
.
.
.
> > +static int samsung_ufs_phy_set_mode(struct phy *generic_phy,
> > +					enum phy_mode mode, int submode) {
> > +	struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(generic_phy);
> > +
> > +	_phy->mode = PHY_MODE_INVALID;
> > +
> > +	if (mode > 0)
> > +		_phy->mode = mode;
> > +
> > +	return 0;
> > +}
> > +
> > +static struct phy_ops samsung_ufs_phy_ops = {
> > +	.init		= samsung_ufs_phy_init,
> > +	.power_on	= samsung_ufs_phy_power_on,
> > +	.power_off	= samsung_ufs_phy_power_off,
> > +	.calibrate	= samsung_ufs_phy_calibrate,
> > +	.set_mode	= samsung_ufs_phy_set_mode,
> 
> missing .owner.
Ack,

> > +}
> > +;
.
.
> > +++ b/drivers/phy/samsung/phy-samsung-ufs.h
> > @@ -0,0 +1,142 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * UFS PHY driver for Samsung EXYNOS SoC
> > + *
> > + * Copyright (C) 2015 Samsung Electronics Co., Ltd.
> 
> 2020
> 
Sure, will update.

> Thanks
> Kishon





[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux