Re: [PATCH 2/2] phy: msm8996-pcie-phy: Add support to msm8996 pcie phy

2016-09-16 Thread Srinivas Kandagatla



On 16/09/16 15:14, Stanimir Varbanov wrote:

> +  writel_relaxed(0x0f, base + QSERDES_COM_BG_TRIM);
> +  writel_relaxed(0x0f, base + QSERDES_COM_PLL_IVCO);
> +  writel_relaxed(0x19, base + QSERDES_COM_CLK_EP_DIV);
> +  writel_relaxed(0x10, base + QSERDES_COM_CLK_ENABLE1);
> +  writel_relaxed(0x00, base + QSERDES_COM_HSCLK_SEL);
> +  writel_relaxed(0x40, base + QSERDES_COM_RESCODE_DIV_NUM);
> +  writel_relaxed(0x00, base + PCIE_COM_SW_RESET);
> +  writel_relaxed(0x03, base + PCIE_COM_START_CONTROL);

I'd make an array with register/value pair and write the registers with
a for () loop. IMO it will be more readable.

Probably 3 arrays - power_on, power_on_common and power_off.
Thats good idea, I will keep that in mind before sending next version 
with common phy driver for USB/PCIE/UFS.


thanks
srini


Re: [PATCH 2/2] phy: msm8996-pcie-phy: Add support to msm8996 pcie phy

2016-09-16 Thread Srinivas Kandagatla



On 13/09/16 17:06, Archit Taneja wrote:



On 9/7/2016 4:25 PM, Srinivas Kandagatla wrote:

This patch adds support to msm8996 pcie phy which supports 3 ports,
Port A, Port B and Port C.

Each port is independent and connected to a pcie host controller,
there is
also a common block which is shared across all the 3 ports.

Signed-off-by: Srinivas Kandagatla 
---
  drivers/phy/Kconfig |   7 +
  drivers/phy/Makefile|   1 +
  drivers/phy/phy-qcom-msm8996-pcie.c | 492




+#define PCIE_LANE_PCS_BASE 0x1400


I've seen the reg offsets of another SoC using the same
IP, but the above offsets aren't the same relative to the
phy base. We might want to create more reg properties in
DT to accommodate register maps on other SoCs.


Yep, I got some more info on this from Vivek and It looks like this IP 
has been reused on other Host controllers and SOCs.

So plan is to write a common driver for all of them.

Thanks,
srini


Re: [PATCH 2/2] phy: msm8996-pcie-phy: Add support to msm8996 pcie phy

2016-09-16 Thread Stanimir Varbanov
Hi Srini,



