Re: [PATCH] scsi: ufs-qcom: add number of lanes per direction

2018-02-26 Thread cang

On 2018-02-09 10:29, Rob Herring wrote:

On Mon, Feb 05, 2018 at 08:02:07PM +0800, Can Guo wrote:

From: Gilad Broner 

Different platforms may have different number of lanes for the UFS 
link.

Add parameter to device tree specifying how many lanes should be
configured for the UFS link. And don't print err message for clocks
that are optional, this leads to unnecessary confusion about failure.

Signed-off-by: Gilad Broner 
Signed-off-by: Subhash Jadavani 
Signed-off-by: Can Guo 

diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt 
b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt

index 5357919..4cee3f9 100644
--- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
+++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
@@ -31,6 +31,9 @@ Optional properties:
  defined or a value in the array is "0" then it is 
assumed
  that the frequency is set by the parent clock or a
  fixed rate clock source.
+- lanes-per-direction:	number of lanes available per direction - 
either 1 or 2.
+			Note that it is assume same number of lanes is used both 
directions at once.


Seems reasonable until someone does not make things symmetrical. We
should design for that case.

You are right, I will make changes like using lanes-tx and lanes-rx for 
Tx/Rx links for asymmetrial senarios and upload V2 patch

+   If not specified, default is 2 lanes per direction.

 Note: If above properties are not defined it can be assumed that the 
supply

 regulators or clocks are always on.


Re: [PATCH v1] scsi: ufs: add 2 lane support

2018-10-08 Thread cang

On 2018-10-04 02:34, Evan Green wrote:

Hi,

On Wed, Oct 3, 2018 at 11:19 AM Can Guo  wrote:


From: Venkat Gopalakrishnan 

Qcom ufs controller v3.1.0 supports 2 lanes, add support
to configure 2 lanes during phy initialization.


I'm reviving this old chestnut, sorry I missed it initially. This
description is a little terse, and I'm actually confused about it. The
description makes it sounds like this patch is adding support for
2-lane UFS controllers, but the patch itself appears to only make the
UFS controller tolerant of a missing lane (or more specifically, a
missing lane clock). Can you describe a little more about what's going
on here, and perhaps fix the description?

I notice that the global clock controller has clocks for TX symbol 0,
and RX symbol 1, but seems to be missing GCC_UFS_PHY_TX_SYMBOL_1_CLK.
Was that an oversight, or is it really not there?



Signed-off-by: Venkat Gopalakrishnan 
Signed-off-by: Subhash Jadavani 
Signed-off-by: Can Guo 
---
 drivers/scsi/ufs/ufs-qcom.c | 20 +---
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 2b38db2..51889ad 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -113,10 +113,10 @@ static void ufs_qcom_disable_lane_clks(struct 
ufs_qcom_host *host)

if (!host->is_lane_clks_enabled)
return;

-   if (host->hba->lanes_per_direction > 1)
+   if (host->tx_l1_sync_clk)
clk_disable_unprepare(host->tx_l1_sync_clk);
clk_disable_unprepare(host->tx_l0_sync_clk);
-   if (host->hba->lanes_per_direction > 1)
+   if (host->rx_l1_sync_clk)
clk_disable_unprepare(host->rx_l1_sync_clk);
clk_disable_unprepare(host->rx_l0_sync_clk);

@@ -147,18 +147,15 @@ static int ufs_qcom_enable_lane_clks(struct 
ufs_qcom_host *host)

if (err)
goto disable_tx_l0;

-   err = ufs_qcom_host_clk_enable(dev, 
"tx_lane1_sync_clk",

-   host->tx_l1_sync_clk);
-   if (err)
-   goto disable_rx_l1;
+   /* The tx lane1 clk could be muxed, hence keep this 
optional */


I'm confused by this comment. What do you mean the clock could be 
muxed?




Hi Evan, sorry for the late response, I totally missed this mail.
Here it means Tx Lane1 clock can be muxed with Tx Lane0 clock.
As by design, Tx Lane1 clock derives from Tx Lane0 clock.

