Commit 283776e9 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'phy-for-4.14-rc' of...

Merge tag 'phy-for-4.14-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy into usb-linus

Kishon writes:

phy: for 4.14 -rc

 *) Handle error return values in rockchip-typec and tegra-xusb
 *) Fix MUX error check and ioremap_resource error check in mvebu-cp110-comphy
 *) Fix NULL pointer dereference error in phy-mtk-tphy
 *) Make sure pipe selector is not set to incompatible value
 *) Fix flaky aux channel communication with rockchip-typec PHY
 *) Fix DP monitors detection issue in rockchip-typec PHY
Signed-off-by: default avatarKishon Vijay Abraham I <kishon@ti.com>
parents b3207c65 2fb85009
...@@ -111,6 +111,8 @@ ...@@ -111,6 +111,8 @@
#define MVEBU_COMPHY_CONF6_40B BIT(18) #define MVEBU_COMPHY_CONF6_40B BIT(18)
#define MVEBU_COMPHY_SELECTOR 0x1140 #define MVEBU_COMPHY_SELECTOR 0x1140
#define MVEBU_COMPHY_SELECTOR_PHY(n) ((n) * 0x4) #define MVEBU_COMPHY_SELECTOR_PHY(n) ((n) * 0x4)
#define MVEBU_COMPHY_PIPE_SELECTOR 0x1144
#define MVEBU_COMPHY_PIPE_SELECTOR_PIPE(n) ((n) * 0x4)
#define MVEBU_COMPHY_LANES 6 #define MVEBU_COMPHY_LANES 6
#define MVEBU_COMPHY_PORTS 3 #define MVEBU_COMPHY_PORTS 3
...@@ -468,13 +470,17 @@ static int mvebu_comphy_power_on(struct phy *phy) ...@@ -468,13 +470,17 @@ static int mvebu_comphy_power_on(struct phy *phy)
{ {
struct mvebu_comphy_lane *lane = phy_get_drvdata(phy); struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
struct mvebu_comphy_priv *priv = lane->priv; struct mvebu_comphy_priv *priv = lane->priv;
int ret; int ret, mux;
u32 mux, val; u32 val;
mux = mvebu_comphy_get_mux(lane->id, lane->port, lane->mode); mux = mvebu_comphy_get_mux(lane->id, lane->port, lane->mode);
if (mux < 0) if (mux < 0)
return -ENOTSUPP; return -ENOTSUPP;
regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);
regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val); regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id)); val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id); val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id);
...@@ -526,6 +532,10 @@ static int mvebu_comphy_power_off(struct phy *phy) ...@@ -526,6 +532,10 @@ static int mvebu_comphy_power_off(struct phy *phy)
val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id)); val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val); regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);
return 0; return 0;
} }
...@@ -576,8 +586,8 @@ static int mvebu_comphy_probe(struct platform_device *pdev) ...@@ -576,8 +586,8 @@ static int mvebu_comphy_probe(struct platform_device *pdev)
return PTR_ERR(priv->regmap); return PTR_ERR(priv->regmap);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->base = devm_ioremap_resource(&pdev->dev, res); priv->base = devm_ioremap_resource(&pdev->dev, res);
if (!priv->base) if (IS_ERR(priv->base))
return -ENOMEM; return PTR_ERR(priv->base);
for_each_available_child_of_node(pdev->dev.of_node, child) { for_each_available_child_of_node(pdev->dev.of_node, child) {
struct mvebu_comphy_lane *lane; struct mvebu_comphy_lane *lane;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
/* banks shared by multiple phys */ /* banks shared by multiple phys */
#define SSUSB_SIFSLV_V1_SPLLC 0x000 /* shared by u3 phys */ #define SSUSB_SIFSLV_V1_SPLLC 0x000 /* shared by u3 phys */
#define SSUSB_SIFSLV_V1_U2FREQ 0x100 /* shared by u2 phys */ #define SSUSB_SIFSLV_V1_U2FREQ 0x100 /* shared by u2 phys */
#define SSUSB_SIFSLV_V1_CHIP 0x300 /* shared by u3 phys */
/* u2 phy bank */ /* u2 phy bank */
#define SSUSB_SIFSLV_V1_U2PHY_COM 0x000 #define SSUSB_SIFSLV_V1_U2PHY_COM 0x000
/* u3/pcie/sata phy banks */ /* u3/pcie/sata phy banks */
...@@ -762,7 +763,7 @@ static void phy_v1_banks_init(struct mtk_tphy *tphy, ...@@ -762,7 +763,7 @@ static void phy_v1_banks_init(struct mtk_tphy *tphy,
case PHY_TYPE_USB3: case PHY_TYPE_USB3:
case PHY_TYPE_PCIE: case PHY_TYPE_PCIE:
u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC; u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC;
u3_banks->chip = NULL; u3_banks->chip = tphy->sif_base + SSUSB_SIFSLV_V1_CHIP;
u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD; u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA; u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA;
break; break;
......
...@@ -443,14 +443,34 @@ static inline int property_enable(struct rockchip_typec_phy *tcphy, ...@@ -443,14 +443,34 @@ static inline int property_enable(struct rockchip_typec_phy *tcphy,
return regmap_write(tcphy->grf_regs, reg->offset, val | mask); return regmap_write(tcphy->grf_regs, reg->offset, val | mask);
} }
static void tcphy_dp_aux_set_flip(struct rockchip_typec_phy *tcphy)
{
u16 tx_ana_ctrl_reg_1;
/*
* Select the polarity of the xcvr:
* 1, Reverses the polarity (If TYPEC, Pulls ups aux_p and pull
* down aux_m)
* 0, Normal polarity (if TYPEC, pulls up aux_m and pulls down
* aux_p)
*/
tx_ana_ctrl_reg_1 = readl(tcphy->base + TX_ANA_CTRL_REG_1);
if (!tcphy->flip)
tx_ana_ctrl_reg_1 |= BIT(12);
else
tx_ana_ctrl_reg_1 &= ~BIT(12);
writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
}
static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
{ {
u16 tx_ana_ctrl_reg_1;
u16 rdata, rdata2, val; u16 rdata, rdata2, val;
/* disable txda_cal_latch_en for rewrite the calibration values */ /* disable txda_cal_latch_en for rewrite the calibration values */
rdata = readl(tcphy->base + TX_ANA_CTRL_REG_1); tx_ana_ctrl_reg_1 = readl(tcphy->base + TX_ANA_CTRL_REG_1);
val = rdata & 0xdfff; tx_ana_ctrl_reg_1 &= ~BIT(13);
writel(val, tcphy->base + TX_ANA_CTRL_REG_1); writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
/* /*
* read a resistor calibration code from CMN_TXPUCAL_CTRL[6:0] and * read a resistor calibration code from CMN_TXPUCAL_CTRL[6:0] and
...@@ -472,9 +492,8 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) ...@@ -472,9 +492,8 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
* Activate this signal for 1 clock cycle to sample new calibration * Activate this signal for 1 clock cycle to sample new calibration
* values. * values.
*/ */
rdata = readl(tcphy->base + TX_ANA_CTRL_REG_1); tx_ana_ctrl_reg_1 |= BIT(13);
val = rdata | 0x2000; writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
writel(val, tcphy->base + TX_ANA_CTRL_REG_1);
usleep_range(150, 200); usleep_range(150, 200);
/* set TX Voltage Level and TX Deemphasis to 0 */ /* set TX Voltage Level and TX Deemphasis to 0 */
...@@ -482,8 +501,10 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) ...@@ -482,8 +501,10 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
/* re-enable decap */ /* re-enable decap */
writel(0x100, tcphy->base + TX_ANA_CTRL_REG_2); writel(0x100, tcphy->base + TX_ANA_CTRL_REG_2);
writel(0x300, tcphy->base + TX_ANA_CTRL_REG_2); writel(0x300, tcphy->base + TX_ANA_CTRL_REG_2);
writel(0x2008, tcphy->base + TX_ANA_CTRL_REG_1); tx_ana_ctrl_reg_1 |= BIT(3);
writel(0x2018, tcphy->base + TX_ANA_CTRL_REG_1); writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
tx_ana_ctrl_reg_1 |= BIT(4);
writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
writel(0, tcphy->base + TX_ANA_CTRL_REG_5); writel(0, tcphy->base + TX_ANA_CTRL_REG_5);
...@@ -494,8 +515,10 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) ...@@ -494,8 +515,10 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
writel(0x1001, tcphy->base + TX_ANA_CTRL_REG_4); writel(0x1001, tcphy->base + TX_ANA_CTRL_REG_4);
/* re-enables Bandgap reference for LDO */ /* re-enables Bandgap reference for LDO */
writel(0x2098, tcphy->base + TX_ANA_CTRL_REG_1); tx_ana_ctrl_reg_1 |= BIT(7);
writel(0x2198, tcphy->base + TX_ANA_CTRL_REG_1); writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
tx_ana_ctrl_reg_1 |= BIT(8);
writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
/* /*
* re-enables the transmitter pre-driver, driver data selection MUX, * re-enables the transmitter pre-driver, driver data selection MUX,
...@@ -505,27 +528,26 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy) ...@@ -505,27 +528,26 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
writel(0x303, tcphy->base + TX_ANA_CTRL_REG_2); writel(0x303, tcphy->base + TX_ANA_CTRL_REG_2);
/* /*
* BIT 12: Controls auxda_polarity, which selects the polarity of the * Do some magic undocumented stuff, some of which appears to
* xcvr: * undo the "re-enables Bandgap reference for LDO" above.
* 1, Reverses the polarity (If TYPEC, Pulls ups aux_p and pull
* down aux_m)
* 0, Normal polarity (if TYPE_C, pulls up aux_m and pulls down
* aux_p)
*/ */
val = 0xa078; tx_ana_ctrl_reg_1 |= BIT(15);
if (!tcphy->flip) tx_ana_ctrl_reg_1 &= ~BIT(8);
val |= BIT(12); tx_ana_ctrl_reg_1 &= ~BIT(7);
writel(val, tcphy->base + TX_ANA_CTRL_REG_1); tx_ana_ctrl_reg_1 |= BIT(6);
tx_ana_ctrl_reg_1 |= BIT(5);
writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
writel(0, tcphy->base + TX_ANA_CTRL_REG_3); writel(0, tcphy->base + TX_ANA_CTRL_REG_3);
writel(0, tcphy->base + TX_ANA_CTRL_REG_4); writel(0, tcphy->base + TX_ANA_CTRL_REG_4);
writel(0, tcphy->base + TX_ANA_CTRL_REG_5); writel(0, tcphy->base + TX_ANA_CTRL_REG_5);
/* /*
* Controls low_power_swing_en, set the voltage swing of the driver * Controls low_power_swing_en, don't set the voltage swing of the
* to 400mv. The values below are peak to peak (differential) values. * driver to 400mv. The values below are peak to peak (differential)
* values.
*/ */
writel(4, tcphy->base + TXDA_COEFF_CALC_CTRL); writel(0, tcphy->base + TXDA_COEFF_CALC_CTRL);
writel(0, tcphy->base + TXDA_CYA_AUXDA_CYA); writel(0, tcphy->base + TXDA_CYA_AUXDA_CYA);
/* Controls tx_high_z_tm_en */ /* Controls tx_high_z_tm_en */
...@@ -555,6 +577,7 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode) ...@@ -555,6 +577,7 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
reset_control_deassert(tcphy->tcphy_rst); reset_control_deassert(tcphy->tcphy_rst);
property_enable(tcphy, &cfg->typec_conn_dir, tcphy->flip); property_enable(tcphy, &cfg->typec_conn_dir, tcphy->flip);
tcphy_dp_aux_set_flip(tcphy);
tcphy_cfg_24m(tcphy); tcphy_cfg_24m(tcphy);
...@@ -685,8 +708,11 @@ static int rockchip_usb3_phy_power_on(struct phy *phy) ...@@ -685,8 +708,11 @@ static int rockchip_usb3_phy_power_on(struct phy *phy)
if (tcphy->mode == new_mode) if (tcphy->mode == new_mode)
goto unlock_ret; goto unlock_ret;
if (tcphy->mode == MODE_DISCONNECT) if (tcphy->mode == MODE_DISCONNECT) {
tcphy_phy_init(tcphy, new_mode); ret = tcphy_phy_init(tcphy, new_mode);
if (ret)
goto unlock_ret;
}
/* wait TCPHY for pipe ready */ /* wait TCPHY for pipe ready */
for (timeout = 0; timeout < 100; timeout++) { for (timeout = 0; timeout < 100; timeout++) {
...@@ -760,10 +786,12 @@ static int rockchip_dp_phy_power_on(struct phy *phy) ...@@ -760,10 +786,12 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
*/ */
if (new_mode == MODE_DFP_DP && tcphy->mode != MODE_DISCONNECT) { if (new_mode == MODE_DFP_DP && tcphy->mode != MODE_DISCONNECT) {
tcphy_phy_deinit(tcphy); tcphy_phy_deinit(tcphy);
tcphy_phy_init(tcphy, new_mode); ret = tcphy_phy_init(tcphy, new_mode);
} else if (tcphy->mode == MODE_DISCONNECT) { } else if (tcphy->mode == MODE_DISCONNECT) {
tcphy_phy_init(tcphy, new_mode); ret = tcphy_phy_init(tcphy, new_mode);
} }
if (ret)
goto unlock_ret;
ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL, ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
val, val & DP_MODE_A2, 1000, val, val & DP_MODE_A2, 1000,
......
...@@ -454,6 +454,8 @@ tegra_xusb_find_port_node(struct tegra_xusb_padctl *padctl, const char *type, ...@@ -454,6 +454,8 @@ tegra_xusb_find_port_node(struct tegra_xusb_padctl *padctl, const char *type,
char *name; char *name;
name = kasprintf(GFP_KERNEL, "%s-%u", type, index); name = kasprintf(GFP_KERNEL, "%s-%u", type, index);
if (!name)
return ERR_PTR(-ENOMEM);
np = of_find_node_by_name(np, name); np = of_find_node_by_name(np, name);
kfree(name); kfree(name);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment