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-qcom-qusb2.c (31000B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2017, 2019, The Linux Foundation. All rights reserved.
      4 */
      5
      6#include <linux/clk.h>
      7#include <linux/delay.h>
      8#include <linux/err.h>
      9#include <linux/io.h>
     10#include <linux/kernel.h>
     11#include <linux/mfd/syscon.h>
     12#include <linux/module.h>
     13#include <linux/nvmem-consumer.h>
     14#include <linux/of.h>
     15#include <linux/of_device.h>
     16#include <linux/phy/phy.h>
     17#include <linux/platform_device.h>
     18#include <linux/regmap.h>
     19#include <linux/regulator/consumer.h>
     20#include <linux/reset.h>
     21#include <linux/slab.h>
     22
     23#include <dt-bindings/phy/phy-qcom-qusb2.h>
     24
     25#define QUSB2PHY_PLL			0x0
     26#define QUSB2PHY_PLL_TEST		0x04
     27#define CLK_REF_SEL			BIT(7)
     28
     29#define QUSB2PHY_PLL_TUNE		0x08
     30#define QUSB2PHY_PLL_USER_CTL1		0x0c
     31#define QUSB2PHY_PLL_USER_CTL2		0x10
     32#define QUSB2PHY_PLL_AUTOPGM_CTL1	0x1c
     33#define QUSB2PHY_PLL_PWR_CTRL		0x18
     34
     35/* QUSB2PHY_PLL_STATUS register bits */
     36#define PLL_LOCKED			BIT(5)
     37
     38/* QUSB2PHY_PLL_COMMON_STATUS_ONE register bits */
     39#define CORE_READY_STATUS		BIT(0)
     40
     41/* QUSB2PHY_PORT_POWERDOWN register bits */
     42#define CLAMP_N_EN			BIT(5)
     43#define FREEZIO_N			BIT(1)
     44#define POWER_DOWN			BIT(0)
     45
     46/* QUSB2PHY_PWR_CTRL1 register bits */
     47#define PWR_CTRL1_VREF_SUPPLY_TRIM	BIT(5)
     48#define PWR_CTRL1_CLAMP_N_EN		BIT(1)
     49
     50#define QUSB2PHY_REFCLK_ENABLE		BIT(0)
     51
     52#define PHY_CLK_SCHEME_SEL		BIT(0)
     53
     54/* QUSB2PHY_INTR_CTRL register bits */
     55#define DMSE_INTR_HIGH_SEL			BIT(4)
     56#define DPSE_INTR_HIGH_SEL			BIT(3)
     57#define CHG_DET_INTR_EN				BIT(2)
     58#define DMSE_INTR_EN				BIT(1)
     59#define DPSE_INTR_EN				BIT(0)
     60
     61/* QUSB2PHY_PLL_CORE_INPUT_OVERRIDE register bits */
     62#define CORE_PLL_EN_FROM_RESET			BIT(4)
     63#define CORE_RESET				BIT(5)
     64#define CORE_RESET_MUX				BIT(6)
     65
     66/* QUSB2PHY_IMP_CTRL1 register bits */
     67#define IMP_RES_OFFSET_MASK			GENMASK(5, 0)
     68#define IMP_RES_OFFSET_SHIFT			0x0
     69
     70/* QUSB2PHY_PLL_BIAS_CONTROL_2 register bits */
     71#define BIAS_CTRL2_RES_OFFSET_MASK		GENMASK(5, 0)
     72#define BIAS_CTRL2_RES_OFFSET_SHIFT		0x0
     73
     74/* QUSB2PHY_CHG_CONTROL_2 register bits */
     75#define CHG_CTRL2_OFFSET_MASK			GENMASK(5, 4)
     76#define CHG_CTRL2_OFFSET_SHIFT			0x4
     77
     78/* QUSB2PHY_PORT_TUNE1 register bits */
     79#define HSTX_TRIM_MASK				GENMASK(7, 4)
     80#define HSTX_TRIM_SHIFT				0x4
     81#define PREEMPH_WIDTH_HALF_BIT			BIT(2)
     82#define PREEMPHASIS_EN_MASK			GENMASK(1, 0)
     83#define PREEMPHASIS_EN_SHIFT			0x0
     84
     85/* QUSB2PHY_PORT_TUNE2 register bits */
     86#define HSDISC_TRIM_MASK			GENMASK(1, 0)
     87#define HSDISC_TRIM_SHIFT			0x0
     88
     89#define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO	0x04
     90#define QUSB2PHY_PLL_CLOCK_INVERTERS		0x18c
     91#define QUSB2PHY_PLL_CMODE			0x2c
     92#define QUSB2PHY_PLL_LOCK_DELAY			0x184
     93#define QUSB2PHY_PLL_DIGITAL_TIMERS_TWO		0xb4
     94#define QUSB2PHY_PLL_BIAS_CONTROL_1		0x194
     95#define QUSB2PHY_PLL_BIAS_CONTROL_2		0x198
     96#define QUSB2PHY_PWR_CTRL2			0x214
     97#define QUSB2PHY_IMP_CTRL1			0x220
     98#define QUSB2PHY_IMP_CTRL2			0x224
     99#define QUSB2PHY_CHG_CTRL2			0x23c
    100
    101struct qusb2_phy_init_tbl {
    102	unsigned int offset;
    103	unsigned int val;
    104	/*
    105	 * register part of layout ?
    106	 * if yes, then offset gives index in the reg-layout
    107	 */
    108	int in_layout;
    109};
    110
    111#define QUSB2_PHY_INIT_CFG(o, v) \
    112	{			\
    113		.offset = o,	\
    114		.val = v,	\
    115	}
    116
    117#define QUSB2_PHY_INIT_CFG_L(o, v) \
    118	{			\
    119		.offset = o,	\
    120		.val = v,	\
    121		.in_layout = 1,	\
    122	}
    123
    124/* set of registers with offsets different per-PHY */
    125enum qusb2phy_reg_layout {
    126	QUSB2PHY_PLL_CORE_INPUT_OVERRIDE,
    127	QUSB2PHY_PLL_STATUS,
    128	QUSB2PHY_PORT_TUNE1,
    129	QUSB2PHY_PORT_TUNE2,
    130	QUSB2PHY_PORT_TUNE3,
    131	QUSB2PHY_PORT_TUNE4,
    132	QUSB2PHY_PORT_TUNE5,
    133	QUSB2PHY_PORT_TEST1,
    134	QUSB2PHY_PORT_TEST2,
    135	QUSB2PHY_PORT_POWERDOWN,
    136	QUSB2PHY_INTR_CTRL,
    137};
    138
    139static const struct qusb2_phy_init_tbl ipq6018_init_tbl[] = {
    140	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL, 0x14),
    141	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xF8),
    142	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0xB3),
    143	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0x83),
    144	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0xC0),
    145	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30),
    146	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79),
    147	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21),
    148	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x00),
    149	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
    150	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TEST2, 0x14),
    151	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TEST, 0x80),
    152	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9F),
    153};
    154
    155static const unsigned int ipq6018_regs_layout[] = {
    156	[QUSB2PHY_PLL_STATUS]              = 0x38,
    157	[QUSB2PHY_PORT_TUNE1]              = 0x80,
    158	[QUSB2PHY_PORT_TUNE2]              = 0x84,
    159	[QUSB2PHY_PORT_TUNE3]              = 0x88,
    160	[QUSB2PHY_PORT_TUNE4]              = 0x8C,
    161	[QUSB2PHY_PORT_TUNE5]              = 0x90,
    162	[QUSB2PHY_PORT_TEST1]              = 0x98,
    163	[QUSB2PHY_PORT_TEST2]              = 0x9C,
    164	[QUSB2PHY_PORT_POWERDOWN]          = 0xB4,
    165	[QUSB2PHY_INTR_CTRL]               = 0xBC,
    166};
    167
    168static const unsigned int msm8996_regs_layout[] = {
    169	[QUSB2PHY_PLL_STATUS]		= 0x38,
    170	[QUSB2PHY_PORT_TUNE1]		= 0x80,
    171	[QUSB2PHY_PORT_TUNE2]		= 0x84,
    172	[QUSB2PHY_PORT_TUNE3]		= 0x88,
    173	[QUSB2PHY_PORT_TUNE4]		= 0x8c,
    174	[QUSB2PHY_PORT_TUNE5]		= 0x90,
    175	[QUSB2PHY_PORT_TEST1]		= 0xb8,
    176	[QUSB2PHY_PORT_TEST2]		= 0x9c,
    177	[QUSB2PHY_PORT_POWERDOWN]	= 0xb4,
    178	[QUSB2PHY_INTR_CTRL]		= 0xbc,
    179};
    180
    181static const struct qusb2_phy_init_tbl msm8996_init_tbl[] = {
    182	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xf8),
    183	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0xb3),
    184	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0x83),
    185	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0xc0),
    186
    187	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30),
    188	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79),
    189	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21),
    190
    191	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TEST2, 0x14),
    192
    193	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f),
    194	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
    195};
    196
    197static const unsigned int msm8998_regs_layout[] = {
    198	[QUSB2PHY_PLL_CORE_INPUT_OVERRIDE] = 0xa8,
    199	[QUSB2PHY_PLL_STATUS]              = 0x1a0,
    200	[QUSB2PHY_PORT_TUNE1]              = 0x23c,
    201	[QUSB2PHY_PORT_TUNE2]              = 0x240,
    202	[QUSB2PHY_PORT_TUNE3]              = 0x244,
    203	[QUSB2PHY_PORT_TUNE4]              = 0x248,
    204	[QUSB2PHY_PORT_TEST1]              = 0x24c,
    205	[QUSB2PHY_PORT_TEST2]              = 0x250,
    206	[QUSB2PHY_PORT_POWERDOWN]          = 0x210,
    207	[QUSB2PHY_INTR_CTRL]               = 0x22c,
    208};
    209
    210static const struct qusb2_phy_init_tbl msm8998_init_tbl[] = {
    211	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x13),
    212	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c),
    213	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CMODE, 0x80),
    214	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_LOCK_DELAY, 0x0a),
    215
    216	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xa5),
    217	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x09),
    218
    219	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_DIGITAL_TIMERS_TWO, 0x19),
    220};
    221
    222static const struct qusb2_phy_init_tbl sm6115_init_tbl[] = {
    223	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xf8),
    224	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x53),
    225	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0x81),
    226	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x17),
    227
    228	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30),
    229	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79),
    230	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21),
    231
    232	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TEST2, 0x14),
    233
    234	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f),
    235	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
    236};
    237
    238static const unsigned int qusb2_v2_regs_layout[] = {
    239	[QUSB2PHY_PLL_CORE_INPUT_OVERRIDE] = 0xa8,
    240	[QUSB2PHY_PLL_STATUS]		= 0x1a0,
    241	[QUSB2PHY_PORT_TUNE1]		= 0x240,
    242	[QUSB2PHY_PORT_TUNE2]		= 0x244,
    243	[QUSB2PHY_PORT_TUNE3]		= 0x248,
    244	[QUSB2PHY_PORT_TUNE4]		= 0x24c,
    245	[QUSB2PHY_PORT_TUNE5]		= 0x250,
    246	[QUSB2PHY_PORT_TEST1]		= 0x254,
    247	[QUSB2PHY_PORT_TEST2]		= 0x258,
    248	[QUSB2PHY_PORT_POWERDOWN]	= 0x210,
    249	[QUSB2PHY_INTR_CTRL]		= 0x230,
    250};
    251
    252static const struct qusb2_phy_init_tbl qusb2_v2_init_tbl[] = {
    253	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x03),
    254	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c),
    255	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CMODE, 0x80),
    256	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_LOCK_DELAY, 0x0a),
    257	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_DIGITAL_TIMERS_TWO, 0x19),
    258	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_1, 0x40),
    259	QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_BIAS_CONTROL_2, 0x20),
    260	QUSB2_PHY_INIT_CFG(QUSB2PHY_PWR_CTRL2, 0x21),
    261	QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL1, 0x0),
    262	QUSB2_PHY_INIT_CFG(QUSB2PHY_IMP_CTRL2, 0x58),
    263
    264	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x30),
    265	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x29),
    266	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE3, 0xca),
    267	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0x04),
    268	QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x03),
    269
    270	QUSB2_PHY_INIT_CFG(QUSB2PHY_CHG_CTRL2, 0x0),
    271};
    272
    273struct qusb2_phy_cfg {
    274	const struct qusb2_phy_init_tbl *tbl;
    275	/* number of entries in the table */
    276	unsigned int tbl_num;
    277	/* offset to PHY_CLK_SCHEME register in TCSR map */
    278	unsigned int clk_scheme_offset;
    279
    280	/* array of registers with different offsets */
    281	const unsigned int *regs;
    282	unsigned int mask_core_ready;
    283	unsigned int disable_ctrl;
    284	unsigned int autoresume_en;
    285
    286	/* true if PHY has PLL_TEST register to select clk_scheme */
    287	bool has_pll_test;
    288
    289	/* true if TUNE1 register must be updated by fused value, else TUNE2 */
    290	bool update_tune1_with_efuse;
    291
    292	/* true if PHY has PLL_CORE_INPUT_OVERRIDE register to reset PLL */
    293	bool has_pll_override;
    294
    295	/* true if PHY default clk scheme is single-ended */
    296	bool se_clk_scheme_default;
    297};
    298
    299static const struct qusb2_phy_cfg msm8996_phy_cfg = {
    300	.tbl		= msm8996_init_tbl,
    301	.tbl_num	= ARRAY_SIZE(msm8996_init_tbl),
    302	.regs		= msm8996_regs_layout,
    303
    304	.has_pll_test	= true,
    305	.se_clk_scheme_default = true,
    306	.disable_ctrl	= (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
    307	.mask_core_ready = PLL_LOCKED,
    308	.autoresume_en	 = BIT(3),
    309};
    310
    311static const struct qusb2_phy_cfg msm8998_phy_cfg = {
    312	.tbl            = msm8998_init_tbl,
    313	.tbl_num        = ARRAY_SIZE(msm8998_init_tbl),
    314	.regs           = msm8998_regs_layout,
    315
    316	.disable_ctrl   = POWER_DOWN,
    317	.mask_core_ready = CORE_READY_STATUS,
    318	.has_pll_override = true,
    319	.se_clk_scheme_default = true,
    320	.autoresume_en   = BIT(0),
    321	.update_tune1_with_efuse = true,
    322};
    323
    324static const struct qusb2_phy_cfg ipq6018_phy_cfg = {
    325	.tbl            = ipq6018_init_tbl,
    326	.tbl_num        = ARRAY_SIZE(ipq6018_init_tbl),
    327	.regs           = ipq6018_regs_layout,
    328
    329	.disable_ctrl   = POWER_DOWN,
    330	.mask_core_ready = PLL_LOCKED,
    331	/* autoresume not used */
    332	.autoresume_en   = BIT(0),
    333};
    334
    335static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = {
    336	.tbl		= qusb2_v2_init_tbl,
    337	.tbl_num	= ARRAY_SIZE(qusb2_v2_init_tbl),
    338	.regs		= qusb2_v2_regs_layout,
    339
    340	.disable_ctrl	= (PWR_CTRL1_VREF_SUPPLY_TRIM | PWR_CTRL1_CLAMP_N_EN |
    341			   POWER_DOWN),
    342	.mask_core_ready = CORE_READY_STATUS,
    343	.has_pll_override = true,
    344	.se_clk_scheme_default = true,
    345	.autoresume_en	  = BIT(0),
    346	.update_tune1_with_efuse = true,
    347};
    348
    349static const struct qusb2_phy_cfg sdm660_phy_cfg = {
    350	.tbl		= msm8996_init_tbl,
    351	.tbl_num	= ARRAY_SIZE(msm8996_init_tbl),
    352	.regs		= msm8996_regs_layout,
    353
    354	.has_pll_test	= true,
    355	.se_clk_scheme_default = false,
    356	.disable_ctrl	= (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
    357	.mask_core_ready = PLL_LOCKED,
    358	.autoresume_en	 = BIT(3),
    359};
    360
    361static const struct qusb2_phy_cfg sm6115_phy_cfg = {
    362	.tbl		= sm6115_init_tbl,
    363	.tbl_num	= ARRAY_SIZE(sm6115_init_tbl),
    364	.regs		= msm8996_regs_layout,
    365
    366	.has_pll_test	= true,
    367	.se_clk_scheme_default = true,
    368	.disable_ctrl	= (CLAMP_N_EN | FREEZIO_N | POWER_DOWN),
    369	.mask_core_ready = PLL_LOCKED,
    370	.autoresume_en	 = BIT(3),
    371};
    372
    373static const char * const qusb2_phy_vreg_names[] = {
    374	"vdd", "vdda-pll", "vdda-phy-dpdm",
    375};
    376
    377#define QUSB2_NUM_VREGS		ARRAY_SIZE(qusb2_phy_vreg_names)
    378
    379/* struct override_param - structure holding qusb2 v2 phy overriding param
    380 * set override true if the  device tree property exists and read and assign
    381 * to value
    382 */
    383struct override_param {
    384	bool override;
    385	u8 value;
    386};
    387
    388/*struct override_params - structure holding qusb2 v2 phy overriding params
    389 * @imp_res_offset: rescode offset to be updated in IMP_CTRL1 register
    390 * @hstx_trim: HSTX_TRIM to be updated in TUNE1 register
    391 * @preemphasis: Amplitude Pre-Emphasis to be updated in TUNE1 register
    392 * @preemphasis_width: half/full-width Pre-Emphasis updated via TUNE1
    393 * @bias_ctrl: bias ctrl to be updated in BIAS_CONTROL_2 register
    394 * @charge_ctrl: charge ctrl to be updated in CHG_CTRL2 register
    395 * @hsdisc_trim: disconnect threshold to be updated in TUNE2 register
    396 */
    397struct override_params {
    398	struct override_param imp_res_offset;
    399	struct override_param hstx_trim;
    400	struct override_param preemphasis;
    401	struct override_param preemphasis_width;
    402	struct override_param bias_ctrl;
    403	struct override_param charge_ctrl;
    404	struct override_param hsdisc_trim;
    405};
    406
    407/**
    408 * struct qusb2_phy - structure holding qusb2 phy attributes
    409 *
    410 * @phy: generic phy
    411 * @base: iomapped memory space for qubs2 phy
    412 *
    413 * @cfg_ahb_clk: AHB2PHY interface clock
    414 * @ref_clk: phy reference clock
    415 * @iface_clk: phy interface clock
    416 * @phy_reset: phy reset control
    417 * @vregs: regulator supplies bulk data
    418 *
    419 * @tcsr: TCSR syscon register map
    420 * @cell: nvmem cell containing phy tuning value
    421 *
    422 * @overrides: pointer to structure for all overriding tuning params
    423 *
    424 * @cfg: phy config data
    425 * @has_se_clk_scheme: indicate if PHY has single-ended ref clock scheme
    426 * @phy_initialized: indicate if PHY has been initialized
    427 * @mode: current PHY mode
    428 */
    429struct qusb2_phy {
    430	struct phy *phy;
    431	void __iomem *base;
    432
    433	struct clk *cfg_ahb_clk;
    434	struct clk *ref_clk;
    435	struct clk *iface_clk;
    436	struct reset_control *phy_reset;
    437	struct regulator_bulk_data vregs[QUSB2_NUM_VREGS];
    438
    439	struct regmap *tcsr;
    440	struct nvmem_cell *cell;
    441
    442	struct override_params overrides;
    443
    444	const struct qusb2_phy_cfg *cfg;
    445	bool has_se_clk_scheme;
    446	bool phy_initialized;
    447	enum phy_mode mode;
    448};
    449
    450static inline void qusb2_write_mask(void __iomem *base, u32 offset,
    451				    u32 val, u32 mask)
    452{
    453	u32 reg;
    454
    455	reg = readl(base + offset);
    456	reg &= ~mask;
    457	reg |= val & mask;
    458	writel(reg, base + offset);
    459
    460	/* Ensure above write is completed */
    461	readl(base + offset);
    462}
    463
    464static inline void qusb2_setbits(void __iomem *base, u32 offset, u32 val)
    465{
    466	u32 reg;
    467
    468	reg = readl(base + offset);
    469	reg |= val;
    470	writel(reg, base + offset);
    471
    472	/* Ensure above write is completed */
    473	readl(base + offset);
    474}
    475
    476static inline void qusb2_clrbits(void __iomem *base, u32 offset, u32 val)
    477{
    478	u32 reg;
    479
    480	reg = readl(base + offset);
    481	reg &= ~val;
    482	writel(reg, base + offset);
    483
    484	/* Ensure above write is completed */
    485	readl(base + offset);
    486}
    487
    488static inline
    489void qcom_qusb2_phy_configure(void __iomem *base,
    490			      const unsigned int *regs,
    491			      const struct qusb2_phy_init_tbl tbl[], int num)
    492{
    493	int i;
    494
    495	for (i = 0; i < num; i++) {
    496		if (tbl[i].in_layout)
    497			writel(tbl[i].val, base + regs[tbl[i].offset]);
    498		else
    499			writel(tbl[i].val, base + tbl[i].offset);
    500	}
    501}
    502
    503/*
    504 * Update board specific PHY tuning override values if specified from
    505 * device tree.
    506 */
    507static void qusb2_phy_override_phy_params(struct qusb2_phy *qphy)
    508{
    509	const struct qusb2_phy_cfg *cfg = qphy->cfg;
    510	struct override_params *or = &qphy->overrides;
    511
    512	if (or->imp_res_offset.override)
    513		qusb2_write_mask(qphy->base, QUSB2PHY_IMP_CTRL1,
    514		or->imp_res_offset.value << IMP_RES_OFFSET_SHIFT,
    515			     IMP_RES_OFFSET_MASK);
    516
    517	if (or->bias_ctrl.override)
    518		qusb2_write_mask(qphy->base, QUSB2PHY_PLL_BIAS_CONTROL_2,
    519		or->bias_ctrl.value << BIAS_CTRL2_RES_OFFSET_SHIFT,
    520			   BIAS_CTRL2_RES_OFFSET_MASK);
    521
    522	if (or->charge_ctrl.override)
    523		qusb2_write_mask(qphy->base, QUSB2PHY_CHG_CTRL2,
    524		or->charge_ctrl.value << CHG_CTRL2_OFFSET_SHIFT,
    525			     CHG_CTRL2_OFFSET_MASK);
    526
    527	if (or->hstx_trim.override)
    528		qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
    529		or->hstx_trim.value << HSTX_TRIM_SHIFT,
    530				 HSTX_TRIM_MASK);
    531
    532	if (or->preemphasis.override)
    533		qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
    534		or->preemphasis.value << PREEMPHASIS_EN_SHIFT,
    535				PREEMPHASIS_EN_MASK);
    536
    537	if (or->preemphasis_width.override) {
    538		if (or->preemphasis_width.value ==
    539		    QUSB2_V2_PREEMPHASIS_WIDTH_HALF_BIT)
    540			qusb2_setbits(qphy->base,
    541				      cfg->regs[QUSB2PHY_PORT_TUNE1],
    542				      PREEMPH_WIDTH_HALF_BIT);
    543		else
    544			qusb2_clrbits(qphy->base,
    545				      cfg->regs[QUSB2PHY_PORT_TUNE1],
    546				      PREEMPH_WIDTH_HALF_BIT);
    547	}
    548
    549	if (or->hsdisc_trim.override)
    550		qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
    551		or->hsdisc_trim.value << HSDISC_TRIM_SHIFT,
    552				 HSDISC_TRIM_MASK);
    553}
    554
    555/*
    556 * Fetches HS Tx tuning value from nvmem and sets the
    557 * QUSB2PHY_PORT_TUNE1/2 register.
    558 * For error case, skip setting the value and use the default value.
    559 */
    560static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy)
    561{
    562	struct device *dev = &qphy->phy->dev;
    563	const struct qusb2_phy_cfg *cfg = qphy->cfg;
    564	u8 *val, hstx_trim;
    565
    566	/* efuse register is optional */
    567	if (!qphy->cell)
    568		return;
    569
    570	/*
    571	 * Read efuse register having TUNE2/1 parameter's high nibble.
    572	 * If efuse register shows value as 0x0 (indicating value is not
    573	 * fused), or if we fail to find a valid efuse register setting,
    574	 * then use default value for high nibble that we have already
    575	 * set while configuring the phy.
    576	 */
    577	val = nvmem_cell_read(qphy->cell, NULL);
    578	if (IS_ERR(val)) {
    579		dev_dbg(dev, "failed to read a valid hs-tx trim value\n");
    580		return;
    581	}
    582	hstx_trim = val[0];
    583	kfree(val);
    584	if (!hstx_trim) {
    585		dev_dbg(dev, "failed to read a valid hs-tx trim value\n");
    586		return;
    587	}
    588
    589	/* Fused TUNE1/2 value is the higher nibble only */
    590	if (cfg->update_tune1_with_efuse)
    591		qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1],
    592				 hstx_trim << HSTX_TRIM_SHIFT, HSTX_TRIM_MASK);
    593	else
    594		qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2],
    595				 hstx_trim << HSTX_TRIM_SHIFT, HSTX_TRIM_MASK);
    596}
    597
    598static int qusb2_phy_set_mode(struct phy *phy,
    599			      enum phy_mode mode, int submode)
    600{
    601	struct qusb2_phy *qphy = phy_get_drvdata(phy);
    602
    603	qphy->mode = mode;
    604
    605	return 0;
    606}
    607
    608static int __maybe_unused qusb2_phy_runtime_suspend(struct device *dev)
    609{
    610	struct qusb2_phy *qphy = dev_get_drvdata(dev);
    611	const struct qusb2_phy_cfg *cfg = qphy->cfg;
    612	u32 intr_mask;
    613
    614	dev_vdbg(dev, "Suspending QUSB2 Phy, mode:%d\n", qphy->mode);
    615
    616	if (!qphy->phy_initialized) {
    617		dev_vdbg(dev, "PHY not initialized, bailing out\n");
    618		return 0;
    619	}
    620
    621	/*
    622	 * Enable DP/DM interrupts to detect line state changes based on current
    623	 * speed. In other words, enable the triggers _opposite_ of what the
    624	 * current D+/D- levels are e.g. if currently D+ high, D- low
    625	 * (HS 'J'/Suspend), configure the mask to trigger on D+ low OR D- high
    626	 */
    627	intr_mask = DPSE_INTR_EN | DMSE_INTR_EN;
    628	switch (qphy->mode) {
    629	case PHY_MODE_USB_HOST_HS:
    630	case PHY_MODE_USB_HOST_FS:
    631	case PHY_MODE_USB_DEVICE_HS:
    632	case PHY_MODE_USB_DEVICE_FS:
    633		intr_mask |= DMSE_INTR_HIGH_SEL;
    634		break;
    635	case PHY_MODE_USB_HOST_LS:
    636	case PHY_MODE_USB_DEVICE_LS:
    637		intr_mask |= DPSE_INTR_HIGH_SEL;
    638		break;
    639	default:
    640		/* No device connected, enable both DP/DM high interrupt */
    641		intr_mask |= DMSE_INTR_HIGH_SEL;
    642		intr_mask |= DPSE_INTR_HIGH_SEL;
    643		break;
    644	}
    645
    646	writel(intr_mask, qphy->base + cfg->regs[QUSB2PHY_INTR_CTRL]);
    647
    648	/* hold core PLL into reset */
    649	if (cfg->has_pll_override) {
    650		qusb2_setbits(qphy->base,
    651			      cfg->regs[QUSB2PHY_PLL_CORE_INPUT_OVERRIDE],
    652			      CORE_PLL_EN_FROM_RESET | CORE_RESET |
    653			      CORE_RESET_MUX);
    654	}
    655
    656	/* enable phy auto-resume only if device is connected on bus */
    657	if (qphy->mode != PHY_MODE_INVALID) {
    658		qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TEST1],
    659			      cfg->autoresume_en);
    660		/* Autoresume bit has to be toggled in order to enable it */
    661		qusb2_clrbits(qphy->base, cfg->regs[QUSB2PHY_PORT_TEST1],
    662			      cfg->autoresume_en);
    663	}
    664
    665	if (!qphy->has_se_clk_scheme)
    666		clk_disable_unprepare(qphy->ref_clk);
    667
    668	clk_disable_unprepare(qphy->cfg_ahb_clk);
    669	clk_disable_unprepare(qphy->iface_clk);
    670
    671	return 0;
    672}
    673
    674static int __maybe_unused qusb2_phy_runtime_resume(struct device *dev)
    675{
    676	struct qusb2_phy *qphy = dev_get_drvdata(dev);
    677	const struct qusb2_phy_cfg *cfg = qphy->cfg;
    678	int ret;
    679
    680	dev_vdbg(dev, "Resuming QUSB2 phy, mode:%d\n", qphy->mode);
    681
    682	if (!qphy->phy_initialized) {
    683		dev_vdbg(dev, "PHY not initialized, bailing out\n");
    684		return 0;
    685	}
    686
    687	ret = clk_prepare_enable(qphy->iface_clk);
    688	if (ret) {
    689		dev_err(dev, "failed to enable iface_clk, %d\n", ret);
    690		return ret;
    691	}
    692
    693	ret = clk_prepare_enable(qphy->cfg_ahb_clk);
    694	if (ret) {
    695		dev_err(dev, "failed to enable cfg ahb clock, %d\n", ret);
    696		goto disable_iface_clk;
    697	}
    698
    699	if (!qphy->has_se_clk_scheme) {
    700		ret = clk_prepare_enable(qphy->ref_clk);
    701		if (ret) {
    702			dev_err(dev, "failed to enable ref clk, %d\n", ret);
    703			goto disable_ahb_clk;
    704		}
    705	}
    706
    707	writel(0x0, qphy->base + cfg->regs[QUSB2PHY_INTR_CTRL]);
    708
    709	/* bring core PLL out of reset */
    710	if (cfg->has_pll_override) {
    711		qusb2_clrbits(qphy->base,
    712			      cfg->regs[QUSB2PHY_PLL_CORE_INPUT_OVERRIDE],
    713			      CORE_RESET | CORE_RESET_MUX);
    714	}
    715
    716	return 0;
    717
    718disable_ahb_clk:
    719	clk_disable_unprepare(qphy->cfg_ahb_clk);
    720disable_iface_clk:
    721	clk_disable_unprepare(qphy->iface_clk);
    722
    723	return ret;
    724}
    725
    726static int qusb2_phy_init(struct phy *phy)
    727{
    728	struct qusb2_phy *qphy = phy_get_drvdata(phy);
    729	const struct qusb2_phy_cfg *cfg = qphy->cfg;
    730	unsigned int val = 0;
    731	unsigned int clk_scheme;
    732	int ret;
    733
    734	dev_vdbg(&phy->dev, "%s(): Initializing QUSB2 phy\n", __func__);
    735
    736	/* turn on regulator supplies */
    737	ret = regulator_bulk_enable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
    738	if (ret)
    739		return ret;
    740
    741	ret = clk_prepare_enable(qphy->iface_clk);
    742	if (ret) {
    743		dev_err(&phy->dev, "failed to enable iface_clk, %d\n", ret);
    744		goto poweroff_phy;
    745	}
    746
    747	/* enable ahb interface clock to program phy */
    748	ret = clk_prepare_enable(qphy->cfg_ahb_clk);
    749	if (ret) {
    750		dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret);
    751		goto disable_iface_clk;
    752	}
    753
    754	/* Perform phy reset */
    755	ret = reset_control_assert(qphy->phy_reset);
    756	if (ret) {
    757		dev_err(&phy->dev, "failed to assert phy_reset, %d\n", ret);
    758		goto disable_ahb_clk;
    759	}
    760
    761	/* 100 us delay to keep PHY in reset mode */
    762	usleep_range(100, 150);
    763
    764	ret = reset_control_deassert(qphy->phy_reset);
    765	if (ret) {
    766		dev_err(&phy->dev, "failed to de-assert phy_reset, %d\n", ret);
    767		goto disable_ahb_clk;
    768	}
    769
    770	/* Disable the PHY */
    771	qusb2_setbits(qphy->base, cfg->regs[QUSB2PHY_PORT_POWERDOWN],
    772		      qphy->cfg->disable_ctrl);
    773
    774	if (cfg->has_pll_test) {
    775		/* save reset value to override reference clock scheme later */
    776		val = readl(qphy->base + QUSB2PHY_PLL_TEST);
    777	}
    778
    779	qcom_qusb2_phy_configure(qphy->base, cfg->regs, cfg->tbl,
    780				 cfg->tbl_num);
    781
    782	/* Override board specific PHY tuning values */
    783	qusb2_phy_override_phy_params(qphy);
    784
    785	/* Set efuse value for tuning the PHY */
    786	qusb2_phy_set_tune2_param(qphy);
    787
    788	/* Enable the PHY */
    789	qusb2_clrbits(qphy->base, cfg->regs[QUSB2PHY_PORT_POWERDOWN],
    790		      POWER_DOWN);
    791
    792	/* Required to get phy pll lock successfully */
    793	usleep_range(150, 160);
    794
    795	/*
    796	 * Not all the SoCs have got a readable TCSR_PHY_CLK_SCHEME
    797	 * register in the TCSR so, if there's none, use the default
    798	 * value hardcoded in the configuration.
    799	 */
    800	qphy->has_se_clk_scheme = cfg->se_clk_scheme_default;
    801
    802	/*
    803	 * read TCSR_PHY_CLK_SCHEME register to check if single-ended
    804	 * clock scheme is selected. If yes, then disable differential
    805	 * ref_clk and use single-ended clock, otherwise use differential
    806	 * ref_clk only.
    807	 */
    808	if (qphy->tcsr) {
    809		ret = regmap_read(qphy->tcsr, qphy->cfg->clk_scheme_offset,
    810				  &clk_scheme);
    811		if (ret) {
    812			dev_err(&phy->dev, "failed to read clk scheme reg\n");
    813			goto assert_phy_reset;
    814		}
    815
    816		/* is it a differential clock scheme ? */
    817		if (!(clk_scheme & PHY_CLK_SCHEME_SEL)) {
    818			dev_vdbg(&phy->dev, "%s(): select differential clk\n",
    819				 __func__);
    820			qphy->has_se_clk_scheme = false;
    821		} else {
    822			dev_vdbg(&phy->dev, "%s(): select single-ended clk\n",
    823				 __func__);
    824		}
    825	}
    826
    827	if (!qphy->has_se_clk_scheme) {
    828		ret = clk_prepare_enable(qphy->ref_clk);
    829		if (ret) {
    830			dev_err(&phy->dev, "failed to enable ref clk, %d\n",
    831				ret);
    832			goto assert_phy_reset;
    833		}
    834	}
    835
    836	if (cfg->has_pll_test) {
    837		if (!qphy->has_se_clk_scheme)
    838			val &= ~CLK_REF_SEL;
    839		else
    840			val |= CLK_REF_SEL;
    841
    842		writel(val, qphy->base + QUSB2PHY_PLL_TEST);
    843
    844		/* ensure above write is through */
    845		readl(qphy->base + QUSB2PHY_PLL_TEST);
    846	}
    847
    848	/* Required to get phy pll lock successfully */
    849	usleep_range(100, 110);
    850
    851	val = readb(qphy->base + cfg->regs[QUSB2PHY_PLL_STATUS]);
    852	if (!(val & cfg->mask_core_ready)) {
    853		dev_err(&phy->dev,
    854			"QUSB2PHY pll lock failed: status reg = %x\n", val);
    855		ret = -EBUSY;
    856		goto disable_ref_clk;
    857	}
    858	qphy->phy_initialized = true;
    859
    860	return 0;
    861
    862disable_ref_clk:
    863	if (!qphy->has_se_clk_scheme)
    864		clk_disable_unprepare(qphy->ref_clk);
    865assert_phy_reset:
    866	reset_control_assert(qphy->phy_reset);
    867disable_ahb_clk:
    868	clk_disable_unprepare(qphy->cfg_ahb_clk);
    869disable_iface_clk:
    870	clk_disable_unprepare(qphy->iface_clk);
    871poweroff_phy:
    872	regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
    873
    874	return ret;
    875}
    876
    877static int qusb2_phy_exit(struct phy *phy)
    878{
    879	struct qusb2_phy *qphy = phy_get_drvdata(phy);
    880
    881	/* Disable the PHY */
    882	qusb2_setbits(qphy->base, qphy->cfg->regs[QUSB2PHY_PORT_POWERDOWN],
    883		      qphy->cfg->disable_ctrl);
    884
    885	if (!qphy->has_se_clk_scheme)
    886		clk_disable_unprepare(qphy->ref_clk);
    887
    888	reset_control_assert(qphy->phy_reset);
    889
    890	clk_disable_unprepare(qphy->cfg_ahb_clk);
    891	clk_disable_unprepare(qphy->iface_clk);
    892
    893	regulator_bulk_disable(ARRAY_SIZE(qphy->vregs), qphy->vregs);
    894
    895	qphy->phy_initialized = false;
    896
    897	return 0;
    898}
    899
    900static const struct phy_ops qusb2_phy_gen_ops = {
    901	.init		= qusb2_phy_init,
    902	.exit		= qusb2_phy_exit,
    903	.set_mode	= qusb2_phy_set_mode,
    904	.owner		= THIS_MODULE,
    905};
    906
    907static const struct of_device_id qusb2_phy_of_match_table[] = {
    908	{
    909		.compatible	= "qcom,ipq6018-qusb2-phy",
    910		.data		= &ipq6018_phy_cfg,
    911	}, {
    912		.compatible	= "qcom,ipq8074-qusb2-phy",
    913		.data		= &msm8996_phy_cfg,
    914	}, {
    915		.compatible	= "qcom,msm8953-qusb2-phy",
    916		.data		= &msm8996_phy_cfg,
    917	}, {
    918		.compatible	= "qcom,msm8996-qusb2-phy",
    919		.data		= &msm8996_phy_cfg,
    920	}, {
    921		.compatible	= "qcom,msm8998-qusb2-phy",
    922		.data		= &msm8998_phy_cfg,
    923	}, {
    924		.compatible	= "qcom,qcm2290-qusb2-phy",
    925		.data		= &sm6115_phy_cfg,
    926	}, {
    927		.compatible	= "qcom,sdm660-qusb2-phy",
    928		.data		= &sdm660_phy_cfg,
    929	}, {
    930		.compatible	= "qcom,sm4250-qusb2-phy",
    931		.data		= &sm6115_phy_cfg,
    932	}, {
    933		.compatible	= "qcom,sm6115-qusb2-phy",
    934		.data		= &sm6115_phy_cfg,
    935	}, {
    936		/*
    937		 * Deprecated. Only here to support legacy device
    938		 * trees that didn't include "qcom,qusb2-v2-phy"
    939		 */
    940		.compatible	= "qcom,sdm845-qusb2-phy",
    941		.data		= &qusb2_v2_phy_cfg,
    942	}, {
    943		.compatible	= "qcom,qusb2-v2-phy",
    944		.data		= &qusb2_v2_phy_cfg,
    945	},
    946	{ },
    947};
    948MODULE_DEVICE_TABLE(of, qusb2_phy_of_match_table);
    949
    950static const struct dev_pm_ops qusb2_phy_pm_ops = {
    951	SET_RUNTIME_PM_OPS(qusb2_phy_runtime_suspend,
    952			   qusb2_phy_runtime_resume, NULL)
    953};
    954
    955static int qusb2_phy_probe(struct platform_device *pdev)
    956{
    957	struct device *dev = &pdev->dev;
    958	struct qusb2_phy *qphy;
    959	struct phy_provider *phy_provider;
    960	struct phy *generic_phy;
    961	int ret, i;
    962	int num;
    963	u32 value;
    964	struct override_params *or;
    965
    966	qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
    967	if (!qphy)
    968		return -ENOMEM;
    969	or = &qphy->overrides;
    970
    971	qphy->base = devm_platform_ioremap_resource(pdev, 0);
    972	if (IS_ERR(qphy->base))
    973		return PTR_ERR(qphy->base);
    974
    975	qphy->cfg_ahb_clk = devm_clk_get(dev, "cfg_ahb");
    976	if (IS_ERR(qphy->cfg_ahb_clk)) {
    977		ret = PTR_ERR(qphy->cfg_ahb_clk);
    978		if (ret != -EPROBE_DEFER)
    979			dev_err(dev, "failed to get cfg ahb clk, %d\n", ret);
    980		return ret;
    981	}
    982
    983	qphy->ref_clk = devm_clk_get(dev, "ref");
    984	if (IS_ERR(qphy->ref_clk)) {
    985		ret = PTR_ERR(qphy->ref_clk);
    986		if (ret != -EPROBE_DEFER)
    987			dev_err(dev, "failed to get ref clk, %d\n", ret);
    988		return ret;
    989	}
    990
    991	qphy->iface_clk = devm_clk_get_optional(dev, "iface");
    992	if (IS_ERR(qphy->iface_clk))
    993		return PTR_ERR(qphy->iface_clk);
    994
    995	qphy->phy_reset = devm_reset_control_get_by_index(&pdev->dev, 0);
    996	if (IS_ERR(qphy->phy_reset)) {
    997		dev_err(dev, "failed to get phy core reset\n");
    998		return PTR_ERR(qphy->phy_reset);
    999	}
   1000
   1001	num = ARRAY_SIZE(qphy->vregs);
   1002	for (i = 0; i < num; i++)
   1003		qphy->vregs[i].supply = qusb2_phy_vreg_names[i];
   1004
   1005	ret = devm_regulator_bulk_get(dev, num, qphy->vregs);
   1006	if (ret) {
   1007		if (ret != -EPROBE_DEFER)
   1008			dev_err(dev, "failed to get regulator supplies: %d\n",
   1009				ret);
   1010		return ret;
   1011	}
   1012
   1013	/* Get the specific init parameters of QMP phy */
   1014	qphy->cfg = of_device_get_match_data(dev);
   1015
   1016	qphy->tcsr = syscon_regmap_lookup_by_phandle(dev->of_node,
   1017							"qcom,tcsr-syscon");
   1018	if (IS_ERR(qphy->tcsr)) {
   1019		dev_dbg(dev, "failed to lookup TCSR regmap\n");
   1020		qphy->tcsr = NULL;
   1021	}
   1022
   1023	qphy->cell = devm_nvmem_cell_get(dev, NULL);
   1024	if (IS_ERR(qphy->cell)) {
   1025		if (PTR_ERR(qphy->cell) == -EPROBE_DEFER)
   1026			return -EPROBE_DEFER;
   1027		qphy->cell = NULL;
   1028		dev_dbg(dev, "failed to lookup tune2 hstx trim value\n");
   1029	}
   1030
   1031	if (!of_property_read_u32(dev->of_node, "qcom,imp-res-offset-value",
   1032				  &value)) {
   1033		or->imp_res_offset.value = (u8)value;
   1034		or->imp_res_offset.override = true;
   1035	}
   1036
   1037	if (!of_property_read_u32(dev->of_node, "qcom,bias-ctrl-value",
   1038				  &value)) {
   1039		or->bias_ctrl.value = (u8)value;
   1040		or->bias_ctrl.override = true;
   1041	}
   1042
   1043	if (!of_property_read_u32(dev->of_node, "qcom,charge-ctrl-value",
   1044				  &value)) {
   1045		or->charge_ctrl.value = (u8)value;
   1046		or->charge_ctrl.override = true;
   1047	}
   1048
   1049	if (!of_property_read_u32(dev->of_node, "qcom,hstx-trim-value",
   1050				  &value)) {
   1051		or->hstx_trim.value = (u8)value;
   1052		or->hstx_trim.override = true;
   1053	}
   1054
   1055	if (!of_property_read_u32(dev->of_node, "qcom,preemphasis-level",
   1056				     &value)) {
   1057		or->preemphasis.value = (u8)value;
   1058		or->preemphasis.override = true;
   1059	}
   1060
   1061	if (!of_property_read_u32(dev->of_node, "qcom,preemphasis-width",
   1062				     &value)) {
   1063		or->preemphasis_width.value = (u8)value;
   1064		or->preemphasis_width.override = true;
   1065	}
   1066
   1067	if (!of_property_read_u32(dev->of_node, "qcom,hsdisc-trim-value",
   1068				  &value)) {
   1069		or->hsdisc_trim.value = (u8)value;
   1070		or->hsdisc_trim.override = true;
   1071	}
   1072
   1073	pm_runtime_set_active(dev);
   1074	pm_runtime_enable(dev);
   1075	/*
   1076	 * Prevent runtime pm from being ON by default. Users can enable
   1077	 * it using power/control in sysfs.
   1078	 */
   1079	pm_runtime_forbid(dev);
   1080
   1081	generic_phy = devm_phy_create(dev, NULL, &qusb2_phy_gen_ops);
   1082	if (IS_ERR(generic_phy)) {
   1083		ret = PTR_ERR(generic_phy);
   1084		dev_err(dev, "failed to create phy, %d\n", ret);
   1085		pm_runtime_disable(dev);
   1086		return ret;
   1087	}
   1088	qphy->phy = generic_phy;
   1089
   1090	dev_set_drvdata(dev, qphy);
   1091	phy_set_drvdata(generic_phy, qphy);
   1092
   1093	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
   1094	if (!IS_ERR(phy_provider))
   1095		dev_info(dev, "Registered Qcom-QUSB2 phy\n");
   1096	else
   1097		pm_runtime_disable(dev);
   1098
   1099	return PTR_ERR_OR_ZERO(phy_provider);
   1100}
   1101
   1102static struct platform_driver qusb2_phy_driver = {
   1103	.probe		= qusb2_phy_probe,
   1104	.driver = {
   1105		.name	= "qcom-qusb2-phy",
   1106		.pm	= &qusb2_phy_pm_ops,
   1107		.of_match_table = qusb2_phy_of_match_table,
   1108	},
   1109};
   1110
   1111module_platform_driver(qusb2_phy_driver);
   1112
   1113MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
   1114MODULE_DESCRIPTION("Qualcomm QUSB2 PHY driver");
   1115MODULE_LICENSE("GPL v2");