From e4d3720461314a9e453e427a56d0ffc5d72624fc Mon Sep 17 00:00:00 2001 From: Gilad Broner Date: Mon, 25 Jan 2016 14:20:35 +0200 Subject: [PATCH] phy: phy-qcom-ufs: separate U11 user registers from phy registers RUMI platform uses QRBTCv2 phy that has 2 separate sets of registers. One is the phy register set, and the other is the U11 user registers. Mapping both sets will require to map a larger range of memory that is overlapping with the ICE registers address. Separate into 2 independent memory mappings to avoid the conflict. Change-Id: Ifdb426cdd7139e918c5c3747f5529b047f4fc1e5 Signed-off-by: Gilad Broner --- drivers/phy/phy-qcom-ufs-qrbtc-v2.c | 38 ++++++++++++++++++++++++----- drivers/phy/phy-qcom-ufs-qrbtc-v2.h | 5 ++-- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/drivers/phy/phy-qcom-ufs-qrbtc-v2.c b/drivers/phy/phy-qcom-ufs-qrbtc-v2.c index a075618e29ae..8836e0ca7020 100644 --- a/drivers/phy/phy-qcom-ufs-qrbtc-v2.c +++ b/drivers/phy/phy-qcom-ufs-qrbtc-v2.c @@ -1,5 +1,5 @@ /* - * 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 * it under the terms of the GNU General Public License version 2 and @@ -23,15 +23,17 @@ int ufs_qcom_phy_qrbtc_v2_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy, int err; int tbl_size_A; struct ufs_qcom_phy_calibration *tbl_A; + struct ufs_qcom_phy_qrbtc_v2 *qrbtc_phy = container_of(ufs_qcom_phy, + struct ufs_qcom_phy_qrbtc_v2, common_cfg); - writel_relaxed(0x15f, ufs_qcom_phy->mmio + U11_UFS_RESET_REG_OFFSET); + writel_relaxed(0x15f, qrbtc_phy->u11_regs + U11_UFS_RESET_REG_OFFSET); /* 50ms are required to stabilize the reset */ usleep_range(50000, 50100); - writel_relaxed(0x0, ufs_qcom_phy->mmio + U11_UFS_RESET_REG_OFFSET); + writel_relaxed(0x0, qrbtc_phy->u11_regs + U11_UFS_RESET_REG_OFFSET); /* Set R3PC REF CLK */ - writel_relaxed(0x80, ufs_qcom_phy->mmio + U11_QRBTC_CONTROL_OFFSET); + writel_relaxed(0x80, qrbtc_phy->u11_regs + U11_QRBTC_CONTROL_OFFSET); tbl_A = phy_cal_table_rate_A; @@ -55,6 +57,8 @@ ufs_qcom_phy_qrbtc_v2_is_pcs_ready(struct ufs_qcom_phy *phy_common) { int err = 0; u32 val; + struct ufs_qcom_phy_qrbtc_v2 *qrbtc_phy = container_of(phy_common, + struct ufs_qcom_phy_qrbtc_v2, common_cfg); /* * The value we are polling for is 0x3D which represents the @@ -72,7 +76,7 @@ ufs_qcom_phy_qrbtc_v2_is_pcs_ready(struct ufs_qcom_phy *phy_common) dev_err(phy_common->dev, "%s: poll for pcs failed err = %d\n", __func__, err); - writel_relaxed(0x100, phy_common->mmio + U11_QRBTC_TX_CLK_CTRL); + writel_relaxed(0x100, qrbtc_phy->u11_regs + U11_QRBTC_TX_CLK_CTRL); return err; } @@ -94,7 +98,6 @@ static void ufs_qcom_phy_qrbtc_v2_start_serdes(struct ufs_qcom_phy *phy) static int ufs_qcom_phy_qrbtc_v2_init(struct phy *generic_phy) { return 0; - } struct phy_ops ufs_qcom_phy_qrbtc_v2_phy_ops = { @@ -115,6 +118,7 @@ static int ufs_qcom_phy_qrbtc_v2_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct phy *generic_phy; struct ufs_qcom_phy_qrbtc_v2 *phy; + struct resource *res; int err = 0; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); @@ -133,6 +137,28 @@ static int ufs_qcom_phy_qrbtc_v2_probe(struct platform_device *pdev) goto out; } + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "u11_user"); + if (!res) { + dev_err(dev, "%s: u11_user resource not found\n", __func__); + err = -EINVAL; + goto out; + } + + phy->u11_regs = devm_ioremap_resource(dev, res); + if (IS_ERR_OR_NULL(phy->u11_regs)) { + if (IS_ERR(phy->u11_regs)) { + err = PTR_ERR(phy->u11_regs); + phy->u11_regs = NULL; + dev_err(dev, "%s: ioremap for phy_mem resource failed %d\n", + __func__, err); + } else { + dev_err(dev, "%s: ioremap for phy_mem resource failed\n", + __func__); + err = -ENOMEM; + } + goto out; + } + phy_set_drvdata(generic_phy, phy); strlcpy(phy->common_cfg.name, UFS_PHY_NAME, diff --git a/drivers/phy/phy-qcom-ufs-qrbtc-v2.h b/drivers/phy/phy-qcom-ufs-qrbtc-v2.h index 3de9a4dffd2a..94590e0fd4a0 100644 --- a/drivers/phy/phy-qcom-ufs-qrbtc-v2.h +++ b/drivers/phy/phy-qcom-ufs-qrbtc-v2.h @@ -1,5 +1,5 @@ /* - * 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 * it under the terms of the GNU General Public License version 2 and @@ -20,7 +20,7 @@ /* QCOM UFS PHY control registers */ #define COM_OFF(x) (0x000 + x) #define PHY_OFF(x) (0x700 + x) -#define PHY_USR(x) (0x11000 + x) +#define PHY_USR(x) (x) #define UFS_PHY_PHY_START_OFFSET PHY_OFF(0x00) #define UFS_PHY_POWER_DOWN_CONTROL_OFFSET PHY_OFF(0x04) @@ -110,6 +110,7 @@ static struct ufs_qcom_phy_calibration phy_cal_table_rate_A[] = { */ struct ufs_qcom_phy_qrbtc_v2 { struct ufs_qcom_phy common_cfg; + void __iomem *u11_regs; }; #endif