I pushed a new change of it as I change the commit name.
Please help review the new patch. Sorry for the inconveience.


+   if (host->tx_l1_sync_clk)
+   ufs_qcom_host_clk_enable(dev, 
"tx_lane1_sync_clk",
+
host->tx_l1_sync_clk);

}

host->is_lane_clks_enabled = true;
goto out;

-disable_rx_l1:
-   if (host->hba->lanes_per_direction > 1)
-   clk_disable_unprepare(host->rx_l1_sync_clk);
 disable_tx_l0:
clk_disable_unprepare(host->tx_l0_sync_clk);
 disable_rx_l0:
@@ -189,8 +186,9 @@ static int ufs_qcom_init_lane_clks(struct 
ufs_qcom_host *host)

if (err)
goto out;

-   err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
-   &host->tx_l1_sync_clk);
+   /* The tx lane1 clk could be muxed, hence keep this 
optional */

+   ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
+   &host->tx_l1_sync_clk);
}
 out:
return err;


Re: [PATCH v1] scsi: ufs: add 2 lane support

2018-10-08 Thread cang

Hi Evan,

On 2018-10-04 02:34, Evan Green wrote:

Hi,

On Wed, Oct 3, 2018 at 11:19 AM Can Guo  wrote:


From: Venkat Gopalakrishnan 

Qcom ufs controller v3.1.0 supports 2 lanes, add support
to configure 2 lanes during phy initialization.


I'm reviving this old chestnut, sorry I missed it initially. This
description is a little terse, and I'm actually confused about it. The
description makes it sounds like this patch is adding support for
2-lane UFS controllers, but the patch itself appears to only make the
UFS controller tolerant of a missing lane (or more specifically, a
missing lane clock). Can you describe a little more about what's going
on here, and perhaps fix the description?

I notice that the global clock controller has clocks for TX symbol 0,
and RX symbol 1, but seems to be missing GCC_UFS_PHY_TX_SYMBOL_1_CLK.
Was that an oversight, or is it really not there?



You are right. The name and commit message are not representing itself
correctly as most of the original commit has been upstreamed already.
I uploaded a new patch to address it.

As per Qcom's design Tx Lane1 clock derives from Tx Lane0. So only
one Tx Lane0 clock would make 2 Tx lanes work.



Signed-off-by: Venkat Gopalakrishnan 
Signed-off-by: Subhash Jadavani 
Signed-off-by: Can Guo 
---
 drivers/scsi/ufs/ufs-qcom.c | 20 +---
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 2b38db2..51889ad 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -113,10 +113,10 @@ static void ufs_qcom_disable_lane_clks(struct 
ufs_qcom_host *host)

if (!host->is_lane_clks_enabled)
return;

-   if (host->hba->lanes_per_direction > 1)
+   if (host->tx_l1_sync_clk)
clk_disable_unprepare(host->tx_l1_sync_clk);
clk_disable_unprepare(host->tx_l0_sync_clk);
-   if (host->hba->lanes_per_direction > 1)
+   if (host->rx_l1_sync_clk)
clk_disable_unprepare(host->rx_l1_sync_clk);
clk_disable_unprepare(host->rx_l0_sync_clk);

@@ -147,18 +147,15 @@ static int ufs_qcom_enable_lane_clks(struct 
ufs_qcom_host *host)

if (err)
goto disable_tx_l0;

-   err = ufs_qcom_host_clk_enable(dev, 
"tx_lane1_sync_clk",

-   host->tx_l1_sync_clk);
-   if (err)
-   goto disable_rx_l1;
+   /* The tx lane1 clk could be muxed, hence keep this 
optional */


I'm confused by this comment. What do you mean the clock could be 
muxed?



+   if (host->tx_l1_sync_clk)
+   ufs_qcom_host_clk_enable(dev, 
"tx_lane1_sync_clk",
+
host->tx_l1_sync_clk);

}

host->is_lane_clks_enabled = true;
goto out;

-disable_rx_l1:
-   if (host->hba->lanes_per_direction > 1)
-   clk_disable_unprepare(host->rx_l1_sync_clk);
 disable_tx_l0:
