aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYaniv Gardi <ygardi@codeaurora.org>2016-03-10 10:37:05 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2016-03-14 21:04:45 -0400
commit54b879b76ea253105505f840bd842c1927c9e380 (patch)
treed0caf219520b92c99979ed7558d40099a97cfe4e
parentf6a695cf7a21519fe32b8005ff1a45d81c307f2c (diff)
scsi: ufs-qcom: add number of lanes per direction
Different platform 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. Reviewed-by: Hannes Reinecke <hare@suse.de> Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Gilad Broner <gbroner@codeaurora.org> Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt3
-rw-r--r--drivers/scsi/ufs/ufs-qcom.c39
-rw-r--r--drivers/scsi/ufs/ufshcd-pltfrm.c19
-rw-r--r--drivers/scsi/ufs/ufshcd.c1
-rw-r--r--drivers/scsi/ufs/ufshcd.h2
5 files changed, 47 insertions, 17 deletions
diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
index 03c0e989e020..66f6adf8d44d 100644
--- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
+++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
@@ -38,6 +38,9 @@ Optional properties:
38 defined or a value in the array is "0" then it is assumed 38 defined or a value in the array is "0" then it is assumed
39 that the frequency is set by the parent clock or a 39 that the frequency is set by the parent clock or a
40 fixed rate clock source. 40 fixed rate clock source.
41-lanes-per-direction : number of lanes available per direction - either 1 or 2.
42 Note that it is assume same number of lanes is used both
43 directions at once. If not specified, default is 2 lanes per direction.
41 44
42Note: If above properties are not defined it can be assumed that the supply 45Note: If above properties are not defined it can be assumed that the supply
43regulators or clocks are always on. 46regulators or clocks are always on.
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 4f38d008bfb4..ed5772902f4b 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2013-2015, Linux Foundation. All rights reserved. 2 * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and 5 * it under the terms of the GNU General Public License version 2 and
@@ -132,21 +132,24 @@ static int ufs_qcom_enable_lane_clks(struct ufs_qcom_host *host)
132 if (err) 132 if (err)
133 goto disable_rx_l0; 133 goto disable_rx_l0;
134 134
135 err = ufs_qcom_host_clk_enable(dev, "rx_lane1_sync_clk", 135 if (host->hba->lanes_per_direction > 1) {
136 host->rx_l1_sync_clk); 136 err = ufs_qcom_host_clk_enable(dev, "rx_lane1_sync_clk",
137 if (err) 137 host->rx_l1_sync_clk);
138 goto disable_tx_l0; 138 if (err)
139 goto disable_tx_l0;
139 140
140 err = ufs_qcom_host_clk_enable(dev, "tx_lane1_sync_clk", 141 err = ufs_qcom_host_clk_enable(dev, "tx_lane1_sync_clk",
141 host->tx_l1_sync_clk); 142 host->tx_l1_sync_clk);
142 if (err) 143 if (err)
143 goto disable_rx_l1; 144 goto disable_rx_l1;
145 }
144 146
145 host->is_lane_clks_enabled = true; 147 host->is_lane_clks_enabled = true;
146 goto out; 148 goto out;
147 149
148disable_rx_l1: 150disable_rx_l1:
149 clk_disable_unprepare(host->rx_l1_sync_clk); 151 if (host->hba->lanes_per_direction > 1)
152 clk_disable_unprepare(host->rx_l1_sync_clk);
150disable_tx_l0: 153disable_tx_l0:
151 clk_disable_unprepare(host->tx_l0_sync_clk); 154 clk_disable_unprepare(host->tx_l0_sync_clk);
152disable_rx_l0: 155disable_rx_l0:
@@ -170,14 +173,16 @@ static int ufs_qcom_init_lane_clks(struct ufs_qcom_host *host)
170 if (err) 173 if (err)
171 goto out; 174 goto out;
172 175
173 err = ufs_qcom_host_clk_get(dev, "rx_lane1_sync_clk", 176 /* In case of single lane per direction, don't read lane1 clocks */
174 &host->rx_l1_sync_clk); 177 if (host->hba->lanes_per_direction > 1) {
175 if (err) 178 err = ufs_qcom_host_clk_get(dev, "rx_lane1_sync_clk",
176 goto out; 179 &host->rx_l1_sync_clk);
177 180 if (err)
178 err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk", 181 goto out;
179 &host->tx_l1_sync_clk);
180 182
183 err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
184 &host->tx_l1_sync_clk);
185 }
181out: 186out:
182 return err; 187 return err;
183} 188}
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
index d2a7b127b05c..718f12e09885 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -40,6 +40,8 @@
40#include "ufshcd.h" 40#include "ufshcd.h"
41#include "ufshcd-pltfrm.h" 41#include "ufshcd-pltfrm.h"
42 42
43#define UFSHCD_DEFAULT_LANES_PER_DIRECTION 2
44
43static int ufshcd_parse_clock_info(struct ufs_hba *hba) 45static int ufshcd_parse_clock_info(struct ufs_hba *hba)
44{ 46{
45 int ret = 0; 47 int ret = 0;
@@ -277,6 +279,21 @@ void ufshcd_pltfrm_shutdown(struct platform_device *pdev)
277} 279}
278EXPORT_SYMBOL_GPL(ufshcd_pltfrm_shutdown); 280EXPORT_SYMBOL_GPL(ufshcd_pltfrm_shutdown);
279 281
282static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba)
283{
284 struct device *dev = hba->dev;
285 int ret;
286
287 ret = of_property_read_u32(dev->of_node, "lanes-per-direction",
288 &hba->lanes_per_direction);
289 if (ret) {
290 dev_dbg(hba->dev,
291 "%s: failed to read lanes-per-direction, ret=%d\n",
292 __func__, ret);
293 hba->lanes_per_direction = UFSHCD_DEFAULT_LANES_PER_DIRECTION;
294 }
295}
296
280/** 297/**
281 * ufshcd_pltfrm_init - probe routine of the driver 298 * ufshcd_pltfrm_init - probe routine of the driver
282 * @pdev: pointer to Platform device handle 299 * @pdev: pointer to Platform device handle
@@ -331,6 +348,8 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
331 pm_runtime_set_active(&pdev->dev); 348 pm_runtime_set_active(&pdev->dev);
332 pm_runtime_enable(&pdev->dev); 349 pm_runtime_enable(&pdev->dev);
333 350
351 ufshcd_init_lanes_per_dir(hba);
352
334 err = ufshcd_init(hba, mmio_base, irq); 353 err = ufshcd_init(hba, mmio_base, irq);
335 if (err) { 354 if (err) {
336 dev_err(dev, "Initialization failed\n"); 355 dev_err(dev, "Initialization failed\n");
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 9c1b94bef8f3..a8e42dfc32ec 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -40,6 +40,7 @@
40#include <linux/async.h> 40#include <linux/async.h>
41#include <linux/devfreq.h> 41#include <linux/devfreq.h>
42 42
43#include <linux/of.h>
43#include "ufshcd.h" 44#include "ufshcd.h"
44#include "unipro.h" 45#include "unipro.h"
45 46
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index e3931d0c94eb..9ae7f85b2a33 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -509,6 +509,8 @@ struct ufs_hba {
509 509
510 bool wlun_dev_clr_ua; 510 bool wlun_dev_clr_ua;
511 511
512 /* Number of lanes available (1 or 2) for Rx/Tx */
513 u32 lanes_per_direction;
512 struct ufs_pa_layer_attr pwr_info; 514 struct ufs_pa_layer_attr pwr_info;
513 struct ufs_pwr_mode_info max_pwr_info; 515 struct ufs_pwr_mode_info max_pwr_info;
514 516