Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * PCIe phy driver for Kirin 970
0004  *
0005  * Copyright (C) 2017 HiSilicon Electronics Co., Ltd.
0006  *      https://www.huawei.com
0007  * Copyright (C) 2021 Huawei Technologies Co., Ltd.
0008  *      https://www.huawei.com
0009  *
0010  * Authors:
0011  *  Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
0012  *  Manivannan Sadhasivam <mani@kernel.org>
0013  *
0014  * Based on:
0015  *  https://lore.kernel.org/lkml/4c9d6581478aa966698758c0420933f5defab4dd.1612335031.git.mchehab+huawei@kernel.org/
0016  */
0017 
0018 #include <linux/bitfield.h>
0019 #include <linux/clk.h>
0020 #include <linux/gpio.h>
0021 #include <linux/kernel.h>
0022 #include <linux/mfd/syscon.h>
0023 #include <linux/module.h>
0024 #include <linux/of_gpio.h>
0025 #include <linux/phy/phy.h>
0026 #include <linux/platform_device.h>
0027 #include <linux/regmap.h>
0028 
0029 #define AXI_CLK_FREQ                207500000
0030 #define REF_CLK_FREQ                100000000
0031 
0032 /* PCIe CTRL registers */
0033 #define SOC_PCIECTRL_CTRL7_ADDR         0x01c
0034 #define SOC_PCIECTRL_CTRL12_ADDR        0x030
0035 #define SOC_PCIECTRL_CTRL20_ADDR        0x050
0036 #define SOC_PCIECTRL_CTRL21_ADDR        0x054
0037 
0038 #define PCIE_OUTPUT_PULL_BITS           GENMASK(3, 0)
0039 #define SOC_PCIECTRL_CTRL20_2P_MEM_CTRL     0x02605550
0040 #define SOC_PCIECTRL_CTRL21_DEFAULT     0x20000070
0041 #define PCIE_PULL_UP_SYS_AUX_PWR_DET        BIT(10)
0042 #define PCIE_OUTPUT_PULL_DOWN           BIT(1)
0043 
0044 /* PCIe PHY registers */
0045 #define SOC_PCIEPHY_CTRL0_ADDR          0x000
0046 #define SOC_PCIEPHY_CTRL1_ADDR          0x004
0047 #define SOC_PCIEPHY_CTRL38_ADDR         0x0098
0048 #define SOC_PCIEPHY_STATE0_ADDR         0x400
0049 
0050 #define RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1    0xc004
0051 #define SUP_DIG_LVL_OVRD_IN         0x003c
0052 #define LANEN_DIG_ASIC_TX_OVRD_IN_1     0x4008
0053 #define LANEN_DIG_ASIC_TX_OVRD_IN_2     0x400c
0054 
0055 #define PCIEPHY_RESET_BIT           BIT(17)
0056 #define PCIEPHY_PIPE_LINE0_RESET_BIT        BIT(19)
0057 #define PCIE_TXDETECT_RX_FAIL           BIT(2)
0058 #define PCIE_CLK_SOURCE             BIT(8)
0059 #define PCIE_IS_CLOCK_STABLE            BIT(19)
0060 #define PCIE_PULL_DOWN_PHY_TEST_POWERDOWN   BIT(22)
0061 #define PCIE_DEASSERT_CONTROLLER_PERST      BIT(2)
0062 
0063 #define EYEPARAM_NOCFG              0xffffffff
0064 #define EYE_PARM0_MASK              GENMASK(8, 6)
0065 #define EYE_PARM1_MASK              GENMASK(11, 8)
0066 #define EYE_PARM2_MASK              GENMASK(5, 0)
0067 #define EYE_PARM3_MASK              GENMASK(12, 7)
0068 #define EYE_PARM4_MASK              GENMASK(14, 9)
0069 #define EYE_PARM0_EN                BIT(9)
0070 #define EYE_PARM1_EN                BIT(12)
0071 #define EYE_PARM2_EN                BIT(6)
0072 #define EYE_PARM3_EN                BIT(13)
0073 #define EYE_PARM4_EN                BIT(15)
0074 
0075 /* hi3670 pciephy register */
0076 #define APB_PHY_START_ADDR          0x40000
0077 #define SOC_PCIEPHY_MMC1PLL_CTRL1       0xc04
0078 #define SOC_PCIEPHY_MMC1PLL_CTRL16      0xC40
0079 #define SOC_PCIEPHY_MMC1PLL_CTRL17      0xC44
0080 #define SOC_PCIEPHY_MMC1PLL_CTRL20      0xC50
0081 #define SOC_PCIEPHY_MMC1PLL_CTRL21      0xC54
0082 #define SOC_PCIEPHY_MMC1PLL_STAT0       0xE00
0083 
0084 #define CRGPERIPH_PEREN12           0x470
0085 #define CRGPERIPH_PERDIS12          0x474
0086 #define CRGPERIPH_PCIECTRL0         0x800
0087 
0088 #define PCIE_FNPLL_FBDIV_MASK           GENMASK(27, 16)
0089 #define PCIE_FNPLL_FRACDIV_MASK         GENMASK(23, 0)
0090 #define PCIE_FNPLL_POSTDIV1_MASK        GENMASK(10, 8)
0091 #define PCIE_FNPLL_POSTDIV2_MASK        GENMASK(14, 12)
0092 #define PCIE_FNPLL_PLL_MODE_MASK        BIT(25)
0093 
0094 #define PCIE_FNPLL_DLL_EN           BIT(27)
0095 #define PCIE_FNPLL_FBDIV            0xd0
0096 #define PCIE_FNPLL_FRACDIV          0x555555
0097 #define PCIE_FNPLL_POSTDIV1         0x5
0098 #define PCIE_FNPLL_POSTDIV2         0x4
0099 #define PCIE_FNPLL_PLL_MODE         0x0
0100 
0101 #define PCIE_PHY_MMC1PLL            0x20
0102 #define PCIE_PHY_CHOOSE_FNPLL           BIT(27)
0103 #define PCIE_PHY_MMC1PLL_DISABLE        BIT(0)
0104 #define PCIE_PHY_PCIEPL_BP          BIT(16)
0105 
0106 /* define ie,oe cfg */
0107 #define IO_OE_HARD_GT_MODE          BIT(1)
0108 #define IO_IE_EN_HARD_BYPASS            BIT(27)
0109 #define IO_OE_EN_HARD_BYPASS            BIT(11)
0110 #define IO_HARD_CTRL_DEBOUNCE_BYPASS        BIT(10)
0111 #define IO_OE_GT_MODE               BIT(8)
0112 #define DEBOUNCE_WAITCFG_IN         GENMASK(23, 20)
0113 #define DEBOUNCE_WAITCFG_OUT            GENMASK(16, 13)
0114 
0115 #define IO_HP_DEBOUNCE_GT           (BIT(12) | BIT(15))
0116 #define IO_PHYREF_SOFT_GT_MODE          BIT(14)
0117 #define IO_REF_SOFT_GT_MODE         BIT(13)
0118 #define IO_REF_HARD_GT_MODE         BIT(0)
0119 
0120 /* noc power domain */
0121 #define NOC_POWER_IDLEREQ_1         0x38c
0122 #define NOC_POWER_IDLE_1            0x394
0123 #define NOC_PW_MASK             0x10000
0124 #define NOC_PW_SET_BIT              0x1
0125 
0126 #define NUM_EYEPARAM                5
0127 
0128 /* info located in sysctrl */
0129 #define SCTRL_PCIE_CMOS_OFFSET          0x60
0130 #define SCTRL_PCIE_CMOS_BIT         0x10
0131 #define SCTRL_PCIE_ISO_OFFSET           0x44
0132 #define SCTRL_PCIE_ISO_BIT          0x30
0133 #define SCTRL_PCIE_HPCLK_OFFSET         0x190
0134 #define SCTRL_PCIE_HPCLK_BIT            0x184000
0135 #define SCTRL_PCIE_OE_OFFSET            0x14a
0136 #define PCIE_DEBOUNCE_PARAM         0xf0f400
0137 #define PCIE_OE_BYPASS              GENMASK(29, 28)
0138 
0139 /* peri_crg ctrl */
0140 #define CRGCTRL_PCIE_ASSERT_OFFSET      0x88
0141 #define CRGCTRL_PCIE_ASSERT_BIT         0x8c000000
0142 
0143 #define FNPLL_HAS_LOCKED            BIT(4)
0144 
0145 /* Time for delay */
0146 #define TIME_CMOS_MIN       100
0147 #define TIME_CMOS_MAX       105
0148 #define PIPE_CLK_STABLE_TIME    100
0149 #define PLL_CTRL_WAIT_TIME  200
0150 #define NOC_POWER_TIME      100
0151 
0152 struct hi3670_pcie_phy {
0153     struct device   *dev;
0154     void __iomem    *base;
0155     struct regmap   *apb;
0156     struct regmap   *crgctrl;
0157     struct regmap   *sysctrl;
0158     struct regmap   *pmctrl;
0159     struct clk  *apb_sys_clk;
0160     struct clk  *apb_phy_clk;
0161     struct clk  *phy_ref_clk;
0162     struct clk  *aclk;
0163     struct clk  *aux_clk;
0164     u32     eye_param[NUM_EYEPARAM];
0165 };
0166 
0167 /* Registers in PCIePHY */
0168 static inline void hi3670_apb_phy_writel(struct hi3670_pcie_phy *phy, u32 val,
0169                      u32 reg)
0170 {
0171     writel(val, phy->base + APB_PHY_START_ADDR + reg);
0172 }
0173 
0174 static inline u32 hi3670_apb_phy_readl(struct hi3670_pcie_phy *phy, u32 reg)
0175 {
0176     return readl(phy->base + APB_PHY_START_ADDR + reg);
0177 }
0178 
0179 static inline void hi3670_apb_phy_updatel(struct hi3670_pcie_phy *phy,
0180                       u32 val, u32 mask, u32 reg)
0181 {
0182     u32 regval;
0183 
0184     regval = hi3670_apb_phy_readl(phy, reg);
0185     regval &= ~mask;
0186     regval |= val;
0187     hi3670_apb_phy_writel(phy, regval, reg);
0188 }
0189 
0190 static inline void kirin_apb_natural_phy_writel(struct hi3670_pcie_phy *phy,
0191                         u32 val, u32 reg)
0192 {
0193     writel(val, phy->base + reg);
0194 }
0195 
0196 static inline u32 kirin_apb_natural_phy_readl(struct hi3670_pcie_phy *phy,
0197                           u32 reg)
0198 {
0199     return readl(phy->base + reg);
0200 }
0201 
0202 static void hi3670_pcie_phy_oe_enable(struct hi3670_pcie_phy *phy, bool enable)
0203 {
0204     u32 val;
0205 
0206     regmap_read(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, &val);
0207     val |= PCIE_DEBOUNCE_PARAM;
0208     if (enable)
0209         val &= ~PCIE_OE_BYPASS;
0210     else
0211         val |= PCIE_OE_BYPASS;
0212     regmap_write(phy->sysctrl, SCTRL_PCIE_OE_OFFSET, val);
0213 }
0214 
0215 static void hi3670_pcie_get_eyeparam(struct hi3670_pcie_phy *phy)
0216 {
0217     struct device *dev = phy->dev;
0218     struct device_node *np;
0219     int ret, i;
0220 
0221     np = dev->of_node;
0222 
0223     ret = of_property_read_u32_array(np, "hisilicon,eye-diagram-param",
0224                      phy->eye_param, NUM_EYEPARAM);
0225     if (!ret)
0226         return;
0227 
0228     /* There's no optional eye_param property. Set array to default */
0229     for (i = 0; i < NUM_EYEPARAM; i++)
0230         phy->eye_param[i] = EYEPARAM_NOCFG;
0231 }
0232 
0233 static void hi3670_pcie_set_eyeparam(struct hi3670_pcie_phy *phy)
0234 {
0235     u32 val;
0236 
0237     val = kirin_apb_natural_phy_readl(phy, RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
0238 
0239     if (phy->eye_param[1] != EYEPARAM_NOCFG) {
0240         val &= ~EYE_PARM1_MASK;
0241         val |= FIELD_PREP(EYE_PARM1_MASK, phy->eye_param[1]);
0242         val |= EYE_PARM1_EN;
0243     }
0244     kirin_apb_natural_phy_writel(phy, val,
0245                      RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1);
0246 
0247     val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_2);
0248     val &= ~(EYE_PARM2_MASK | EYE_PARM3_MASK);
0249     if (phy->eye_param[2] != EYEPARAM_NOCFG) {
0250         val |= FIELD_PREP(EYE_PARM2_MASK, phy->eye_param[2]);
0251         val |= EYE_PARM2_EN;
0252     }
0253 
0254     if (phy->eye_param[3] != EYEPARAM_NOCFG) {
0255         val |= FIELD_PREP(EYE_PARM3_MASK, phy->eye_param[3]);
0256         val |= EYE_PARM3_EN;
0257     }
0258 
0259     kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_2);
0260 
0261     val = kirin_apb_natural_phy_readl(phy, SUP_DIG_LVL_OVRD_IN);
0262     if (phy->eye_param[0] != EYEPARAM_NOCFG) {
0263         val &= ~EYE_PARM0_MASK;
0264         val |= FIELD_PREP(EYE_PARM0_MASK, phy->eye_param[0]);
0265         val |= EYE_PARM0_EN;
0266     }
0267     kirin_apb_natural_phy_writel(phy, val, SUP_DIG_LVL_OVRD_IN);
0268 
0269     val = kirin_apb_natural_phy_readl(phy, LANEN_DIG_ASIC_TX_OVRD_IN_1);
0270     if (phy->eye_param[4] != EYEPARAM_NOCFG) {
0271         val &= ~EYE_PARM4_MASK;
0272         val |= FIELD_PREP(EYE_PARM4_MASK, phy->eye_param[4]);
0273         val |= EYE_PARM4_EN;
0274     }
0275     kirin_apb_natural_phy_writel(phy, val, LANEN_DIG_ASIC_TX_OVRD_IN_1);
0276 }
0277 
0278 static void hi3670_pcie_natural_cfg(struct hi3670_pcie_phy *phy)
0279 {
0280     u32 val;
0281 
0282     /* change 2p mem_ctrl */
0283     regmap_write(phy->apb, SOC_PCIECTRL_CTRL20_ADDR,
0284              SOC_PCIECTRL_CTRL20_2P_MEM_CTRL);
0285 
0286     regmap_read(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, &val);
0287     val |= PCIE_PULL_UP_SYS_AUX_PWR_DET;
0288     regmap_write(phy->apb, SOC_PCIECTRL_CTRL7_ADDR, val);
0289 
0290     /* output, pull down */
0291     regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
0292     val &= ~PCIE_OUTPUT_PULL_BITS;
0293     val |= PCIE_OUTPUT_PULL_DOWN;
0294     regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
0295 
0296     /* Handle phy_reset and lane0_reset to HW */
0297     hi3670_apb_phy_updatel(phy, PCIEPHY_RESET_BIT,
0298                    PCIEPHY_PIPE_LINE0_RESET_BIT | PCIEPHY_RESET_BIT,
0299                    SOC_PCIEPHY_CTRL1_ADDR);
0300 
0301     /* fix chip bug: TxDetectRx fail */
0302     hi3670_apb_phy_updatel(phy, PCIE_TXDETECT_RX_FAIL, PCIE_TXDETECT_RX_FAIL,
0303                    SOC_PCIEPHY_CTRL38_ADDR);
0304 }
0305 
0306 static void hi3670_pcie_pll_init(struct hi3670_pcie_phy *phy)
0307 {
0308     hi3670_apb_phy_updatel(phy, PCIE_PHY_CHOOSE_FNPLL, PCIE_PHY_CHOOSE_FNPLL,
0309                    SOC_PCIEPHY_MMC1PLL_CTRL1);
0310 
0311     hi3670_apb_phy_updatel(phy,
0312                    FIELD_PREP(PCIE_FNPLL_FBDIV_MASK, PCIE_FNPLL_FBDIV),
0313                    PCIE_FNPLL_FBDIV_MASK,
0314                    SOC_PCIEPHY_MMC1PLL_CTRL16);
0315 
0316     hi3670_apb_phy_updatel(phy,
0317                    FIELD_PREP(PCIE_FNPLL_FRACDIV_MASK, PCIE_FNPLL_FRACDIV),
0318                    PCIE_FNPLL_FRACDIV_MASK, SOC_PCIEPHY_MMC1PLL_CTRL17);
0319 
0320     hi3670_apb_phy_updatel(phy,
0321                    PCIE_FNPLL_DLL_EN |
0322                    FIELD_PREP(PCIE_FNPLL_POSTDIV1_MASK, PCIE_FNPLL_POSTDIV1) |
0323                    FIELD_PREP(PCIE_FNPLL_POSTDIV2_MASK, PCIE_FNPLL_POSTDIV2) |
0324                    FIELD_PREP(PCIE_FNPLL_PLL_MODE_MASK, PCIE_FNPLL_PLL_MODE),
0325                    PCIE_FNPLL_POSTDIV1_MASK |
0326                    PCIE_FNPLL_POSTDIV2_MASK |
0327                    PCIE_FNPLL_PLL_MODE_MASK | PCIE_FNPLL_DLL_EN,
0328                    SOC_PCIEPHY_MMC1PLL_CTRL20);
0329 
0330     hi3670_apb_phy_writel(phy, PCIE_PHY_MMC1PLL,
0331                   SOC_PCIEPHY_MMC1PLL_CTRL21);
0332 }
0333 
0334 static int hi3670_pcie_pll_ctrl(struct hi3670_pcie_phy *phy, bool enable)
0335 {
0336     struct device *dev = phy->dev;
0337     u32 val;
0338     int time = PLL_CTRL_WAIT_TIME;
0339 
0340     if (enable) {
0341         /* pd = 0 */
0342         hi3670_apb_phy_updatel(phy, 0, PCIE_PHY_MMC1PLL_DISABLE,
0343                        SOC_PCIEPHY_MMC1PLL_CTRL16);
0344 
0345         /* choose FNPLL */
0346         val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_STAT0);
0347         while (!(val & FNPLL_HAS_LOCKED)) {
0348             if (!time) {
0349                 dev_err(dev, "wait for pll_lock timeout\n");
0350                 return -EINVAL;
0351             }
0352             time--;
0353             udelay(1);
0354             val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_MMC1PLL_STAT0);
0355         }
0356 
0357         hi3670_apb_phy_updatel(phy, 0, PCIE_PHY_PCIEPL_BP,
0358                        SOC_PCIEPHY_MMC1PLL_CTRL20);
0359 
0360     } else {
0361         hi3670_apb_phy_updatel(phy,
0362                        PCIE_PHY_MMC1PLL_DISABLE,
0363                        PCIE_PHY_MMC1PLL_DISABLE,
0364                        SOC_PCIEPHY_MMC1PLL_CTRL16);
0365 
0366         hi3670_apb_phy_updatel(phy, PCIE_PHY_PCIEPL_BP,
0367                        PCIE_PHY_PCIEPL_BP,
0368                        SOC_PCIEPHY_MMC1PLL_CTRL20);
0369     }
0370 
0371     return 0;
0372 }
0373 
0374 static void hi3670_pcie_hp_debounce_gt(struct hi3670_pcie_phy *phy, bool open)
0375 {
0376     if (open)
0377         /* gt_clk_pcie_hp/gt_clk_pcie_debounce open */
0378         regmap_write(phy->crgctrl, CRGPERIPH_PEREN12,
0379                  IO_HP_DEBOUNCE_GT);
0380     else
0381         /* gt_clk_pcie_hp/gt_clk_pcie_debounce close */
0382         regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
0383                  IO_HP_DEBOUNCE_GT);
0384 }
0385 
0386 static void hi3670_pcie_phyref_gt(struct hi3670_pcie_phy *phy, bool open)
0387 {
0388     unsigned int val;
0389 
0390     regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
0391 
0392     if (open)
0393         val &= ~IO_OE_HARD_GT_MODE; /* enable hard gt mode */
0394     else
0395         val |= IO_OE_HARD_GT_MODE; /* disable hard gt mode */
0396 
0397     regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
0398 
0399     /* disable soft gt mode */
0400     regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12, IO_PHYREF_SOFT_GT_MODE);
0401 }
0402 
0403 static void hi3670_pcie_oe_ctrl(struct hi3670_pcie_phy *phy, bool en_flag)
0404 {
0405     unsigned int val;
0406 
0407     regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
0408 
0409     /* set ie cfg */
0410     val |= IO_IE_EN_HARD_BYPASS;
0411 
0412     /* set oe cfg */
0413     val &= ~IO_HARD_CTRL_DEBOUNCE_BYPASS;
0414 
0415     /* set phy_debounce in&out time */
0416     val |= (DEBOUNCE_WAITCFG_IN | DEBOUNCE_WAITCFG_OUT);
0417 
0418     /* select oe_gt_mode */
0419     val |= IO_OE_GT_MODE;
0420 
0421     if (en_flag)
0422         val &= ~IO_OE_EN_HARD_BYPASS;
0423     else
0424         val |= IO_OE_EN_HARD_BYPASS;
0425 
0426     regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
0427 }
0428 
0429 static void hi3670_pcie_ioref_gt(struct hi3670_pcie_phy *phy, bool open)
0430 {
0431     unsigned int val;
0432 
0433     if (open) {
0434         regmap_write(phy->apb, SOC_PCIECTRL_CTRL21_ADDR,
0435                  SOC_PCIECTRL_CTRL21_DEFAULT);
0436 
0437         hi3670_pcie_oe_ctrl(phy, true);
0438 
0439         /* en hard gt mode */
0440         regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
0441         val &= ~IO_REF_HARD_GT_MODE;
0442         regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
0443 
0444         /* disable soft gt mode */
0445         regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
0446                  IO_REF_SOFT_GT_MODE);
0447 
0448     } else {
0449         /* disable hard gt mode */
0450         regmap_read(phy->crgctrl, CRGPERIPH_PCIECTRL0, &val);
0451         val |= IO_REF_HARD_GT_MODE;
0452         regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
0453 
0454         /* disable soft gt mode */
0455         regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
0456                  IO_REF_SOFT_GT_MODE);
0457 
0458         hi3670_pcie_oe_ctrl(phy, false);
0459     }
0460 }
0461 
0462 static int hi3670_pcie_allclk_ctrl(struct hi3670_pcie_phy *phy, bool clk_on)
0463 {
0464     struct device *dev = phy->dev;
0465     int ret = 0;
0466 
0467     if (!clk_on)
0468         goto close_clocks;
0469 
0470     /* choose 100MHz clk src: Bit[8]==1 pad, Bit[8]==0 pll */
0471     hi3670_apb_phy_updatel(phy, 0, PCIE_CLK_SOURCE,
0472                    SOC_PCIEPHY_CTRL1_ADDR);
0473 
0474     hi3670_pcie_pll_init(phy);
0475 
0476     ret = hi3670_pcie_pll_ctrl(phy, true);
0477     if (ret) {
0478         dev_err(dev, "Failed to enable pll\n");
0479         return -EINVAL;
0480     }
0481     hi3670_pcie_hp_debounce_gt(phy, true);
0482     hi3670_pcie_phyref_gt(phy, true);
0483     hi3670_pcie_ioref_gt(phy, true);
0484 
0485     ret = clk_set_rate(phy->aclk, AXI_CLK_FREQ);
0486     if (ret) {
0487         dev_err(dev, "Failed to set rate\n");
0488         goto close_clocks;
0489     }
0490 
0491     return 0;
0492 
0493 close_clocks:
0494     hi3670_pcie_ioref_gt(phy, false);
0495     hi3670_pcie_phyref_gt(phy, false);
0496     hi3670_pcie_hp_debounce_gt(phy, false);
0497 
0498     hi3670_pcie_pll_ctrl(phy, false);
0499 
0500     return ret;
0501 }
0502 
0503 static bool is_pipe_clk_stable(struct hi3670_pcie_phy *phy)
0504 {
0505     struct device *dev = phy->dev;
0506     u32 val;
0507     u32 time = PIPE_CLK_STABLE_TIME;
0508     u32 pipe_clk_stable = PCIE_IS_CLOCK_STABLE;
0509 
0510     val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
0511     while (val & pipe_clk_stable) {
0512         mdelay(1);
0513         if (!time) {
0514             dev_err(dev, "PIPE clk is not stable\n");
0515             return false;
0516         }
0517         time--;
0518         val = hi3670_apb_phy_readl(phy, SOC_PCIEPHY_STATE0_ADDR);
0519     }
0520 
0521     return true;
0522 }
0523 
0524 static int hi3670_pcie_noc_power(struct hi3670_pcie_phy *phy, bool enable)
0525 {
0526     struct device *dev = phy->dev;
0527     u32 time = NOC_POWER_TIME;
0528     unsigned int val = NOC_PW_MASK;
0529     int rst;
0530 
0531     if (enable)
0532         val = NOC_PW_MASK | NOC_PW_SET_BIT;
0533     else
0534         val = NOC_PW_MASK;
0535     rst = enable ? 1 : 0;
0536 
0537     regmap_write(phy->pmctrl, NOC_POWER_IDLEREQ_1, val);
0538 
0539     time = NOC_POWER_TIME;
0540     regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
0541     while ((val & NOC_PW_SET_BIT) != rst) {
0542         udelay(10);
0543         if (!time) {
0544             dev_err(dev, "Failed to reverse noc power-status\n");
0545             return -EINVAL;
0546         }
0547         time--;
0548         regmap_read(phy->pmctrl, NOC_POWER_IDLE_1, &val);
0549     }
0550 
0551     return 0;
0552 }
0553 
0554 static int hi3670_pcie_get_resources_from_pcie(struct hi3670_pcie_phy *phy)
0555 {
0556     struct device_node *pcie_port;
0557     struct device *dev = phy->dev;
0558     struct device *pcie_dev;
0559 
0560     pcie_port = of_get_child_by_name(dev->parent->of_node, "pcie");
0561     if (!pcie_port) {
0562         dev_err(dev, "no pcie node found in %s\n",
0563             dev->parent->of_node->full_name);
0564         return -ENODEV;
0565     }
0566 
0567     pcie_dev = bus_find_device_by_of_node(&platform_bus_type, pcie_port);
0568     if (!pcie_dev) {
0569         dev_err(dev, "Didn't find pcie device\n");
0570         return -ENODEV;
0571     }
0572 
0573     /*
0574      * We might just use NULL instead of the APB name, as the
0575      * pcie-kirin currently registers directly just one regmap (although
0576      * the DWC driver register other regmaps).
0577      *
0578      * Yet, it sounds safer to warrant that it will be accessing the
0579      * right regmap. So, let's use the named version.
0580      */
0581     phy->apb = dev_get_regmap(pcie_dev, "kirin_pcie_apb");
0582     if (!phy->apb) {
0583         dev_err(dev, "Failed to get APB regmap\n");
0584         return -ENODEV;
0585     }
0586 
0587     return 0;
0588 }
0589 
0590 static int kirin_pcie_clk_ctrl(struct hi3670_pcie_phy *phy, bool enable)
0591 {
0592     int ret = 0;
0593 
0594     if (!enable)
0595         goto close_clk;
0596 
0597     ret = clk_set_rate(phy->phy_ref_clk, REF_CLK_FREQ);
0598     if (ret)
0599         return ret;
0600 
0601     ret = clk_prepare_enable(phy->phy_ref_clk);
0602     if (ret)
0603         return ret;
0604 
0605     ret = clk_prepare_enable(phy->apb_sys_clk);
0606     if (ret)
0607         goto apb_sys_fail;
0608 
0609     ret = clk_prepare_enable(phy->apb_phy_clk);
0610     if (ret)
0611         goto apb_phy_fail;
0612 
0613     ret = clk_prepare_enable(phy->aclk);
0614     if (ret)
0615         goto aclk_fail;
0616 
0617     ret = clk_prepare_enable(phy->aux_clk);
0618     if (ret)
0619         goto aux_clk_fail;
0620 
0621     return 0;
0622 
0623 close_clk:
0624     clk_disable_unprepare(phy->aux_clk);
0625 aux_clk_fail:
0626     clk_disable_unprepare(phy->aclk);
0627 aclk_fail:
0628     clk_disable_unprepare(phy->apb_phy_clk);
0629 apb_phy_fail:
0630     clk_disable_unprepare(phy->apb_sys_clk);
0631 apb_sys_fail:
0632     clk_disable_unprepare(phy->phy_ref_clk);
0633 
0634     return ret;
0635 }
0636 
0637 static int hi3670_pcie_phy_init(struct phy *generic_phy)
0638 {
0639     struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
0640     int ret;
0641 
0642     /*
0643      * The code under hi3670_pcie_get_resources_from_pcie() need to
0644      * access the reset-gpios and the APB registers, both from the
0645      * pcie-kirin driver.
0646      *
0647      * The APB is obtained via the pcie driver's regmap
0648      * Such kind of resource can only be obtained during the PCIe
0649      * power_on sequence, as the code inside pcie-kirin needs to
0650      * be already probed, as it needs to register the APB regmap.
0651      */
0652 
0653     ret = hi3670_pcie_get_resources_from_pcie(phy);
0654     if (ret)
0655         return ret;
0656 
0657     return 0;
0658 }
0659 
0660 static int hi3670_pcie_phy_power_on(struct phy *generic_phy)
0661 {
0662     struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
0663     int val, ret;
0664 
0665     /* Power supply for Host */
0666     regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, SCTRL_PCIE_CMOS_BIT);
0667     usleep_range(TIME_CMOS_MIN, TIME_CMOS_MAX);
0668 
0669     hi3670_pcie_phy_oe_enable(phy, true);
0670 
0671     ret = kirin_pcie_clk_ctrl(phy, true);
0672     if (ret)
0673         return ret;
0674 
0675     /* ISO disable, PCIeCtrl, PHY assert and clk gate clear */
0676     regmap_write(phy->sysctrl, SCTRL_PCIE_ISO_OFFSET, SCTRL_PCIE_ISO_BIT);
0677     regmap_write(phy->crgctrl, CRGCTRL_PCIE_ASSERT_OFFSET,
0678              CRGCTRL_PCIE_ASSERT_BIT);
0679     regmap_write(phy->sysctrl, SCTRL_PCIE_HPCLK_OFFSET,
0680              SCTRL_PCIE_HPCLK_BIT);
0681 
0682     hi3670_pcie_natural_cfg(phy);
0683 
0684     ret = hi3670_pcie_allclk_ctrl(phy, true);
0685     if (ret)
0686         goto disable_clks;
0687 
0688     /* pull down phy_test_powerdown signal */
0689     hi3670_apb_phy_updatel(phy, 0, PCIE_PULL_DOWN_PHY_TEST_POWERDOWN,
0690                    SOC_PCIEPHY_CTRL0_ADDR);
0691 
0692     /* deassert controller perst_n */
0693     regmap_read(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, &val);
0694     val |= PCIE_DEASSERT_CONTROLLER_PERST;
0695     regmap_write(phy->apb, SOC_PCIECTRL_CTRL12_ADDR, val);
0696     udelay(10);
0697 
0698     ret = is_pipe_clk_stable(phy);
0699     if (!ret)
0700         goto disable_clks;
0701 
0702     hi3670_pcie_set_eyeparam(phy);
0703 
0704     ret = hi3670_pcie_noc_power(phy, false);
0705     if (ret)
0706         goto disable_clks;
0707 
0708     return 0;
0709 
0710 disable_clks:
0711     kirin_pcie_clk_ctrl(phy, false);
0712     return ret;
0713 }
0714 
0715 static int hi3670_pcie_phy_power_off(struct phy *generic_phy)
0716 {
0717     struct hi3670_pcie_phy *phy = phy_get_drvdata(generic_phy);
0718 
0719     hi3670_pcie_phy_oe_enable(phy, false);
0720 
0721     hi3670_pcie_allclk_ctrl(phy, false);
0722 
0723     /* Drop power supply for Host */
0724     regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, 0);
0725 
0726     /*
0727      * FIXME: The enabled clocks should be disabled here by calling
0728      * kirin_pcie_clk_ctrl(phy, false);
0729      * However, some clocks used at Kirin 970 should be marked as
0730      * CLK_IS_CRITICAL at clk-hi3670 driver, as powering such clocks off
0731      * cause an Asynchronous SError interrupt, which produces panic().
0732      * While clk-hi3670 is not fixed, we cannot risk disabling clocks here.
0733      */
0734 
0735     return 0;
0736 }
0737 
0738 static const struct phy_ops hi3670_phy_ops = {
0739     .init       = hi3670_pcie_phy_init,
0740     .power_on   = hi3670_pcie_phy_power_on,
0741     .power_off  = hi3670_pcie_phy_power_off,
0742     .owner      = THIS_MODULE,
0743 };
0744 
0745 static int hi3670_pcie_phy_get_resources(struct hi3670_pcie_phy *phy,
0746                      struct platform_device *pdev)
0747 {
0748     struct device *dev = &pdev->dev;
0749 
0750     /* syscon */
0751     phy->crgctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-crgctrl");
0752     if (IS_ERR(phy->crgctrl))
0753         return PTR_ERR(phy->crgctrl);
0754 
0755     phy->sysctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-sctrl");
0756     if (IS_ERR(phy->sysctrl))
0757         return PTR_ERR(phy->sysctrl);
0758 
0759     phy->pmctrl = syscon_regmap_lookup_by_compatible("hisilicon,hi3670-pmctrl");
0760     if (IS_ERR(phy->pmctrl))
0761         return PTR_ERR(phy->pmctrl);
0762 
0763     /* clocks */
0764     phy->phy_ref_clk = devm_clk_get(dev, "phy_ref");
0765     if (IS_ERR(phy->phy_ref_clk))
0766         return PTR_ERR(phy->phy_ref_clk);
0767 
0768     phy->aux_clk = devm_clk_get(dev, "aux");
0769     if (IS_ERR(phy->aux_clk))
0770         return PTR_ERR(phy->aux_clk);
0771 
0772     phy->apb_phy_clk = devm_clk_get(dev, "apb_phy");
0773     if (IS_ERR(phy->apb_phy_clk))
0774         return PTR_ERR(phy->apb_phy_clk);
0775 
0776     phy->apb_sys_clk = devm_clk_get(dev, "apb_sys");
0777     if (IS_ERR(phy->apb_sys_clk))
0778         return PTR_ERR(phy->apb_sys_clk);
0779 
0780     phy->aclk = devm_clk_get(dev, "aclk");
0781     if (IS_ERR(phy->aclk))
0782         return PTR_ERR(phy->aclk);
0783 
0784     /* registers */
0785     phy->base = devm_platform_ioremap_resource(pdev, 0);
0786     if (IS_ERR(phy->base))
0787         return PTR_ERR(phy->base);
0788 
0789     hi3670_pcie_get_eyeparam(phy);
0790 
0791     return 0;
0792 }
0793 
0794 static int hi3670_pcie_phy_probe(struct platform_device *pdev)
0795 {
0796     struct phy_provider *phy_provider;
0797     struct device *dev = &pdev->dev;
0798     struct hi3670_pcie_phy *phy;
0799     struct phy *generic_phy;
0800     int ret;
0801 
0802     phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
0803     if (!phy)
0804         return -ENOMEM;
0805 
0806     phy->dev = dev;
0807 
0808     ret = hi3670_pcie_phy_get_resources(phy, pdev);
0809     if (ret)
0810         return ret;
0811 
0812     generic_phy = devm_phy_create(dev, dev->of_node, &hi3670_phy_ops);
0813     if (IS_ERR(generic_phy)) {
0814         dev_err(dev, "failed to create PHY\n");
0815         return PTR_ERR(generic_phy);
0816     }
0817 
0818     phy_set_drvdata(generic_phy, phy);
0819     phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
0820 
0821     return PTR_ERR_OR_ZERO(phy_provider);
0822 }
0823 
0824 static const struct of_device_id hi3670_pcie_phy_match[] = {
0825     {
0826         .compatible = "hisilicon,hi970-pcie-phy",
0827     },
0828     {},
0829 };
0830 
0831 static struct platform_driver hi3670_pcie_phy_driver = {
0832     .probe  = hi3670_pcie_phy_probe,
0833     .driver = {
0834         .of_match_table = hi3670_pcie_phy_match,
0835         .name       = "hi3670_pcie_phy",
0836         .suppress_bind_attrs = true,
0837     }
0838 };
0839 builtin_platform_driver(hi3670_pcie_phy_driver);
0840 
0841 MODULE_DEVICE_TABLE(of, hi3670_pcie_phy_match);
0842 MODULE_DESCRIPTION("PCIe phy driver for Kirin 970");
0843 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>");
0844 MODULE_AUTHOR("Manivannan Sadhasivam <mani@kernel.org>");
0845 MODULE_LICENSE("GPL v2");