clk_disable_unprepare(host->tx_l0_sync_clk);
 disable_rx_l0:
@@ -189,8 +186,9 @@ static int ufs_qcom_init_lane_clks(struct 
ufs_qcom_host *host)

if (err)
goto out;

-   err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
-   &host->tx_l1_sync_clk);
+   /* The tx lane1 clk could be muxed, hence keep this 
optional */

+   ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
+   &host->tx_l1_sync_clk);
}
 out:
return err;


Re: [PATCH 1/1] scsi: ufs: make UFS Tx lane1 clock optional

2018-10-10 Thread cang

Hi Doug,

Really thank you for your review.

On 2018-10-10 05:56, Doug Anderson wrote:

Hi,

On Sun, Oct 7, 2018 at 9:34 PM Can Guo  wrote:


From: Venkat Gopalakrishnan 

The UFS Tx lane1 clock could be muxed, hence keep it optional by 
ignoring

it if it is not provided in device tree.


Thanks for the updated commit message.  This makes much more sense now! 
 :-)





Yeah, sorry for making you guys confused. My bad previously.

@@ -113,10 +110,10 @@ static void ufs_qcom_disable_lane_clks(struct 
ufs_qcom_host *host)

if (!host->is_lane_clks_enabled)
return;

-   if (host->hba->lanes_per_direction > 1)
+   if (host->tx_l1_sync_clk)
clk_disable_unprepare(host->tx_l1_sync_clk);


I don't believe you need the "if".  A NULL clock is by definition OK
to enable / disable which is designed to make optional clocks easier
to deal with.




You are right, I checked the implemention, clock enable/disable func 
would

bail out if clk is NULL just as your comments.


clk_disable_unprepare(host->tx_l0_sync_clk);
-   if (host->hba->lanes_per_direction > 1)
+   if (host->rx_l1_sync_clk)
clk_disable_unprepare(host->rx_l1_sync_clk);


optional: Technically this part of the patch wasn't actually needed,
right?  "rx_l1_sync_clk" is not optional so that means that
"rx_l1_sync_clk" should be non-NULL exactly when lanes_per_direction >
1.

...but actually I'm fine with keeping this part of your patch for
symmetry.  Especially since you can leverage the
clk_disable_unprepare(NULL) to simplify your code.  Please mention in
your commit message that this is a cleanup and just for symmetry.
Probably also remove the "if" tests that are guarding
ufs_qcom_host_clk_enable().




Sure, got it.


clk_disable_unprepare(host->rx_l0_sync_clk);

@@ -141,24 +138,21 @@ static int ufs_qcom_enable_lane_clks(struct 
ufs_qcom_host *host)

if (err)
goto disable_rx_l0;

