0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
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
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
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
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
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
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
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
0140 #define CRGCTRL_PCIE_ASSERT_OFFSET 0x88
0141 #define CRGCTRL_PCIE_ASSERT_BIT 0x8c000000
0142
0143 #define FNPLL_HAS_LOCKED BIT(4)
0144
0145
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
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
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
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
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
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
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
0342 hi3670_apb_phy_updatel(phy, 0, PCIE_PHY_MMC1PLL_DISABLE,
0343 SOC_PCIEPHY_MMC1PLL_CTRL16);
0344
0345
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
0378 regmap_write(phy->crgctrl, CRGPERIPH_PEREN12,
0379 IO_HP_DEBOUNCE_GT);
0380 else
0381
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;
0394 else
0395 val |= IO_OE_HARD_GT_MODE;
0396
0397 regmap_write(phy->crgctrl, CRGPERIPH_PCIECTRL0, val);
0398
0399
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
0410 val |= IO_IE_EN_HARD_BYPASS;
0411
0412
0413 val &= ~IO_HARD_CTRL_DEBOUNCE_BYPASS;
0414
0415
0416 val |= (DEBOUNCE_WAITCFG_IN | DEBOUNCE_WAITCFG_OUT);
0417
0418
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
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
0445 regmap_write(phy->crgctrl, CRGPERIPH_PERDIS12,
0446 IO_REF_SOFT_GT_MODE);
0447
0448 } else {
0449
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
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
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
0575
0576
0577
0578
0579
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
0644
0645
0646
0647
0648
0649
0650
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
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
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
0689 hi3670_apb_phy_updatel(phy, 0, PCIE_PULL_DOWN_PHY_TEST_POWERDOWN,
0690 SOC_PCIEPHY_CTRL0_ADDR);
0691
0692
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
0724 regmap_write(phy->sysctrl, SCTRL_PCIE_CMOS_OFFSET, 0);
0725
0726
0727
0728
0729
0730
0731
0732
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
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
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
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");