> +
> +static int qcom_msm8996_phy_common_power_off(struct phy *phy)
> +{
> + struct phy_msm8996_desc *phydesc = phy_get_drvdata(phy);
> + struct phy_msm8996_priv *priv = phydesc->priv;
> + void __iomem *base = priv->base;
> +
> + mutex_lock(&priv->phy_mutex);
> + if (--priv->init_count) {
> + mutex_unlock(&priv->phy_mutex);
> + return 0;
> + }
> +
> + writel_relaxed(0x01, base + PCIE_COM_SW_RESET);
> + writel_relaxed(0x0, base + PCIE_COM_POWER_DOWN_CONTROL);
> +
> + reset_control_assert(priv->phy_rstc);
> + reset_control_assert(priv->phycom_rstc);
> + clk_disable_unprepare(priv->cfg_clk);
> + clk_disable_unprepare(priv->aux_clk);
> + clk_disable_unprepare(priv->ref_clk);
> + clk_disable_unprepare(priv->ref_clk_src);
> +
> + mutex_unlock(&priv->phy_mutex);
> +
> + return 0;
> +}
> +
> +static int qcom_msm8996_phy_common_power_on(struct phy *phy)
> +{
> + struct phy_msm8996_desc *phydesc = phy_get_drvdata(phy);
> + struct phy_msm8996_priv *priv = phydesc->priv;
> + void __iomem *base = priv->base;
> + int ret;
> +
> + mutex_lock(&priv->phy_mutex);
> + if (priv->init_count++) {
> + mutex_unlock(&priv->phy_mutex);
> + return 0;
> + }
> +
> + clk_prepare_enable(priv->cfg_clk);
> + clk_prepare_enable(priv->aux_clk);
> + clk_prepare_enable(priv->ref_clk);
> + clk_prepare_enable(priv->ref_clk_src);
> +
> + reset_control_deassert(priv->phy_rstc);
> + reset_control_deassert(priv->phycom_rstc);
> +
> + writel_relaxed(0x01, base + PCIE_COM_POWER_DOWN_CONTROL);
> + writel_relaxed(0x1c, base + QSERDES_COM_BIAS_EN_CLKBUFLR_EN);
> + writel_relaxed(0x10, base + QSERDES_COM_CLK_ENABLE1);
> + writel_relaxed(0x33, base + QSERDES_COM_CLK_SELECT);
> + writel_relaxed(0x06, base + QSERDES_COM_CMN_CONFIG);
> + writel_relaxed(0x42, base + QSERDES_COM_LOCK_CMP_EN);
> + writel_relaxed(0x00, base + QSERDES_COM_VCO_TUNE_MAP);
> + writel_relaxed(0xff, base + QSERDES_COM_VCO_TUNE_TIMER1);
> + writel_relaxed(0x1f, base + QSERDES_COM_VCO_TUNE_TIMER2);
> + writel_relaxed(0x01, base + QSERDES_COM_HSCLK_SEL);
> + writel_relaxed(0x01, base + QSERDES_COM_SVS_MODE_CLK_SEL);
> + writel_relaxed(0x00, base + QSERDES_COM_CORE_CLK_EN);
> + writel_relaxed(0x0a, base + QSERDES_COM_CORECLK_DIV);
> + writel_relaxed(0x09, base + QSERDES_COM_BG_TIMER);
> + writel_relaxed(0x82, base + QSERDES_COM_DEC_START_MODE0);
> + writel_relaxed(0x03, base + QSERDES_COM_DIV_FRAC_START3_MODE0);
> + writel_relaxed(0x55, base + QSERDES_COM_DIV_FRAC_START2_MODE0);
> + writel_relaxed(0x55, base + QSERDES_COM_DIV_FRAC_START1_MODE0);
> + writel_relaxed(0x00, base + QSERDES_COM_LOCK_CMP3_MODE0);
> + writel_relaxed(0x1a, base + QSERDES_COM_LOCK_CMP2_MODE0);
> + writel_relaxed(0x0a, base + QSERDES_COM_LOCK_CMP1_MODE0);
> + writel_relaxed(0x33, base + QSERDES_COM_CLK_SELECT);
> + writel_relaxed(0x02, base + QSERDES_COM_SYS_CLK_CTRL);
> + writel_relaxed(0x1f, base + QSERDES_COM_SYSCLK_BUF_ENABLE);
> + writel_relaxed(0x04, base + QSERDES_COM_SYSCLK_EN_SEL);
> + writel_relaxed(0x0b, base + QSERDES_COM_CP_CTRL_MODE0);
> + writel_relaxed(0x16, base + QSERDES_COM_PLL_RCTRL_MODE0);
> + writel_relaxed(0x28, base + QSERDES_COM_PLL_CCTRL_MODE0);
> + writel_relaxed(0x00, base + QSERDES_COM_INTEGLOOP_GAIN1_MODE0);
> + writel_relaxed(0x80, base + QSERDES_COM_INTEGLOOP_GAIN0_MODE0);
> + writel_relaxed(0x01, base + QSERDES_COM_SSC_EN_CENTER);
> + writel_relaxed(0x31, base + QSERDES_COM_SSC_PER1);
> + writel_relaxed(0x01, base + QSERDES_COM_SSC_PER2);
> + writel_relaxed(0x02, base + QSERDES_COM_SSC_ADJ_PER1);
> + writel_relaxed(0x00, base + QSERDES_COM_SSC_ADJ_PER2);
> + writel_relaxed(0x2f, base + QSERDES_COM_SSC_STEP_SIZE1);
> + writel_relaxed(0x19, base + QSERDES_COM_SSC_STEP_SIZE2);
> + writel_relaxed(0x15, base + QSERDES_COM_RESCODE_DIV_NUM);
> + writel_relaxed(0x0f, base + QSERDES_COM_BG_TRIM);
> + writel_relaxed(0x0f, base + QSERDES_COM_PLL_IVCO);
> + writel_relaxed(0x19, base + QSERDES_COM_CLK_EP_DIV);
> + writel_relaxed(0x10, base + QSERDES_COM_CLK_ENABLE1);
> + writel_relaxed(0x00, base + QSERDES_COM_HSCLK_SEL);
> + writel_relaxed(0x40, base + QSERDES_COM_RESCODE_DIV_NUM);
> + writel_relaxed(0x00, base + PCIE_COM_SW_RESET);
> + writel_relaxed(0x03, base + PCIE_COM_START_CONTROL);

I'd make an array with register/value pair and write the registers with
a for () loop. IMO it will be more readable.

Probably 3 arrays - power_on, power_on_common and power_off.


-- 
regards,
Stan


Re: [PATCH 2/2] phy: msm8996-pcie-phy: Add support to msm8996 pcie phy

2016-09-13 Thread Archit Taneja



On 9/7/2016 4:25 PM, Srinivas Kandagatla wrote:

This patch adds support to msm8996 pcie phy which supports 3 ports,
Port A, Port B and Port C.

Each port is independent and connected to a pcie host controller, there is
also a common block which is shared across all the 3 ports.

Signed-off-by: Srinivas Kandagatla 
---
  drivers/phy/Kconfig |   7 +
  drivers/phy/Makefile|   1 +
  drivers/phy/phy-qcom-msm8996-pcie.c | 492 
  3 files changed, 500 insertions(+)
  create mode 100644 drivers/phy/phy-qcom-msm8996-pcie.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 19bff3a..8ad621c 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -344,6 +344,13 @@ config PHY_QCOM_APQ8064_SATA
depends on OF
select GENERIC_PHY

+config PHY_QCOM_MSM8996_PCIE
+   tristate "Qualcomm MSM8996 PCIE SerDes/PHY driver"
+   depends on ARCH_QCOM
+   depends on HAS_IOMEM
+   depends on OF
+   select GENERIC_PHY
+
  config PHY_QCOM_IPQ806X_SATA
tristate "Qualcomm IPQ806x SATA SerDes/PHY driver"
depends on ARCH_QCOM
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 90ae198..273b9c5 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -38,6 +38,7 @@ phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += 
phy-exynos5250-usb2.o
  phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2)+= phy-s5pv210-usb2.o
  obj-$(CONFIG_PHY_EXYNOS5_USBDRD)  += phy-exynos5-usbdrd.o
  obj-$(CONFIG_PHY_QCOM_APQ8064_SATA)   += phy-qcom-apq8064-sata.o
+obj-$(CONFIG_PHY_QCOM_MSM8996_PCIE)+= phy-qcom-msm8996-pcie.o
  obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
  obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
  obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
diff --git a/drivers/phy/phy-qcom-msm8996-pcie.c 
b/drivers/phy/phy-qcom-msm8996-pcie.c
new file mode 100644
index 000..f7d0c73
--- /dev/null
+++ b/drivers/phy/phy-qcom-msm8996-pcie.c
@@ -0,0 +1,492 @@
+/*
+ * Copyright (c) 2014, The 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define QSERDES_COM_BG_TIMER   0x00c
+#define QSERDES_COM_SSC_EN_CENTER  0x010
+#define QSERDES_COM_SSC_ADJ_PER1   0x014
+#define QSERDES_COM_SSC_ADJ_PER2   0x018
+#define QSERDES_COM_SSC_PER1   0x01c
+#define QSERDES_COM_SSC_PER2   0x020
+#define QSERDES_COM_SSC_STEP_SIZE1 0x024
+#define QSERDES_COM_SSC_STEP_SIZE2 0x028
+#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN0x034
+#define QSERDES_COM_CLK_ENABLE10x038
+#define QSERDES_COM_SYS_CLK_CTRL   0x03c
+#define QSERDES_COM_SYSCLK_BUF_ENABLE  0x040
+#define QSERDES_COM_PLL_IVCO   0x048
+#define QSERDES_COM_LOCK_CMP1_MODE00x04c
+#define QSERDES_COM_LOCK_CMP2_MODE00x050
+#define QSERDES_COM_LOCK_CMP3_MODE00x054
+#define QSERDES_COM_BG_TRIM0x070
+#define QSERDES_COM_CLK_EP_DIV 0x074
+#define QSERDES_COM_CP_CTRL_MODE0  0x078
+#define QSERDES_COM_PLL_RCTRL_MODE00x084
+#define QSERDES_COM_PLL_CCTRL_MODE00x090
+#define QSERDES_COM_SYSCLK_EN_SEL  0x0ac
+#define QSERDES_COM_RESETSM_CNTRL  0x0b4
+#define QSERDES_COM_RESTRIM_CTRL   0x0bc
+#define QSERDES_COM_RESCODE_DIV_NUM0x0c4
+#define QSERDES_COM_LOCK_CMP_EN0x0c8
+#define QSERDES_COM_DEC_START_MODE00x0d0
+#define QSERDES_COM_DIV_FRAC_START1_MODE0  0x0dc
+#define QSERDES_COM_DIV_FRAC_START2_MODE0  0x0e0
+#define QSERDES_COM_DIV_FRAC_START3_MODE0  0x0e4
+#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0  0x108
+#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0  0x10c
+#define QSERDES_COM_VCO_TUNE_CTRL  0x124
+#define QSERDES_COM_VCO_TUNE_MAP   0x128
+#define QSERDES_COM_VCO_TUNE1_MODE00x12c
+#define QSERDES_COM_VCO_TUNE2_MODE00x130
+#define QSERDES_COM_VCO_TUNE_TIMER10x144
+#define QSERDES_COM_VCO_TUNE_TIMER20x148
+#define QSERDES_COM_BG_CTRL0x170
+#define QSERDES_COM_CLK_SELECT 0x174
+#define QSERDES_COM_HSCLK_SEL  0x178
+#define QSERDES_COM_CORECLK_DIV0x184
+#defin