-   if (host->hba->lanes_per_direction > 1) {
+   if (host->rx_l1_sync_clk) {


Similar: the above change isn't required but I'm OK if you want to
make this change for symmetry / to cleanup clock handling.  Please
mention in your commit message.




Sure, shall do so.

+   /* The tx lane1 clk could be muxed, hence keep this optional 
*/

+   if (host->tx_l1_sync_clk)
+   ufs_qcom_host_clk_enable(dev, "tx_lane1_sync_clk",
+host->tx_l1_sync_clk);


If "host->tx_l1_sync_clk" is provided then you should still check the
return value of ufs_qcom_host_clk_enable(), right?  ...so please leave
the error path here.




Yeah... you are right.

@@ -174,23 +168,33 @@ static int ufs_qcom_init_lane_clks(struct 
ufs_qcom_host *host)


err = ufs_qcom_host_clk_get(dev,
"rx_lane0_sync_clk", &host->rx_l0_sync_clk);
-   if (err)
+   if (err) {
+   dev_err(dev, "%s: failed to get rx_lane0_sync_clk, err 
%d",

+   __func__, err);


nit: including "__func__" in dev_xxx() calls is discouraged.  The
"dev_xxx" calls already print the device name and the string within a
given device driver should be unique enough so __func__ just adds crap
to the logs.  If you really feel that __func__ adds something for you,
try posting up a patch to make all "dev_err" functions include
__func__.  ...but I think you'd probably be rejected.

suggestion: you'd save a few lines of code and simplify your probe if
you just passed an "optional" bool to the ufs_qcom_host_clk_get() that
controlled the printout.




Good idea!


-   err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
-   &host->tx_l1_sync_clk);
+   /* The tx lane1 clk could be muxed, hence keep this 
optional */

+   ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
+   &host->tx_l1_sync_clk);


To be technically correct you should actually check the error value
returned by ufs_qcom_host_clk_get().  Specifically figure out what the
error value is when "tx_lane1_sync_clk" isn't specified and check for
that.

...one reason this matters is -EPROBE_DEFER.  In theory devm_clk_get()
could return -EPROBE_DEFER.  In such a case you'd want to exit the
probe, not continue on.  It's also just good coding practice to handle
just the error you want though so that if the function returned some
other failing case you'd propagate it down instead of eating it.

If you passed "optional" to ufs_qcom_host_clk_get() as suggested above
you could put this error-code checking in ufs_qcom_host_clk_get() and
return 0 from that function if an optional clock was found to not
exist.

-Doug


I think I understand it. Thanks a lot for the thorough review and 
suggestions.


-Can Guo


Re: [PATCH v2 1/1] scsi: ufs: make UFS Tx lane1 clock optional for QCOM platforms

2018-10-11 Thread cang

Hi Doug,

On 2018-10-12 04:21, Doug Anderson wrote:

Hi,

On Thu, Oct 11, 2018 at 5:33 AM Can Guo  wrote:

 static int ufs_qcom_host_clk_get(struct device *dev,
-   const char *name, struct clk **clk_out)
+   const char *name, struct clk **clk_out, bool optional)
 {
struct clk *clk;
int err = 0;

clk = devm_clk_get(dev, name);
-   if (IS_ERR(clk)) {
+   if (clk == ERR_PTR(-EPROBE_DEFER)) {
+   err = -EPROBE_DEFER;
+   dev_warn(dev, "required clock %s hasn't probed yet, 
err %d\n",

+   name, err);
+   } else if (IS_ERR(clk)) {
+   if (optional)
+   return 0;


Change this function to:

static int ufs_qcom_host_clk_get(struct device *dev,
const char *name, struct clk **clk_out, bool optional)
{
  struct clk *clk;
  int err;

  clk = devm_clk_get(dev, name);
  if (!IS_ERR(clk)) {
*clk_out = clk;
return 0;
  }

  err = PTR_ERR(clk);

  if (optional && err == -ENOENT) {
*clk_out = NULL;
return 0;
  }

  if (err != -EPROBE_DEFER)
dev_err(dev, "failed to get %s err %d",
name, err);

  return err;
}

Specifically:

* Typically it just spams the log to print something when you see an
-EPROBE_DEFER.

* If a clock is optional you should only consider things a success
only if "-ENOENT" was returned.  All other errors should be considered
fatal.

* If a clock is optional it's slightly cleaner to set *clk_out to
NULL.  I know you're initting global data that happened to already be
NULL by default, but it still feels nice for the abstraction of the
function to do this.

* Please don't pass __func__ to your error messages.




Thank you for the detailed instructions. Shall make the change like so.


err = PTR_ERR(clk);
dev_err(dev, "%s: failed to get %s err %d",
__func__, name, err);
@@ -113,10 +119,10 @@ static void ufs_qcom_disable_lane_clks(struct 
ufs_qcom_host *host)

if (!host->is_lane_clks_enabled)
return;

-   if (host->hba->lanes_per_direction > 1)
+   if (host->tx_l1_sync_clk)


Remove this "if".  Always call clk_disable_unprepare() which will be a
no-op if "host->tx_l1_sync_clk" is NULL.  clk_disable_unprepare() is a
no-op for NULL clocks by design specifically to make code like this
cleaner.




Shall do.


clk_disable_unprepare(host->tx_l1_sync_clk);
clk_disable_unprepare(host->tx_l0_sync_clk);
-   if (host->hba->lanes_per_direction > 1)
+   if (host->rx_l1_sync_clk)


Remove this "if".  Always call clk_disable_unprepare() which will be a
no-op if "host->rx_l1_sync_clk" is NULL.  clk_disable_unprepare() is a
no-op for NULL clocks by design specifically to make code like this
cleaner.




Shall do.


clk_disable_unprepare(host->rx_l1_sync_clk);
clk_disable_unprepare(host->rx_l0_sync_clk);

@@ -141,12 +147,14 @@ static int ufs_qcom_enable_lane_clks(struct 
ufs_qcom_host *host)

if (err)
goto disable_rx_l0;

-   if (host->hba->lanes_per_direction > 1) {
+   if (host->rx_l1_sync_clk) {


Remove this "if".  Always call ufs_qcom_host_clk_enable().  The
clk_prepare_enable() inside ufs_qcom_host_clk_enable() will be a no-op
if "host->rx_l1_sync_clk" is NULL and will return 0 (no error).




Shall do so.

err = ufs_qcom_host_clk_enable(dev, 
"rx_lane1_sync_clk",

host->rx_l1_sync_clk);
if (err)
goto disable_tx_l0;
+   }

+   if (host->tx_l1_sync_clk) {


Remove this "if".  Always call ufs_qcom_host_clk_enable().  The
clk_prepare_enable() inside ufs_qcom_host_clk_enable() will be a no-op
if "host->tx_l1_sync_clk" is NULL and will return 0 (no error).


-Doug


Shall do so. Thank you.

-Can Guo


Re: [PATCH v3 1/1] scsi: ufs: make UFS Tx lane1 clock optional for QCOM platforms

2018-10-11 Thread cang

Hi,

On 2018-10-12 14:10, Vivek Gautam wrote:

On 10/12/2018 6:42 AM, Can Guo wrote:

From: Venkat Gopalakrishnan 

Per Qcom's UFS host controller HW design, the UFS Tx lane1 clock could 
be
muxed with Tx lane0 clock, hence keep Tx lane1 clock optional by 
ignoring
it if it is not provided in device tree. This change also performs 
some
cleanup to lanes per direction checks when enable/disable lane clocks 
just

for symmetry.

Signed-off-by: Venkat Gopalakrishnan 
Signed-off-by: Subhash Jadavani 
Signed-off-by: Can Guo 
---
Changes since v2:
- Incorporated review comments from Doug.

Changes since v1:
- Incorporated review comments from Doug.
- Update the commit title and commit message.

  drivers/scsi/ufs/ufs-qcom.c | 55 
-

  1 file changed, 29 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 2b38db2..dbc84cb 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -79,20 +79,28 @@ static int ufs_qcom_get_connected_tx_lanes(struct 
ufs_hba *hba, u32 *tx_lanes)

  }
static int ufs_qcom_host_clk_get(struct device *dev,
-   const char *name, struct clk **clk_out)
+   const char *name, struct clk **clk_out, bool optional)
  {
struct clk *clk;
int err = 0;
clk = devm_clk_get(dev, name);
-   if (IS_ERR(clk)) {
-   err = PTR_ERR(clk);
-   dev_err(dev, "%s: failed to get %s err %d",
-   __func__, name, err);
-   } else {
+   if (!IS_ERR(clk)) {
*clk_out = clk;
+   return 0;
}
  + err = PTR_ERR(clk);
+
+   if (optional && err == -ENOENT) {
+   *clk_out = NULL;
+   return 0;
+   }
+
+   if (err != -EPROBE_DEFER)
+   dev_err(dev, "failed to get %s err %d",
+   name, err);
+
return err;
  }
  @@ -113,11 +121,9 @@ static void ufs_qcom_disable_lane_clks(struct 
ufs_qcom_host *host)

if (!host->is_lane_clks_enabled)
return;
  - if (host->hba->lanes_per_direction > 1)
-   clk_disable_unprepare(host->tx_l1_sync_clk);
+   clk_disable_unprepare(host->tx_l1_sync_clk);
clk_disable_unprepare(host->tx_l0_sync_clk);
-   if (host->hba->lanes_per_direction > 1)
-   clk_disable_unprepare(host->rx_l1_sync_clk);
+   clk_disable_unprepare(host->rx_l1_sync_clk);
clk_disable_unprepare(host->rx_l0_sync_clk);
host->is_lane_clks_enabled = false;
@@ -141,24 +147,21 @@ static int ufs_qcom_enable_lane_clks(struct 
ufs_qcom_host *host)

if (err)
goto disable_rx_l0;
  - if (host->hba->lanes_per_direction > 1) {
-   err = ufs_qcom_host_clk_enable(dev, "rx_lane1_sync_clk",
+   err = ufs_qcom_host_clk_enable(dev, "rx_lane1_sync_clk",
host->rx_l1_sync_clk);
-   if (err)
-   goto disable_tx_l0;
+   if (err)
+   goto disable_tx_l0;
  - err = ufs_qcom_host_clk_enable(dev, "tx_lane1_sync_clk",
+   err = ufs_qcom_host_clk_enable(dev, "tx_lane1_sync_clk",
host->tx_l1_sync_clk);
-   if (err)
-   goto disable_rx_l1;
-   }
+   if (err)
+   goto disable_rx_l1;
host->is_lane_clks_enabled = true;
goto out;
disable_rx_l1:
-   if (host->hba->lanes_per_direction > 1)
-   clk_disable_unprepare(host->rx_l1_sync_clk);
+   clk_disable_unprepare(host->rx_l1_sync_clk);
  disable_tx_l0:
clk_disable_unprepare(host->tx_l0_sync_clk);
  disable_rx_l0:
@@ -172,25 +175,25 @@ static int ufs_qcom_init_lane_clks(struct 
ufs_qcom_host *host)

int err = 0;
struct device *dev = host->hba->dev;
  - err = ufs_qcom_host_clk_get(dev,
-   "rx_lane0_sync_clk", &host->rx_l0_sync_clk);
+   err = ufs_qcom_host_clk_get(dev, "rx_lane0_sync_clk",
+   &host->rx_l0_sync_clk, false);
if (err)
goto out;
  - err = ufs_qcom_host_clk_get(dev,
-   "tx_lane0_sync_clk", &host->tx_l0_sync_clk);
+   err = ufs_qcom_host_clk_get(dev, "tx_lane0_sync_clk",
+   &host->tx_l0_sync_clk, false);
if (err)
goto out;
	/* In case of single lane per direction, don't read lane1 clocks 
*/

if (host->hba->lanes_per_direction > 1) {
err = ufs_qcom_host_clk_get(dev, "rx_lane1_sync_clk",
-   &host->rx_l1_sync_clk);
+   &host->rx_l1_sync_clk, false);
if (err)
goto out;
err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
-   &host->tx_l1_sync_clk);
+   &host->tx_l1_sync_clk, t

Re: [PATCH v3 1/1] scsi: ufs: make UFS Tx lane1 clock optional for QCOM platforms

2018-10-12 Thread cang

On 2018-10-13 00:55, Doug Anderson wrote:

Hi,

On Thu, Oct 11, 2018 at 6:12 PM Can Guo  wrote:

+   if (err != -EPROBE_DEFER)
+   dev_err(dev, "failed to get %s err %d",
+   name, err);


I wouldn't spin just for this, but if you spin for some other reason
you could move the above "dev_err" onto one line now.  Sorry: I should
have noticed that / done that on my patch...




Yeah... I didn't notice it too. Shall push a new one to address it.

@@ -141,24 +147,21 @@ static int ufs_qcom_enable_lane_clks(struct 
ufs_qcom_host *host)


Idea for a future patch: now that I look at what's left of this
function you're basically re-implementing clk_bulk_prepare_enable()
and clk_bulk_disable_unprepare() now.  I bet your code would be
cleaner / nicer by switching to that.

...possibly you might need to improve the clk_bulk_get() API to allow
for some clock to be optional, but that would be a pretty easy patch
to post up.

In any case I think it's better to do the clk_bulk switch in a future
/ separate patch, so:

Reviewed-by: Douglas Anderson 
Tested-by: Douglas Anderson 


-Doug


That is a good idea, I shall follow up after this one is merged.

Thank you.
-Can Guo


Re: [PATCH v5 1/1] scsi: ufs: make UFS Tx lane1 clock optional for QCOM platforms

2018-10-15 Thread cang

Hi Martin,

On 2018-10-16 10:56, Martin K. Petersen wrote:

Can,


Per Qcom's UFS host controller HW design, the UFS Tx lane1 clock could
be muxed with Tx lane0 clock, hence keep Tx lane1 clock optional by
ignoring it if it is not provided in device tree. This change also
performs some cleanup to lanes per direction checks when
enable/disable lane clocks just for symmetry.


Applied to 4.20/scsi-queue, thanks!


Thanks a lot!

-Can Guo


Re: [PATCH v1] scsi: ufs: add 2 lane support

2018-04-11 Thread cang

On 2018-04-02 18:00, Vivek Gautam wrote:

Hi Can,


On 3/2/2018 1:48 PM, Can Guo wrote:

From: Venkat Gopalakrishnan 

Qcom ufs controller v3.1.0 supports 2 lanes, add support
to configure 2 lanes during phy initialization.

Signed-off-by: Venkat Gopalakrishnan 
Signed-off-by: Subhash Jadavani 
Signed-off-by: Can Guo 
---
  drivers/scsi/ufs/ufs-qcom.c | 20 +---
  1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 2b38db2..51889ad 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -113,10 +113,10 @@ static void ufs_qcom_disable_lane_clks(struct 
ufs_qcom_host *host)

if (!host->is_lane_clks_enabled)
return;
  - if (host->hba->lanes_per_direction > 1)
+   if (host->tx_l1_sync_clk)
clk_disable_unprepare(host->tx_l1_sync_clk);
clk_disable_unprepare(host->tx_l0_sync_clk);
-   if (host->hba->lanes_per_direction > 1)
+   if (host->rx_l1_sync_clk)
clk_disable_unprepare(host->rx_l1_sync_clk);
clk_disable_unprepare(host->rx_l0_sync_clk);
  @@ -147,18 +147,15 @@ static int ufs_qcom_enable_lane_clks(struct 
ufs_qcom_host *host)

if (err)
goto disable_tx_l0;
  - err = ufs_qcom_host_clk_enable(dev, "tx_lane1_sync_clk",
-   host->tx_l1_sync_clk);
-   if (err)
-   goto disable_rx_l1;
+   /* The tx lane1 clk could be muxed, hence keep this optional */


You need a similar change for "rx_l1_sync_clk" also.
And also get rid of 'lanes_per_direction' flag as well for
ufs_qcom_enable_lane_clks()
and ufs_qcom_init_lane_clks() too, as you are doing in
ufs_qcom_disable_lane_clks().



Sure, got it.

Thanks
Can


+   if (host->tx_l1_sync_clk)
+   ufs_qcom_host_clk_enable(dev, "tx_lane1_sync_clk",
+host->tx_l1_sync_clk);
}
host->is_lane_clks_enabled = true;
goto out;
  -disable_rx_l1:
-   if (host->hba->lanes_per_direction > 1)
-   clk_disable_unprepare(host->rx_l1_sync_clk);
  disable_tx_l0:
clk_disable_unprepare(host->tx_l0_sync_clk);
  disable_rx_l0:
@@ -189,8 +186,9 @@ static int ufs_qcom_init_lane_clks(struct 
ufs_qcom_host *host)

if (err)
goto out;
  - err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
-   &host->tx_l1_sync_clk);
+   /* The tx lane1 clk could be muxed, hence keep this optional */
+   ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
+   &host->tx_l1_sync_clk);


same here.

Best regards
Vivek



Shall do as well.

Thanks
Can


}
  out:
return err;