cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

phy-hi3670-usb3.c (15693B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Phy provider for USB 3.1 controller on HiSilicon Kirin970 platform
      4 *
      5 * Copyright (C) 2017-2020 Hilisicon Electronics Co., Ltd.
      6 *		http://www.huawei.com
      7 *
      8 * Authors: Yu Chen <chenyu56@huawei.com>
      9 */
     10
     11#include <linux/bitfield.h>
     12#include <linux/clk.h>
     13#include <linux/kernel.h>
     14#include <linux/mfd/syscon.h>
     15#include <linux/module.h>
     16#include <linux/phy/phy.h>
     17#include <linux/platform_device.h>
     18#include <linux/regmap.h>
     19
     20#define SCTRL_SCDEEPSLEEPED		(0x0)
     21#define USB_CLK_SELECTED		BIT(20)
     22
     23#define PERI_CRG_PEREN0			(0x00)
     24#define PERI_CRG_PERDIS0		(0x04)
     25#define PERI_CRG_PEREN4			(0x40)
     26#define PERI_CRG_PERDIS4		(0x44)
     27#define PERI_CRG_PERRSTEN4		(0x90)
     28#define PERI_CRG_PERRSTDIS4		(0x94)
     29#define PERI_CRG_ISODIS			(0x148)
     30#define PERI_CRG_PEREN6			(0x410)
     31#define PERI_CRG_PERDIS6		(0x414)
     32
     33#define USB_REFCLK_ISO_EN		BIT(25)
     34
     35#define GT_CLK_USB2PHY_REF		BIT(19)
     36
     37#define PCTRL_PERI_CTRL3		(0x10)
     38#define PCTRL_PERI_CTRL3_MSK_START	(16)
     39#define USB_TCXO_EN			BIT(1)
     40
     41#define PCTRL_PERI_CTRL24		(0x64)
     42#define SC_CLK_USB3PHY_3MUX1_SEL	BIT(25)
     43
     44#define USB3OTG_CTRL0			(0x00)
     45#define USB3OTG_CTRL3			(0x0c)
     46#define USB3OTG_CTRL4			(0x10)
     47#define USB3OTG_CTRL5			(0x14)
     48#define USB3OTG_CTRL7			(0x1c)
     49#define USB_MISC_CFG50			(0x50)
     50#define USB_MISC_CFG54			(0x54)
     51#define USB_MISC_CFG58			(0x58)
     52#define USB_MISC_CFG5C			(0x5c)
     53#define USB_MISC_CFGA0			(0xa0)
     54#define TCA_CLK_RST			(0x200)
     55#define TCA_INTR_EN			(0x204)
     56#define TCA_INTR_STS			(0x208)
     57#define TCA_GCFG			(0x210)
     58#define TCA_TCPC			(0x214)
     59#define TCA_SYSMODE_CFG			(0x218)
     60#define TCA_VBUS_CTRL			(0x240)
     61
     62#define CTRL0_USB3_VBUSVLD		BIT(7)
     63#define CTRL0_USB3_VBUSVLD_SEL		BIT(6)
     64
     65#define CTRL3_USB2_VBUSVLDEXT0		BIT(6)
     66#define CTRL3_USB2_VBUSVLDEXTSEL0	BIT(5)
     67
     68#define CTRL5_USB2_SIDDQ		BIT(0)
     69
     70#define CTRL7_USB2_REFCLKSEL_MASK	GENMASK(4, 3)
     71#define CTRL7_USB2_REFCLKSEL_ABB	(BIT(4) | BIT(3))
     72#define CTRL7_USB2_REFCLKSEL_PAD	BIT(4)
     73
     74#define CFG50_USB3_PHY_TEST_POWERDOWN	BIT(23)
     75
     76#define CFG54_USB31PHY_CR_ADDR_MASK	GENMASK(31, 16)
     77
     78#define CFG54_USB3PHY_REF_USE_PAD	BIT(12)
     79#define CFG54_PHY0_PMA_PWR_STABLE	BIT(11)
     80#define CFG54_PHY0_PCS_PWR_STABLE	BIT(9)
     81#define CFG54_USB31PHY_CR_ACK		BIT(7)
     82#define CFG54_USB31PHY_CR_WR_EN		BIT(5)
     83#define CFG54_USB31PHY_CR_SEL		BIT(4)
     84#define CFG54_USB31PHY_CR_RD_EN		BIT(3)
     85#define CFG54_USB31PHY_CR_CLK		BIT(2)
     86#define CFG54_USB3_PHY0_ANA_PWR_EN	BIT(1)
     87
     88#define CFG58_USB31PHY_CR_DATA_MASK     GENMASK(31, 16)
     89
     90#define CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN	BIT(1)
     91
     92#define CFGA0_VAUX_RESET		BIT(9)
     93#define CFGA0_USB31C_RESET		BIT(8)
     94#define CFGA0_USB2PHY_REFCLK_SELECT	BIT(4)
     95#define CFGA0_USB3PHY_RESET		BIT(1)
     96#define CFGA0_USB2PHY_POR		BIT(0)
     97
     98#define INTR_EN_XA_TIMEOUT_EVT_EN	BIT(1)
     99#define INTR_EN_XA_ACK_EVT_EN		BIT(0)
    100
    101#define CLK_RST_TCA_REF_CLK_EN		BIT(1)
    102#define CLK_RST_SUSPEND_CLK_EN		BIT(0)
    103
    104#define GCFG_ROLE_HSTDEV		BIT(4)
    105#define GCFG_OP_MODE			GENMASK(1, 0)
    106#define GCFG_OP_MODE_CTRL_SYNC_MODE	BIT(0)
    107
    108#define TCPC_VALID			BIT(4)
    109#define TCPC_LOW_POWER_EN		BIT(3)
    110#define TCPC_MUX_CONTROL_MASK		GENMASK(1, 0)
    111#define TCPC_MUX_CONTROL_USB31		BIT(0)
    112
    113#define SYSMODE_CFG_TYPEC_DISABLE	BIT(3)
    114
    115#define VBUS_CTRL_POWERPRESENT_OVERRD	GENMASK(3, 2)
    116#define VBUS_CTRL_VBUSVALID_OVERRD	GENMASK(1, 0)
    117
    118#define KIRIN970_USB_DEFAULT_PHY_PARAM	(0xfdfee4)
    119#define KIRIN970_USB_DEFAULT_PHY_VBOOST	(0x5)
    120
    121#define TX_VBOOST_LVL_REG		(0xf)
    122#define TX_VBOOST_LVL_START		(6)
    123#define TX_VBOOST_LVL_ENABLE		BIT(9)
    124
    125struct hi3670_priv {
    126	struct device *dev;
    127	struct regmap *peri_crg;
    128	struct regmap *pctrl;
    129	struct regmap *sctrl;
    130	struct regmap *usb31misc;
    131
    132	u32 eye_diagram_param;
    133	u32 tx_vboost_lvl;
    134
    135	u32 peri_crg_offset;
    136	u32 pctrl_offset;
    137	u32 usb31misc_offset;
    138};
    139
    140static int hi3670_phy_cr_clk(struct regmap *usb31misc)
    141{
    142	int ret;
    143
    144	/* Clock up */
    145	ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
    146				 CFG54_USB31PHY_CR_CLK, CFG54_USB31PHY_CR_CLK);
    147	if (ret)
    148		return ret;
    149
    150	/* Clock down */
    151	return regmap_update_bits(usb31misc, USB_MISC_CFG54,
    152				  CFG54_USB31PHY_CR_CLK, 0);
    153}
    154
    155static int hi3670_phy_cr_set_sel(struct regmap *usb31misc)
    156{
    157	return regmap_update_bits(usb31misc, USB_MISC_CFG54,
    158				  CFG54_USB31PHY_CR_SEL, CFG54_USB31PHY_CR_SEL);
    159}
    160
    161static int hi3670_phy_cr_start(struct regmap *usb31misc, int direction)
    162{
    163	int ret, reg;
    164
    165	if (direction)
    166		reg = CFG54_USB31PHY_CR_WR_EN;
    167	else
    168		reg = CFG54_USB31PHY_CR_RD_EN;
    169
    170	ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, reg, reg);
    171
    172	if (ret)
    173		return ret;
    174
    175	ret = hi3670_phy_cr_clk(usb31misc);
    176	if (ret)
    177		return ret;
    178
    179	return regmap_update_bits(usb31misc, USB_MISC_CFG54,
    180				  CFG54_USB31PHY_CR_RD_EN | CFG54_USB31PHY_CR_WR_EN, 0);
    181}
    182
    183static int hi3670_phy_cr_wait_ack(struct regmap *usb31misc)
    184{
    185	u32 reg;
    186	int retry = 10;
    187	int ret;
    188
    189	while (retry-- > 0) {
    190		ret = regmap_read(usb31misc, USB_MISC_CFG54, &reg);
    191		if (ret)
    192			return ret;
    193		if ((reg & CFG54_USB31PHY_CR_ACK) == CFG54_USB31PHY_CR_ACK)
    194			return 0;
    195
    196		ret = hi3670_phy_cr_clk(usb31misc);
    197		if (ret)
    198			return ret;
    199
    200		usleep_range(10, 20);
    201	}
    202
    203	return -ETIMEDOUT;
    204}
    205
    206static int hi3670_phy_cr_set_addr(struct regmap *usb31misc, u32 addr)
    207{
    208	u32 reg;
    209	int ret;
    210
    211	ret = regmap_read(usb31misc, USB_MISC_CFG54, &reg);
    212	if (ret)
    213		return ret;
    214
    215	reg = FIELD_PREP(CFG54_USB31PHY_CR_ADDR_MASK, addr);
    216
    217	return regmap_update_bits(usb31misc, USB_MISC_CFG54,
    218				  CFG54_USB31PHY_CR_ADDR_MASK, reg);
    219}
    220
    221static int hi3670_phy_cr_read(struct regmap *usb31misc, u32 addr, u32 *val)
    222{
    223	int reg, i, ret;
    224
    225	for (i = 0; i < 100; i++) {
    226		ret = hi3670_phy_cr_clk(usb31misc);
    227		if (ret)
    228			return ret;
    229	}
    230
    231	ret = hi3670_phy_cr_set_sel(usb31misc);
    232	if (ret)
    233		return ret;
    234
    235	ret = hi3670_phy_cr_set_addr(usb31misc, addr);
    236	if (ret)
    237		return ret;
    238
    239	ret = hi3670_phy_cr_start(usb31misc, 0);
    240	if (ret)
    241		return ret;
    242
    243	ret = hi3670_phy_cr_wait_ack(usb31misc);
    244	if (ret)
    245		return ret;
    246
    247	ret = regmap_read(usb31misc, USB_MISC_CFG58, &reg);
    248	if (ret)
    249		return ret;
    250
    251	*val = FIELD_GET(CFG58_USB31PHY_CR_DATA_MASK, reg);
    252
    253	return 0;
    254}
    255
    256static int hi3670_phy_cr_write(struct regmap *usb31misc, u32 addr, u32 val)
    257{
    258	int i;
    259	int ret;
    260
    261	for (i = 0; i < 100; i++) {
    262		ret = hi3670_phy_cr_clk(usb31misc);
    263		if (ret)
    264			return ret;
    265	}
    266
    267	ret = hi3670_phy_cr_set_sel(usb31misc);
    268	if (ret)
    269		return ret;
    270
    271	ret = hi3670_phy_cr_set_addr(usb31misc, addr);
    272	if (ret)
    273		return ret;
    274
    275	ret = regmap_write(usb31misc, USB_MISC_CFG58,
    276			   FIELD_PREP(CFG58_USB31PHY_CR_DATA_MASK, val));
    277	if (ret)
    278		return ret;
    279
    280	ret = hi3670_phy_cr_start(usb31misc, 1);
    281	if (ret)
    282		return ret;
    283
    284	return hi3670_phy_cr_wait_ack(usb31misc);
    285}
    286
    287static int hi3670_phy_set_params(struct hi3670_priv *priv)
    288{
    289	u32 reg;
    290	int ret;
    291	int retry = 3;
    292
    293	ret = regmap_write(priv->usb31misc, USB3OTG_CTRL4,
    294			   priv->eye_diagram_param);
    295	if (ret) {
    296		dev_err(priv->dev, "set USB3OTG_CTRL4 failed\n");
    297		return ret;
    298	}
    299
    300	while (retry-- > 0) {
    301		ret = hi3670_phy_cr_read(priv->usb31misc,
    302					 TX_VBOOST_LVL_REG, &reg);
    303		if (!ret)
    304			break;
    305
    306		if (ret != -ETIMEDOUT) {
    307			dev_err(priv->dev, "read TX_VBOOST_LVL_REG failed\n");
    308			return ret;
    309		}
    310	}
    311	if (ret)
    312		return ret;
    313
    314	reg |= (TX_VBOOST_LVL_ENABLE | (priv->tx_vboost_lvl << TX_VBOOST_LVL_START));
    315	ret = hi3670_phy_cr_write(priv->usb31misc, TX_VBOOST_LVL_REG, reg);
    316	if (ret)
    317		dev_err(priv->dev, "write TX_VBOOST_LVL_REG failed\n");
    318
    319	return ret;
    320}
    321
    322static bool hi3670_is_abbclk_selected(struct hi3670_priv *priv)
    323{
    324	u32 reg;
    325
    326	if (!priv->sctrl) {
    327		dev_err(priv->dev, "priv->sctrl is null!\n");
    328		return false;
    329	}
    330
    331	if (regmap_read(priv->sctrl, SCTRL_SCDEEPSLEEPED, &reg)) {
    332		dev_err(priv->dev, "SCTRL_SCDEEPSLEEPED read failed!\n");
    333		return false;
    334	}
    335
    336	if ((reg & USB_CLK_SELECTED) == 0)
    337		return false;
    338
    339	return true;
    340}
    341
    342static int hi3670_config_phy_clock(struct hi3670_priv *priv)
    343{
    344	u32 val, mask;
    345	int ret;
    346
    347	if (!hi3670_is_abbclk_selected(priv)) {
    348		/* usb refclk iso disable */
    349		ret = regmap_write(priv->peri_crg, PERI_CRG_ISODIS,
    350				   USB_REFCLK_ISO_EN);
    351		if (ret)
    352			goto out;
    353
    354		/* enable usb_tcxo_en */
    355		ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
    356				   USB_TCXO_EN |
    357				   (USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START));
    358
    359		/* select usbphy clk from abb */
    360		mask = SC_CLK_USB3PHY_3MUX1_SEL;
    361		ret = regmap_update_bits(priv->pctrl,
    362					 PCTRL_PERI_CTRL24, mask, 0);
    363		if (ret)
    364			goto out;
    365
    366		ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
    367					 CFGA0_USB2PHY_REFCLK_SELECT, 0);
    368		if (ret)
    369			goto out;
    370
    371		ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
    372		if (ret)
    373			goto out;
    374		val &= ~CTRL7_USB2_REFCLKSEL_MASK;
    375		val |= CTRL7_USB2_REFCLKSEL_ABB;
    376		ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
    377		if (ret)
    378			goto out;
    379
    380		return 0;
    381	}
    382
    383	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
    384				 CFG54_USB3PHY_REF_USE_PAD,
    385				 CFG54_USB3PHY_REF_USE_PAD);
    386	if (ret)
    387		goto out;
    388
    389	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
    390				 CFGA0_USB2PHY_REFCLK_SELECT,
    391				 CFGA0_USB2PHY_REFCLK_SELECT);
    392	if (ret)
    393		goto out;
    394
    395	ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
    396	if (ret)
    397		goto out;
    398	val &= ~CTRL7_USB2_REFCLKSEL_MASK;
    399	val |= CTRL7_USB2_REFCLKSEL_PAD;
    400	ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
    401	if (ret)
    402		goto out;
    403
    404	ret = regmap_write(priv->peri_crg,
    405			   PERI_CRG_PEREN6, GT_CLK_USB2PHY_REF);
    406	if (ret)
    407		goto out;
    408
    409	return 0;
    410out:
    411	dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
    412	return ret;
    413}
    414
    415static int hi3670_config_tca(struct hi3670_priv *priv)
    416{
    417	u32 val, mask;
    418	int ret;
    419
    420	ret = regmap_write(priv->usb31misc, TCA_INTR_STS, 0xffff);
    421	if (ret)
    422		goto out;
    423
    424	ret = regmap_write(priv->usb31misc, TCA_INTR_EN,
    425			   INTR_EN_XA_TIMEOUT_EVT_EN | INTR_EN_XA_ACK_EVT_EN);
    426	if (ret)
    427		goto out;
    428
    429	mask = CLK_RST_TCA_REF_CLK_EN | CLK_RST_SUSPEND_CLK_EN;
    430	ret = regmap_update_bits(priv->usb31misc, TCA_CLK_RST, mask, 0);
    431	if (ret)
    432		goto out;
    433
    434	ret = regmap_update_bits(priv->usb31misc, TCA_GCFG,
    435				 GCFG_ROLE_HSTDEV | GCFG_OP_MODE,
    436				 GCFG_ROLE_HSTDEV | GCFG_OP_MODE_CTRL_SYNC_MODE);
    437	if (ret)
    438		goto out;
    439
    440	ret = regmap_update_bits(priv->usb31misc, TCA_SYSMODE_CFG,
    441				 SYSMODE_CFG_TYPEC_DISABLE, 0);
    442	if (ret)
    443		goto out;
    444
    445	ret = regmap_read(priv->usb31misc, TCA_TCPC, &val);
    446	if (ret)
    447		goto out;
    448	val &= ~(TCPC_VALID | TCPC_LOW_POWER_EN | TCPC_MUX_CONTROL_MASK);
    449	val |= (TCPC_VALID | TCPC_MUX_CONTROL_USB31);
    450	ret = regmap_write(priv->usb31misc, TCA_TCPC, val);
    451	if (ret)
    452		goto out;
    453
    454	ret = regmap_write(priv->usb31misc, TCA_VBUS_CTRL,
    455			   VBUS_CTRL_POWERPRESENT_OVERRD | VBUS_CTRL_VBUSVALID_OVERRD);
    456	if (ret)
    457		goto out;
    458
    459	return 0;
    460out:
    461	dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
    462	return ret;
    463}
    464
    465static int hi3670_phy_init(struct phy *phy)
    466{
    467	struct hi3670_priv *priv = phy_get_drvdata(phy);
    468	u32 val;
    469	int ret;
    470
    471	/* assert controller */
    472	val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET |
    473	      CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
    474	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, 0);
    475	if (ret)
    476		goto out;
    477
    478	ret = hi3670_config_phy_clock(priv);
    479	if (ret)
    480		goto out;
    481
    482	/* Exit from IDDQ mode */
    483	ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL5,
    484				 CTRL5_USB2_SIDDQ, 0);
    485	if (ret)
    486		goto out;
    487
    488	/* Release USB31 PHY out of TestPowerDown mode */
    489	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG50,
    490				 CFG50_USB3_PHY_TEST_POWERDOWN, 0);
    491	if (ret)
    492		goto out;
    493
    494	/* Deassert phy */
    495	val = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
    496	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
    497	if (ret)
    498		goto out;
    499
    500	usleep_range(100, 120);
    501
    502	/* Tell the PHY power is stable */
    503	val = CFG54_USB3_PHY0_ANA_PWR_EN | CFG54_PHY0_PCS_PWR_STABLE |
    504	      CFG54_PHY0_PMA_PWR_STABLE;
    505	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
    506				 val, val);
    507	if (ret)
    508		goto out;
    509
    510	ret = hi3670_config_tca(priv);
    511	if (ret)
    512		goto out;
    513
    514	/* Enable SSC */
    515	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG5C,
    516				 CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN,
    517				 CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN);
    518	if (ret)
    519		goto out;
    520
    521	/* Deassert controller */
    522	val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET;
    523	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
    524	if (ret)
    525		goto out;
    526
    527	usleep_range(100, 120);
    528
    529	/* Set fake vbus valid signal */
    530	val = CTRL0_USB3_VBUSVLD | CTRL0_USB3_VBUSVLD_SEL;
    531	ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL0, val, val);
    532	if (ret)
    533		goto out;
    534
    535	val = CTRL3_USB2_VBUSVLDEXT0 | CTRL3_USB2_VBUSVLDEXTSEL0;
    536	ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL3, val, val);
    537	if (ret)
    538		goto out;
    539
    540	usleep_range(100, 120);
    541
    542	ret = hi3670_phy_set_params(priv);
    543	if (ret)
    544		goto out;
    545
    546	return 0;
    547out:
    548	dev_err(priv->dev, "failed to init phy ret: %d\n", ret);
    549	return ret;
    550}
    551
    552static int hi3670_phy_exit(struct phy *phy)
    553{
    554	struct hi3670_priv *priv = phy_get_drvdata(phy);
    555	u32 mask;
    556	int ret;
    557
    558	/* Assert phy */
    559	mask = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
    560	ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, mask, 0);
    561	if (ret)
    562		goto out;
    563
    564	if (!hi3670_is_abbclk_selected(priv)) {
    565		/* disable usb_tcxo_en */
    566		ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
    567				   USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START);
    568	} else {
    569		ret = regmap_write(priv->peri_crg, PERI_CRG_PERDIS6,
    570				   GT_CLK_USB2PHY_REF);
    571		if (ret)
    572			goto out;
    573	}
    574
    575	return 0;
    576out:
    577	dev_err(priv->dev, "failed to exit phy ret: %d\n", ret);
    578	return ret;
    579}
    580
    581static const struct phy_ops hi3670_phy_ops = {
    582	.init		= hi3670_phy_init,
    583	.exit		= hi3670_phy_exit,
    584	.owner		= THIS_MODULE,
    585};
    586
    587static int hi3670_phy_probe(struct platform_device *pdev)
    588{
    589	struct phy_provider *phy_provider;
    590	struct device *dev = &pdev->dev;
    591	struct phy *phy;
    592	struct hi3670_priv *priv;
    593
    594	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
    595	if (!priv)
    596		return -ENOMEM;
    597
    598	priv->dev = dev;
    599	priv->peri_crg = syscon_regmap_lookup_by_phandle(dev->of_node,
    600							 "hisilicon,pericrg-syscon");
    601	if (IS_ERR(priv->peri_crg)) {
    602		dev_err(dev, "no hisilicon,pericrg-syscon\n");
    603		return PTR_ERR(priv->peri_crg);
    604	}
    605
    606	priv->pctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
    607						      "hisilicon,pctrl-syscon");
    608	if (IS_ERR(priv->pctrl)) {
    609		dev_err(dev, "no hisilicon,pctrl-syscon\n");
    610		return PTR_ERR(priv->pctrl);
    611	}
    612
    613	priv->sctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
    614						      "hisilicon,sctrl-syscon");
    615	if (IS_ERR(priv->sctrl)) {
    616		dev_err(dev, "no hisilicon,sctrl-syscon\n");
    617		return PTR_ERR(priv->sctrl);
    618	}
    619
    620	/* node of hi3670 phy is a sub-node of usb3_otg_bc */
    621	priv->usb31misc = syscon_node_to_regmap(dev->parent->of_node);
    622	if (IS_ERR(priv->usb31misc)) {
    623		dev_err(dev, "no hisilicon,usb3-otg-bc-syscon\n");
    624		return PTR_ERR(priv->usb31misc);
    625	}
    626
    627	if (of_property_read_u32(dev->of_node, "hisilicon,eye-diagram-param",
    628				 &priv->eye_diagram_param))
    629		priv->eye_diagram_param = KIRIN970_USB_DEFAULT_PHY_PARAM;
    630
    631	if (of_property_read_u32(dev->of_node, "hisilicon,tx-vboost-lvl",
    632				 &priv->tx_vboost_lvl))
    633		priv->tx_vboost_lvl = KIRIN970_USB_DEFAULT_PHY_VBOOST;
    634
    635	phy = devm_phy_create(dev, NULL, &hi3670_phy_ops);
    636	if (IS_ERR(phy))
    637		return PTR_ERR(phy);
    638
    639	phy_set_drvdata(phy, priv);
    640	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
    641	return PTR_ERR_OR_ZERO(phy_provider);
    642}
    643
    644static const struct of_device_id hi3670_phy_of_match[] = {
    645	{ .compatible = "hisilicon,hi3670-usb-phy" },
    646	{ },
    647};
    648MODULE_DEVICE_TABLE(of, hi3670_phy_of_match);
    649
    650static struct platform_driver hi3670_phy_driver = {
    651	.probe	= hi3670_phy_probe,
    652	.driver = {
    653		.name	= "hi3670-usb-phy",
    654		.of_match_table	= hi3670_phy_of_match,
    655	}
    656};
    657module_platform_driver(hi3670_phy_driver);
    658
    659MODULE_AUTHOR("Yu Chen <chenyu56@huawei.com>");
    660MODULE_LICENSE("GPL v2");
    661MODULE_DESCRIPTION("Hilisicon Kirin970 USB31 PHY Driver");