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