Loading drivers/usb/phy/class-dual-role.c +6 −1 Original line number Diff line number Diff line Loading @@ -13,6 +13,11 @@ * GNU General Public License for more details. * */ /* * NOTE: This file has been modified by Sony Mobile Communications Inc. * Modifications are Copyright (c) 2017 Sony Mobile Communications Inc, * and licensed under the license of the file. */ #include <linux/ctype.h> #include <linux/device.h> Loading Loading @@ -413,7 +418,7 @@ static umode_t dual_role_attr_is_visible(struct kobject *kobj, if (dual_role->desc->property_is_writeable && dual_role_property_is_writeable(dual_role, property) > 0) mode |= S_IWUSR; mode |= S_IWUSR | S_IWGRP; return mode; } Loading drivers/usb/phy/phy-msm-qusb-v2.c +180 −11 Original line number Diff line number Diff line Loading @@ -10,6 +10,11 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* * NOTE: This file has been modified by Sony Mobile Communications Inc. * Modifications are Copyright (c) 2016 Sony Mobile Communications Inc, * and licensed under the license of the file. */ #include <linux/module.h> #include <linux/kernel.h> Loading Loading @@ -51,6 +56,9 @@ #define QUSB2PHY_PORT_TUNE1 0x23c #define QUSB2PHY_TEST1 0x24C #define QUSB2PHY_PORT_TUNE2 0x240 #define QUSB2PHY_PORT_TUNE3 0x244 #define QUSB2PHY_PORT_TUNE4 0x248 #define QUSB2PHY_1P2_VOL_MIN 1200000 /* uV */ #define QUSB2PHY_1P2_VOL_MAX 1200000 /* uV */ Loading @@ -70,9 +78,39 @@ #define QUSB2PHY_PLL_ANALOG_CONTROLS_ONE 0x0 #define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO 0x4 #define USB_PHY_HSTX_TRIM 0xF0 /* TUNE1 7:4 */ #define USB_PHY_HSTX_SR 0x0C /* TUNE1 3:2 */ #define USB_PHY_HSTX_SR_BIAS 0x03 /* TUNE1 1:0 */ #define USB_PHY_SEL_EMPH_HALF_WIDTH 0x10 /* TUNE2 4 */ #define USB_PHY_EN_EMPHASIS 0x0C /* TUNE2 3:2 */ #define USB_PHY_HS_DISCON_TRIM 0x03 /* TUNE2 1:0 */ #define USB_PHY_CDR_WIDE 0x80 /* TUNE3 7 */ #define USB_PHY_CDR_PULSE_SMPL 0x40 /* TUNE3 6 */ #define USB_PHY_TX2RX_DLY 0x3F /* TUNE3 5:0 */ #define USB_PHY_HANDOFF_PHSEL 0xE0 /* TUNE4 7:5 */ #define USB_PHY_FORCE_HSRX_ALWAYS_ON 0x10 /* TUNE4 4 */ #define USB_PHY_SQ_FILTER_DIS 0x08 /* TUNE4 3 */ #define USB_PHY_SQ_LEVEL 0x07 /* TUNE4 2:0 */ unsigned int phy_tune1; unsigned int phy_tune2; unsigned int phy_tune3; unsigned int phy_tune4; unsigned int phy_host_tune1; unsigned int phy_host_tune2; module_param(phy_tune1, uint, S_IRUGO | S_IWUSR); module_param(phy_tune2, uint, S_IRUGO | S_IWUSR); module_param(phy_tune3, uint, S_IRUGO | S_IWUSR); module_param(phy_tune4, uint, S_IRUGO | S_IWUSR); module_param(phy_host_tune1, uint, S_IRUGO | S_IWUSR); module_param(phy_host_tune2, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(phy_tune1, "QUSB PHY v2 TUNE1"); MODULE_PARM_DESC(phy_tune2, "QUSB PHY v2 TUNE2"); MODULE_PARM_DESC(phy_tune3, "QUSB PHY v2 TUNE3"); MODULE_PARM_DESC(phy_tune4, "QUSB PHY v2 TUNE4"); MODULE_PARM_DESC(phy_host_tune1, "QUSB PHY HOST v2 TUNE1"); MODULE_PARM_DESC(phy_host_tune2, "QUSB PHY HOST v2 TUNE2"); struct qusb_phy { struct usb_phy phy; Loading @@ -98,8 +136,10 @@ struct qusb_phy { int *qusb_phy_host_init_seq; u32 tune_val; u32 host_tune_val; int efuse_bit_pos; int efuse_num_of_bits; u32 efuse_offset; int power_enabled_ref; bool clocks_enabled; Loading Loading @@ -380,14 +420,16 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value) return ret; } static void qusb_phy_get_tune1_param(struct qusb_phy *qphy) static u32 qusb_phy_get_tune1_param(struct qusb_phy *qphy) { u8 reg; u32 bit_mask = 1; u32 tune_val; pr_debug("%s(): num_of_bits:%d bit_pos:%d\n", __func__, pr_debug("%s(): num_of_bits:%d bit_pos:%d offset:%d\n", __func__, qphy->efuse_num_of_bits, qphy->efuse_bit_pos); qphy->efuse_bit_pos, qphy->efuse_offset); /* get bit mask based on number of bits to use with efuse reg */ bit_mask = (bit_mask << qphy->efuse_num_of_bits) - 1; Loading @@ -396,18 +438,22 @@ static void qusb_phy_get_tune1_param(struct qusb_phy *qphy) * if efuse reg is updated (i.e non-zero) then use it to program * tune parameters */ qphy->tune_val = readl_relaxed(qphy->efuse_reg); tune_val = readl_relaxed(qphy->efuse_reg); pr_debug("%s(): bit_mask:%d efuse based tune1 value:%d\n", __func__, bit_mask, qphy->tune_val); __func__, bit_mask, tune_val); qphy->tune_val = TUNE_VAL_MASK(qphy->tune_val, qphy->efuse_bit_pos, bit_mask); tune_val = TUNE_VAL_MASK(tune_val, qphy->efuse_bit_pos, bit_mask); reg = readb_relaxed(qphy->base + QUSB2PHY_PORT_TUNE1); if (qphy->tune_val) { if (tune_val) { tune_val += qphy->efuse_offset; if ((s32)tune_val < 0) tune_val = 0x00; else if ((s32)tune_val > 0x0f) tune_val = 0x0f; reg = reg & 0x0f; reg |= (qphy->tune_val << 4); reg |= (tune_val << 4); } qphy->tune_val = reg; return reg; } static void qusb_phy_write_seq(void __iomem *base, u32 *seq, int cnt, Loading @@ -424,6 +470,75 @@ static void qusb_phy_write_seq(void __iomem *base, u32 *seq, int cnt, } } static inline u32 msm_usb_read_reg_field(void *base, u32 offset, const u32 mask) { u32 shift = find_first_bit((void *)&mask, 32); u32 val = readb_relaxed(base + offset); val &= mask; /* clear other bits */ val >>= shift; return val; } static void msm_qphy_param_output(struct usb_phy *phy) { struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy); /* PORT_TUNE1 */ dev_dbg(phy->dev, "PORT_TUNE1:0x%02x\n", readb_relaxed(qphy->base + QUSB2PHY_PORT_TUNE1)); dev_dbg(phy->dev, " :HSTX_TRIM \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE1, USB_PHY_HSTX_TRIM)); dev_dbg(phy->dev, " :HSTX_SR \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE1, USB_PHY_HSTX_SR)); dev_dbg(phy->dev, " :HSTX_SR_BIAS \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE1, USB_PHY_HSTX_SR_BIAS)); /* PORT_TUNE2 */ dev_dbg(phy->dev, "PORT_TUNE2:0x%02x\n", readb_relaxed(qphy->base + QUSB2PHY_PORT_TUNE2)); dev_dbg(phy->dev, " :SEL_EMPH_HALF_WIDTH \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE2, USB_PHY_SEL_EMPH_HALF_WIDTH)); dev_dbg(phy->dev, " :EN_EMPHASIS \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE2, USB_PHY_EN_EMPHASIS)); dev_dbg(phy->dev, " :HS_DISCON_TRIM \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE2, USB_PHY_HS_DISCON_TRIM)); /* PORT_TUNE3 */ dev_dbg(phy->dev, "PORT_TUNE3:0x%02x\n", readb_relaxed(qphy->base + QUSB2PHY_PORT_TUNE3)); dev_dbg(phy->dev, " :CDR_WIDE \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE3, USB_PHY_CDR_WIDE)); dev_dbg(phy->dev, " :CDR_PULSE_SMPL \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE3, USB_PHY_CDR_PULSE_SMPL)); dev_dbg(phy->dev, " :TX2RX_DLY \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE3, USB_PHY_TX2RX_DLY)); /* PORT_TUNE4 */ dev_dbg(phy->dev, "PORT_TUNE4:0x%02x\n", readb_relaxed(qphy->base + QUSB2PHY_PORT_TUNE4)); dev_dbg(phy->dev, " :HANDOFF_PHSEL \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE4, USB_PHY_HANDOFF_PHSEL)); dev_dbg(phy->dev, " :FORCE_HSRX_ALWAYS_ON \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE4, USB_PHY_FORCE_HSRX_ALWAYS_ON)); dev_dbg(phy->dev, " :SQ_FILTER_DIS \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE4, USB_PHY_SQ_FILTER_DIS)); dev_dbg(phy->dev, " :SQ_LEVEL \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE4, USB_PHY_SQ_LEVEL)); } static void qusb_phy_host_init(struct usb_phy *phy) { u8 reg; Loading @@ -444,6 +559,32 @@ static void qusb_phy_host_init(struct usb_phy *phy) qusb_phy_write_seq(qphy->base, qphy->qusb_phy_host_init_seq, qphy->host_init_seq_len, 0); if (qphy->efuse_reg) { if (!qphy->host_tune_val) qphy->host_tune_val = qusb_phy_get_tune1_param(qphy); pr_debug("%s(): Programming host TUNE1 parameter as:%x\n", __func__, qphy->host_tune_val); writel_relaxed(qphy->host_tune_val, qphy->base + QUSB2PHY_PORT_TUNE1); } /* If phy_tune1 modparam set, override tune1 value */ if (phy_host_tune1) { pr_debug("%s(): (modparam) HOST_TUNE1 val:0x%02x\n", __func__, phy_host_tune1); writel_relaxed(phy_host_tune1, qphy->base + QUSB2PHY_PORT_TUNE1); } /* If phy_tune2 modparam set, override tune2 value */ if (phy_host_tune2) { pr_debug("%s(): (modparam) HOST TUNE2 val:0x%02x\n", __func__, phy_host_tune2); writel_relaxed(phy_host_tune2, qphy->base + QUSB2PHY_PORT_TUNE2); } msm_qphy_param_output(phy); /* Ensure above write is completed before turning ON ref clk */ wmb(); Loading Loading @@ -520,7 +661,7 @@ static int qusb_phy_init(struct usb_phy *phy) qphy->init_seq_len, 0); if (qphy->efuse_reg) { if (!qphy->tune_val) qusb_phy_get_tune1_param(qphy); qphy->tune_val = qusb_phy_get_tune1_param(qphy); pr_debug("%s(): Programming TUNE1 parameter as:%x\n", __func__, qphy->tune_val); Loading @@ -535,6 +676,28 @@ static int qusb_phy_init(struct usb_phy *phy) writel_relaxed(phy_tune1, qphy->base + QUSB2PHY_PORT_TUNE1); } /* If phy_tune2 modparam set, override tune2 value */ if (phy_tune2) { pr_debug("%s(): (modparam) TUNE2 val:0x%02x\n", __func__, phy_tune2); writel_relaxed(phy_tune2, qphy->base + QUSB2PHY_PORT_TUNE2); } /* If phy_tune3 modparam set, override tune3 value */ if (phy_tune3) { pr_debug("%s(): (modparam) TUNE3 val:0x%02x\n", __func__, phy_tune3); writel_relaxed(phy_tune3, qphy->base + QUSB2PHY_PORT_TUNE3); } /* If phy_tune4 modparam set, override tune4 value */ if (phy_tune4) { pr_debug("%s(): (modparam) TUNE4 val:0x%02x\n", __func__, phy_tune4); writel_relaxed(phy_tune4, qphy->base + QUSB2PHY_PORT_TUNE4); } msm_qphy_param_output(phy); /* ensure above writes are completed before re-enabling PHY */ wmb(); Loading Loading @@ -886,6 +1049,12 @@ static int qusb_phy_probe(struct platform_device *pdev) &qphy->efuse_num_of_bits); } if (!ret) { ret = of_property_read_u32(dev->of_node, "qcom,efuse-offset", &qphy->efuse_offset); } if (ret) { dev_err(dev, "DT Value for efuse is invalid.\n"); Loading drivers/usb/phy/phy-msm-ssusb-qmp.c +55 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,11 @@ * GNU General Public License for more details. * */ /* * NOTE: This file has been modified by Sony Mobile Communications Inc. * Modifications are Copyright (c) 2017 Sony Mobile Communications Inc, * and licensed under the license of the file. */ #include <linux/module.h> #include <linux/kernel.h> Loading Loading @@ -57,6 +62,24 @@ enum ldo_levels { /* port select mux: 1 - sw control. 0 - HW control*/ #define SW_PORTSELECT_MX BIT(1) #define SSUSB3PHY_TXA_DRV_LVL 0x21c #define SSUSB3PHY_TXB_DRV_LVL 0x61c #define SSUSB3PHY_TXA_EMP_POST1_LVL 0x20c #define SSUSB3PHY_TXB_EMP_POST1_LVL 0x60c unsigned int ssphy_txa_drv_lvl; unsigned int ssphy_txb_drv_lvl; unsigned int ssphy_txa_emp_post1_lvl; unsigned int ssphy_txb_emp_post1_lvl; module_param(ssphy_txa_drv_lvl, uint, S_IRUGO | S_IWUSR); module_param(ssphy_txb_drv_lvl, uint, S_IRUGO | S_IWUSR); module_param(ssphy_txa_emp_post1_lvl, uint, S_IRUGO | S_IWUSR); module_param(ssphy_txb_emp_post1_lvl, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(ssphy_txa_drv_lvl, "SSUSB3PHY QSERDES TXA DRV LVL"); MODULE_PARM_DESC(ssphy_txb_drv_lvl, "SSUSB3PHY QSERDES TXB DRV LVL"); MODULE_PARM_DESC(ssphy_txa_emp_post1_lvl, "SSUSB3PHY QSERDES TXA EMP POST1 LVL"); MODULE_PARM_DESC(ssphy_txb_emp_post1_lvl, "SSUSB3PHY QSERDES TXB EMP POST1 LVL"); enum qmp_phy_rev_reg { USB3_PHY_PCS_STATUS, USB3_PHY_AUTONOMOUS_MODE_CTRL, Loading Loading @@ -263,6 +286,21 @@ disable_fpc_redrive: return rc < 0 ? rc : 0; } static void msm_ssphy_param_output(struct usb_phy *uphy) { struct msm_ssphy_qmp *phy = container_of(uphy, struct msm_ssphy_qmp, phy); dev_dbg(uphy->dev, "SS_USB3PHY_QSERDES_TXA_TX_DEV_LVL:0x%02x\n", readb_relaxed(phy->base + SSUSB3PHY_TXA_DRV_LVL)); dev_dbg(uphy->dev, "SS_USB3PHY_QSERDES_TXB_TX_DEV_LVL:0x%02x\n", readb_relaxed(phy->base + SSUSB3PHY_TXB_DRV_LVL)); dev_dbg(uphy->dev, "SS_USB3PHY_QSERDES_TXA_TX_EMP_POST1_LVL:0x%02x\n", readb_relaxed(phy->base + SSUSB3PHY_TXA_EMP_POST1_LVL)); dev_dbg(uphy->dev, "SS_USB3PHY_QSERDES_TXB_TX_EMP_POST1_LVL:0x%02x\n", readb_relaxed(phy->base + SSUSB3PHY_TXB_EMP_POST1_LVL)); } static int configure_phy_regs(struct usb_phy *uphy, const struct qmp_reg_val *reg) { Loading @@ -280,6 +318,23 @@ static int configure_phy_regs(struct usb_phy *uphy, usleep_range(reg->delay, reg->delay + 10); reg++; } /* ssusb phy dynamic set */ if (ssphy_txa_drv_lvl) writel_relaxed(ssphy_txa_drv_lvl, phy->base + SSUSB3PHY_TXA_DRV_LVL); if (ssphy_txb_drv_lvl) writel_relaxed(ssphy_txb_drv_lvl, phy->base + SSUSB3PHY_TXB_DRV_LVL); if (ssphy_txa_emp_post1_lvl) writel_relaxed(ssphy_txa_emp_post1_lvl, phy->base + SSUSB3PHY_TXA_EMP_POST1_LVL); if (ssphy_txb_emp_post1_lvl) writel_relaxed(ssphy_txb_emp_post1_lvl, phy->base + SSUSB3PHY_TXB_EMP_POST1_LVL); /* parameter output */ msm_ssphy_param_output(uphy); return 0; } Loading Loading
drivers/usb/phy/class-dual-role.c +6 −1 Original line number Diff line number Diff line Loading @@ -13,6 +13,11 @@ * GNU General Public License for more details. * */ /* * NOTE: This file has been modified by Sony Mobile Communications Inc. * Modifications are Copyright (c) 2017 Sony Mobile Communications Inc, * and licensed under the license of the file. */ #include <linux/ctype.h> #include <linux/device.h> Loading Loading @@ -413,7 +418,7 @@ static umode_t dual_role_attr_is_visible(struct kobject *kobj, if (dual_role->desc->property_is_writeable && dual_role_property_is_writeable(dual_role, property) > 0) mode |= S_IWUSR; mode |= S_IWUSR | S_IWGRP; return mode; } Loading
drivers/usb/phy/phy-msm-qusb-v2.c +180 −11 Original line number Diff line number Diff line Loading @@ -10,6 +10,11 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* * NOTE: This file has been modified by Sony Mobile Communications Inc. * Modifications are Copyright (c) 2016 Sony Mobile Communications Inc, * and licensed under the license of the file. */ #include <linux/module.h> #include <linux/kernel.h> Loading Loading @@ -51,6 +56,9 @@ #define QUSB2PHY_PORT_TUNE1 0x23c #define QUSB2PHY_TEST1 0x24C #define QUSB2PHY_PORT_TUNE2 0x240 #define QUSB2PHY_PORT_TUNE3 0x244 #define QUSB2PHY_PORT_TUNE4 0x248 #define QUSB2PHY_1P2_VOL_MIN 1200000 /* uV */ #define QUSB2PHY_1P2_VOL_MAX 1200000 /* uV */ Loading @@ -70,9 +78,39 @@ #define QUSB2PHY_PLL_ANALOG_CONTROLS_ONE 0x0 #define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO 0x4 #define USB_PHY_HSTX_TRIM 0xF0 /* TUNE1 7:4 */ #define USB_PHY_HSTX_SR 0x0C /* TUNE1 3:2 */ #define USB_PHY_HSTX_SR_BIAS 0x03 /* TUNE1 1:0 */ #define USB_PHY_SEL_EMPH_HALF_WIDTH 0x10 /* TUNE2 4 */ #define USB_PHY_EN_EMPHASIS 0x0C /* TUNE2 3:2 */ #define USB_PHY_HS_DISCON_TRIM 0x03 /* TUNE2 1:0 */ #define USB_PHY_CDR_WIDE 0x80 /* TUNE3 7 */ #define USB_PHY_CDR_PULSE_SMPL 0x40 /* TUNE3 6 */ #define USB_PHY_TX2RX_DLY 0x3F /* TUNE3 5:0 */ #define USB_PHY_HANDOFF_PHSEL 0xE0 /* TUNE4 7:5 */ #define USB_PHY_FORCE_HSRX_ALWAYS_ON 0x10 /* TUNE4 4 */ #define USB_PHY_SQ_FILTER_DIS 0x08 /* TUNE4 3 */ #define USB_PHY_SQ_LEVEL 0x07 /* TUNE4 2:0 */ unsigned int phy_tune1; unsigned int phy_tune2; unsigned int phy_tune3; unsigned int phy_tune4; unsigned int phy_host_tune1; unsigned int phy_host_tune2; module_param(phy_tune1, uint, S_IRUGO | S_IWUSR); module_param(phy_tune2, uint, S_IRUGO | S_IWUSR); module_param(phy_tune3, uint, S_IRUGO | S_IWUSR); module_param(phy_tune4, uint, S_IRUGO | S_IWUSR); module_param(phy_host_tune1, uint, S_IRUGO | S_IWUSR); module_param(phy_host_tune2, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(phy_tune1, "QUSB PHY v2 TUNE1"); MODULE_PARM_DESC(phy_tune2, "QUSB PHY v2 TUNE2"); MODULE_PARM_DESC(phy_tune3, "QUSB PHY v2 TUNE3"); MODULE_PARM_DESC(phy_tune4, "QUSB PHY v2 TUNE4"); MODULE_PARM_DESC(phy_host_tune1, "QUSB PHY HOST v2 TUNE1"); MODULE_PARM_DESC(phy_host_tune2, "QUSB PHY HOST v2 TUNE2"); struct qusb_phy { struct usb_phy phy; Loading @@ -98,8 +136,10 @@ struct qusb_phy { int *qusb_phy_host_init_seq; u32 tune_val; u32 host_tune_val; int efuse_bit_pos; int efuse_num_of_bits; u32 efuse_offset; int power_enabled_ref; bool clocks_enabled; Loading Loading @@ -380,14 +420,16 @@ static int qusb_phy_update_dpdm(struct usb_phy *phy, int value) return ret; } static void qusb_phy_get_tune1_param(struct qusb_phy *qphy) static u32 qusb_phy_get_tune1_param(struct qusb_phy *qphy) { u8 reg; u32 bit_mask = 1; u32 tune_val; pr_debug("%s(): num_of_bits:%d bit_pos:%d\n", __func__, pr_debug("%s(): num_of_bits:%d bit_pos:%d offset:%d\n", __func__, qphy->efuse_num_of_bits, qphy->efuse_bit_pos); qphy->efuse_bit_pos, qphy->efuse_offset); /* get bit mask based on number of bits to use with efuse reg */ bit_mask = (bit_mask << qphy->efuse_num_of_bits) - 1; Loading @@ -396,18 +438,22 @@ static void qusb_phy_get_tune1_param(struct qusb_phy *qphy) * if efuse reg is updated (i.e non-zero) then use it to program * tune parameters */ qphy->tune_val = readl_relaxed(qphy->efuse_reg); tune_val = readl_relaxed(qphy->efuse_reg); pr_debug("%s(): bit_mask:%d efuse based tune1 value:%d\n", __func__, bit_mask, qphy->tune_val); __func__, bit_mask, tune_val); qphy->tune_val = TUNE_VAL_MASK(qphy->tune_val, qphy->efuse_bit_pos, bit_mask); tune_val = TUNE_VAL_MASK(tune_val, qphy->efuse_bit_pos, bit_mask); reg = readb_relaxed(qphy->base + QUSB2PHY_PORT_TUNE1); if (qphy->tune_val) { if (tune_val) { tune_val += qphy->efuse_offset; if ((s32)tune_val < 0) tune_val = 0x00; else if ((s32)tune_val > 0x0f) tune_val = 0x0f; reg = reg & 0x0f; reg |= (qphy->tune_val << 4); reg |= (tune_val << 4); } qphy->tune_val = reg; return reg; } static void qusb_phy_write_seq(void __iomem *base, u32 *seq, int cnt, Loading @@ -424,6 +470,75 @@ static void qusb_phy_write_seq(void __iomem *base, u32 *seq, int cnt, } } static inline u32 msm_usb_read_reg_field(void *base, u32 offset, const u32 mask) { u32 shift = find_first_bit((void *)&mask, 32); u32 val = readb_relaxed(base + offset); val &= mask; /* clear other bits */ val >>= shift; return val; } static void msm_qphy_param_output(struct usb_phy *phy) { struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy); /* PORT_TUNE1 */ dev_dbg(phy->dev, "PORT_TUNE1:0x%02x\n", readb_relaxed(qphy->base + QUSB2PHY_PORT_TUNE1)); dev_dbg(phy->dev, " :HSTX_TRIM \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE1, USB_PHY_HSTX_TRIM)); dev_dbg(phy->dev, " :HSTX_SR \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE1, USB_PHY_HSTX_SR)); dev_dbg(phy->dev, " :HSTX_SR_BIAS \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE1, USB_PHY_HSTX_SR_BIAS)); /* PORT_TUNE2 */ dev_dbg(phy->dev, "PORT_TUNE2:0x%02x\n", readb_relaxed(qphy->base + QUSB2PHY_PORT_TUNE2)); dev_dbg(phy->dev, " :SEL_EMPH_HALF_WIDTH \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE2, USB_PHY_SEL_EMPH_HALF_WIDTH)); dev_dbg(phy->dev, " :EN_EMPHASIS \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE2, USB_PHY_EN_EMPHASIS)); dev_dbg(phy->dev, " :HS_DISCON_TRIM \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE2, USB_PHY_HS_DISCON_TRIM)); /* PORT_TUNE3 */ dev_dbg(phy->dev, "PORT_TUNE3:0x%02x\n", readb_relaxed(qphy->base + QUSB2PHY_PORT_TUNE3)); dev_dbg(phy->dev, " :CDR_WIDE \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE3, USB_PHY_CDR_WIDE)); dev_dbg(phy->dev, " :CDR_PULSE_SMPL \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE3, USB_PHY_CDR_PULSE_SMPL)); dev_dbg(phy->dev, " :TX2RX_DLY \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE3, USB_PHY_TX2RX_DLY)); /* PORT_TUNE4 */ dev_dbg(phy->dev, "PORT_TUNE4:0x%02x\n", readb_relaxed(qphy->base + QUSB2PHY_PORT_TUNE4)); dev_dbg(phy->dev, " :HANDOFF_PHSEL \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE4, USB_PHY_HANDOFF_PHSEL)); dev_dbg(phy->dev, " :FORCE_HSRX_ALWAYS_ON \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE4, USB_PHY_FORCE_HSRX_ALWAYS_ON)); dev_dbg(phy->dev, " :SQ_FILTER_DIS \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE4, USB_PHY_SQ_FILTER_DIS)); dev_dbg(phy->dev, " :SQ_LEVEL \t0x%02x\n", msm_usb_read_reg_field(qphy->base, QUSB2PHY_PORT_TUNE4, USB_PHY_SQ_LEVEL)); } static void qusb_phy_host_init(struct usb_phy *phy) { u8 reg; Loading @@ -444,6 +559,32 @@ static void qusb_phy_host_init(struct usb_phy *phy) qusb_phy_write_seq(qphy->base, qphy->qusb_phy_host_init_seq, qphy->host_init_seq_len, 0); if (qphy->efuse_reg) { if (!qphy->host_tune_val) qphy->host_tune_val = qusb_phy_get_tune1_param(qphy); pr_debug("%s(): Programming host TUNE1 parameter as:%x\n", __func__, qphy->host_tune_val); writel_relaxed(qphy->host_tune_val, qphy->base + QUSB2PHY_PORT_TUNE1); } /* If phy_tune1 modparam set, override tune1 value */ if (phy_host_tune1) { pr_debug("%s(): (modparam) HOST_TUNE1 val:0x%02x\n", __func__, phy_host_tune1); writel_relaxed(phy_host_tune1, qphy->base + QUSB2PHY_PORT_TUNE1); } /* If phy_tune2 modparam set, override tune2 value */ if (phy_host_tune2) { pr_debug("%s(): (modparam) HOST TUNE2 val:0x%02x\n", __func__, phy_host_tune2); writel_relaxed(phy_host_tune2, qphy->base + QUSB2PHY_PORT_TUNE2); } msm_qphy_param_output(phy); /* Ensure above write is completed before turning ON ref clk */ wmb(); Loading Loading @@ -520,7 +661,7 @@ static int qusb_phy_init(struct usb_phy *phy) qphy->init_seq_len, 0); if (qphy->efuse_reg) { if (!qphy->tune_val) qusb_phy_get_tune1_param(qphy); qphy->tune_val = qusb_phy_get_tune1_param(qphy); pr_debug("%s(): Programming TUNE1 parameter as:%x\n", __func__, qphy->tune_val); Loading @@ -535,6 +676,28 @@ static int qusb_phy_init(struct usb_phy *phy) writel_relaxed(phy_tune1, qphy->base + QUSB2PHY_PORT_TUNE1); } /* If phy_tune2 modparam set, override tune2 value */ if (phy_tune2) { pr_debug("%s(): (modparam) TUNE2 val:0x%02x\n", __func__, phy_tune2); writel_relaxed(phy_tune2, qphy->base + QUSB2PHY_PORT_TUNE2); } /* If phy_tune3 modparam set, override tune3 value */ if (phy_tune3) { pr_debug("%s(): (modparam) TUNE3 val:0x%02x\n", __func__, phy_tune3); writel_relaxed(phy_tune3, qphy->base + QUSB2PHY_PORT_TUNE3); } /* If phy_tune4 modparam set, override tune4 value */ if (phy_tune4) { pr_debug("%s(): (modparam) TUNE4 val:0x%02x\n", __func__, phy_tune4); writel_relaxed(phy_tune4, qphy->base + QUSB2PHY_PORT_TUNE4); } msm_qphy_param_output(phy); /* ensure above writes are completed before re-enabling PHY */ wmb(); Loading Loading @@ -886,6 +1049,12 @@ static int qusb_phy_probe(struct platform_device *pdev) &qphy->efuse_num_of_bits); } if (!ret) { ret = of_property_read_u32(dev->of_node, "qcom,efuse-offset", &qphy->efuse_offset); } if (ret) { dev_err(dev, "DT Value for efuse is invalid.\n"); Loading
drivers/usb/phy/phy-msm-ssusb-qmp.c +55 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,11 @@ * GNU General Public License for more details. * */ /* * NOTE: This file has been modified by Sony Mobile Communications Inc. * Modifications are Copyright (c) 2017 Sony Mobile Communications Inc, * and licensed under the license of the file. */ #include <linux/module.h> #include <linux/kernel.h> Loading Loading @@ -57,6 +62,24 @@ enum ldo_levels { /* port select mux: 1 - sw control. 0 - HW control*/ #define SW_PORTSELECT_MX BIT(1) #define SSUSB3PHY_TXA_DRV_LVL 0x21c #define SSUSB3PHY_TXB_DRV_LVL 0x61c #define SSUSB3PHY_TXA_EMP_POST1_LVL 0x20c #define SSUSB3PHY_TXB_EMP_POST1_LVL 0x60c unsigned int ssphy_txa_drv_lvl; unsigned int ssphy_txb_drv_lvl; unsigned int ssphy_txa_emp_post1_lvl; unsigned int ssphy_txb_emp_post1_lvl; module_param(ssphy_txa_drv_lvl, uint, S_IRUGO | S_IWUSR); module_param(ssphy_txb_drv_lvl, uint, S_IRUGO | S_IWUSR); module_param(ssphy_txa_emp_post1_lvl, uint, S_IRUGO | S_IWUSR); module_param(ssphy_txb_emp_post1_lvl, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(ssphy_txa_drv_lvl, "SSUSB3PHY QSERDES TXA DRV LVL"); MODULE_PARM_DESC(ssphy_txb_drv_lvl, "SSUSB3PHY QSERDES TXB DRV LVL"); MODULE_PARM_DESC(ssphy_txa_emp_post1_lvl, "SSUSB3PHY QSERDES TXA EMP POST1 LVL"); MODULE_PARM_DESC(ssphy_txb_emp_post1_lvl, "SSUSB3PHY QSERDES TXB EMP POST1 LVL"); enum qmp_phy_rev_reg { USB3_PHY_PCS_STATUS, USB3_PHY_AUTONOMOUS_MODE_CTRL, Loading Loading @@ -263,6 +286,21 @@ disable_fpc_redrive: return rc < 0 ? rc : 0; } static void msm_ssphy_param_output(struct usb_phy *uphy) { struct msm_ssphy_qmp *phy = container_of(uphy, struct msm_ssphy_qmp, phy); dev_dbg(uphy->dev, "SS_USB3PHY_QSERDES_TXA_TX_DEV_LVL:0x%02x\n", readb_relaxed(phy->base + SSUSB3PHY_TXA_DRV_LVL)); dev_dbg(uphy->dev, "SS_USB3PHY_QSERDES_TXB_TX_DEV_LVL:0x%02x\n", readb_relaxed(phy->base + SSUSB3PHY_TXB_DRV_LVL)); dev_dbg(uphy->dev, "SS_USB3PHY_QSERDES_TXA_TX_EMP_POST1_LVL:0x%02x\n", readb_relaxed(phy->base + SSUSB3PHY_TXA_EMP_POST1_LVL)); dev_dbg(uphy->dev, "SS_USB3PHY_QSERDES_TXB_TX_EMP_POST1_LVL:0x%02x\n", readb_relaxed(phy->base + SSUSB3PHY_TXB_EMP_POST1_LVL)); } static int configure_phy_regs(struct usb_phy *uphy, const struct qmp_reg_val *reg) { Loading @@ -280,6 +318,23 @@ static int configure_phy_regs(struct usb_phy *uphy, usleep_range(reg->delay, reg->delay + 10); reg++; } /* ssusb phy dynamic set */ if (ssphy_txa_drv_lvl) writel_relaxed(ssphy_txa_drv_lvl, phy->base + SSUSB3PHY_TXA_DRV_LVL); if (ssphy_txb_drv_lvl) writel_relaxed(ssphy_txb_drv_lvl, phy->base + SSUSB3PHY_TXB_DRV_LVL); if (ssphy_txa_emp_post1_lvl) writel_relaxed(ssphy_txa_emp_post1_lvl, phy->base + SSUSB3PHY_TXA_EMP_POST1_LVL); if (ssphy_txb_emp_post1_lvl) writel_relaxed(ssphy_txb_emp_post1_lvl, phy->base + SSUSB3PHY_TXB_EMP_POST1_LVL); /* parameter output */ msm_ssphy_param_output(uphy); return 0; } Loading