Commit 54b879b7 authored by Yaniv Gardi's avatar Yaniv Gardi Committed by Martin K. Petersen

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: default avatarHannes Reinecke <hare@suse.de>
Acked-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarGilad Broner <gbroner@codeaurora.org>
Signed-off-by: default avatarYaniv Gardi <ygardi@codeaurora.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent f6a695cf
...@@ -38,6 +38,9 @@ Optional properties: ...@@ -38,6 +38,9 @@ Optional properties:
defined or a value in the array is "0" then it is assumed defined or a value in the array is "0" then it is assumed
that the frequency is set by the parent clock or a that the frequency is set by the parent clock or a
fixed rate clock source. 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. If not specified, default is 2 lanes per direction.
Note: If above properties are not defined it can be assumed that the supply Note: If above properties are not defined it can be assumed that the supply
regulators or clocks are always on. regulators or clocks are always on.
......
/* /*
* Copyright (c) 2013-2015, Linux Foundation. All rights reserved. * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * 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,21 +132,24 @@ static int ufs_qcom_enable_lane_clks(struct ufs_qcom_host *host)
if (err) if (err)
goto disable_rx_l0; goto disable_rx_l0;
err = ufs_qcom_host_clk_enable(dev, "rx_lane1_sync_clk", if (host->hba->lanes_per_direction > 1) {
host->rx_l1_sync_clk); err = ufs_qcom_host_clk_enable(dev, "rx_lane1_sync_clk",
if (err) host->rx_l1_sync_clk);
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); host->tx_l1_sync_clk);
if (err) if (err)
goto disable_rx_l1; goto disable_rx_l1;
}
host->is_lane_clks_enabled = true; host->is_lane_clks_enabled = true;
goto out; goto out;
disable_rx_l1: disable_rx_l1:
clk_disable_unprepare(host->rx_l1_sync_clk); if (host->hba->lanes_per_direction > 1)
clk_disable_unprepare(host->rx_l1_sync_clk);
disable_tx_l0: disable_tx_l0:
clk_disable_unprepare(host->tx_l0_sync_clk); clk_disable_unprepare(host->tx_l0_sync_clk);
disable_rx_l0: disable_rx_l0:
...@@ -170,14 +173,16 @@ static int ufs_qcom_init_lane_clks(struct ufs_qcom_host *host) ...@@ -170,14 +173,16 @@ static int ufs_qcom_init_lane_clks(struct ufs_qcom_host *host)
if (err) if (err)
goto out; goto out;
err = ufs_qcom_host_clk_get(dev, "rx_lane1_sync_clk", /* In case of single lane per direction, don't read lane1 clocks */
&host->rx_l1_sync_clk); if (host->hba->lanes_per_direction > 1) {
if (err) err = ufs_qcom_host_clk_get(dev, "rx_lane1_sync_clk",
goto out; &host->rx_l1_sync_clk);
if (err)
err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk", goto out;
&host->tx_l1_sync_clk);
err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
&host->tx_l1_sync_clk);
}
out: out:
return err; return err;
} }
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#include "ufshcd.h" #include "ufshcd.h"
#include "ufshcd-pltfrm.h" #include "ufshcd-pltfrm.h"
#define UFSHCD_DEFAULT_LANES_PER_DIRECTION 2
static int ufshcd_parse_clock_info(struct ufs_hba *hba) static int ufshcd_parse_clock_info(struct ufs_hba *hba)
{ {
int ret = 0; int ret = 0;
...@@ -277,6 +279,21 @@ void ufshcd_pltfrm_shutdown(struct platform_device *pdev) ...@@ -277,6 +279,21 @@ void ufshcd_pltfrm_shutdown(struct platform_device *pdev)
} }
EXPORT_SYMBOL_GPL(ufshcd_pltfrm_shutdown); EXPORT_SYMBOL_GPL(ufshcd_pltfrm_shutdown);
static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba)
{
struct device *dev = hba->dev;
int ret;
ret = of_property_read_u32(dev->of_node, "lanes-per-direction",
&hba->lanes_per_direction);
if (ret) {
dev_dbg(hba->dev,
"%s: failed to read lanes-per-direction, ret=%d\n",
__func__, ret);
hba->lanes_per_direction = UFSHCD_DEFAULT_LANES_PER_DIRECTION;
}
}
/** /**
* ufshcd_pltfrm_init - probe routine of the driver * ufshcd_pltfrm_init - probe routine of the driver
* @pdev: pointer to Platform device handle * @pdev: pointer to Platform device handle
...@@ -331,6 +348,8 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, ...@@ -331,6 +348,8 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
pm_runtime_set_active(&pdev->dev); pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
ufshcd_init_lanes_per_dir(hba);
err = ufshcd_init(hba, mmio_base, irq); err = ufshcd_init(hba, mmio_base, irq);
if (err) { if (err) {
dev_err(dev, "Initialization failed\n"); dev_err(dev, "Initialization failed\n");
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <linux/async.h> #include <linux/async.h>
#include <linux/devfreq.h> #include <linux/devfreq.h>
#include <linux/of.h>
#include "ufshcd.h" #include "ufshcd.h"
#include "unipro.h" #include "unipro.h"
......
...@@ -509,6 +509,8 @@ struct ufs_hba { ...@@ -509,6 +509,8 @@ struct ufs_hba {
bool wlun_dev_clr_ua; bool wlun_dev_clr_ua;
/* Number of lanes available (1 or 2) for Rx/Tx */
u32 lanes_per_direction;
struct ufs_pa_layer_attr pwr_info; struct ufs_pa_layer_attr pwr_info;
struct ufs_pwr_mode_info max_pwr_info; struct ufs_pwr_mode_info max_pwr_info;
......
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