Skip to content

Commit fdb968a

Browse files
committed
phy: apple: atc: support mode switches in atcphy_dpphy_set_mode()
Required for the DP2HDMI only atc3 port on 14/16 inch Macbook Pros. Fixes: 9ca3958 ("phy: apple: atc: Support DisplayPort only operation") Signed-off-by: Janne Grunau <j@jannau.net>
1 parent 436e509 commit fdb968a

1 file changed

Lines changed: 57 additions & 12 deletions

File tree

drivers/phy/apple/atc.c

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "atc.h"
1010
#include "trace.h"
1111

12+
#include <asm-generic/errno.h>
1213
#include <dt-bindings/phy/phy.h>
1314
#include <linux/bitfield.h>
1415
#include <linux/delay.h>
@@ -1776,12 +1777,58 @@ static const struct phy_ops apple_atc_usb2_phy_ops = {
17761777
.exit = atcphy_usb2_power_off,
17771778
};
17781779

1780+
static int atcphy_dpphy_mux_set(struct apple_atcphy *atcphy, enum atcphy_mode target)
1781+
{
1782+
int ret = 0;
1783+
1784+
// TODO:
1785+
flush_work(&atcphy->mux_set_work);
1786+
1787+
mutex_lock(&atcphy->lock);
1788+
1789+
if (atcphy->mode == target)
1790+
goto out_unlock;
1791+
1792+
atcphy->target_mode = target;
1793+
1794+
WARN_ON(!schedule_work(&atcphy->mux_set_work));
1795+
ret = wait_for_completion_timeout(&atcphy->atcphy_online_event,
1796+
msecs_to_jiffies(1000));
1797+
if (ret == 0)
1798+
ret = -ETIMEDOUT;
1799+
else if (ret > 0)
1800+
ret = 0;
1801+
1802+
out_unlock:
1803+
mutex_unlock(&atcphy->lock);
1804+
return ret;
1805+
}
1806+
17791807
static int atcphy_dpphy_set_mode(struct phy *phy, enum phy_mode mode,
17801808
int submode)
17811809
{
1782-
/* nothing to do here since the setup already happened in mux_set */
1783-
if (mode == PHY_MODE_DP && submode >= 0 && submode <= 5)
1810+
struct apple_atcphy *atcphy = phy_get_drvdata(phy);
1811+
1812+
if (!atcphy->dp_only)
17841813
return 0;
1814+
1815+
dev_info(atcphy->dev, "%s(mode=%u, submode=%d)\n", __func__, mode, submode);
1816+
1817+
switch (mode) {
1818+
case PHY_MODE_INVALID:
1819+
if (atcphy->mode == APPLE_ATCPHY_MODE_OFF)
1820+
return 0;
1821+
return atcphy_dpphy_mux_set(atcphy, APPLE_ATCPHY_MODE_OFF);
1822+
case PHY_MODE_DP:
1823+
/* TODO: does this get called for DP-altmode? */
1824+
if (atcphy->mode == APPLE_ATCPHY_MODE_USB3_DP ||
1825+
atcphy->mode == APPLE_ATCPHY_MODE_DP)
1826+
return 0;
1827+
return atcphy_dpphy_mux_set(atcphy, APPLE_ATCPHY_MODE_DP);
1828+
default:
1829+
break;
1830+
}
1831+
17851832
return -EINVAL;
17861833
}
17871834

@@ -1791,6 +1838,11 @@ static int atcphy_dpphy_validate(struct phy *phy, enum phy_mode mode,
17911838
struct phy_configure_opts_dp *opts = &opts_->dp;
17921839
struct apple_atcphy *atcphy = phy_get_drvdata(phy);
17931840

1841+
if (mode == PHY_MODE_INVALID) {
1842+
memset(opts, 0, sizeof(*opts));
1843+
return 0;
1844+
}
1845+
17941846
if (mode != PHY_MODE_DP)
17951847
return -EINVAL;
17961848
if (submode != 0)
@@ -1836,9 +1888,9 @@ static int atcphy_dpphy_configure(struct phy *phy,
18361888
if (opts->set_lanes) {
18371889
if (((atcphy->mode == APPLE_ATCPHY_MODE_DP && opts->lanes != 4) ||
18381890
(atcphy->mode == APPLE_ATCPHY_MODE_USB3_DP && opts->lanes != 2)) &&
1839-
opts->lanes != 0)
1840-
dev_warn(atcphy->dev, "Unexpected lane count %u for mode %u\n",
1841-
opts->lanes, atcphy->mode);
1891+
(atcphy->mode == APPLE_ATCPHY_MODE_OFF && opts->lanes != 0))
1892+
dev_warn(atcphy->dev, "Unexpected lane count %u for mode %u\n",
1893+
opts->lanes, atcphy->mode);
18421894

18431895
}
18441896

@@ -2429,13 +2481,6 @@ static int atcphy_probe(struct platform_device *pdev)
24292481
if (ret)
24302482
return ret;
24312483

2432-
if (atcphy->dp_only) {
2433-
atcphy->target_mode = APPLE_ATCPHY_MODE_DP;
2434-
WARN_ON(!schedule_work(&atcphy->mux_set_work));
2435-
wait_for_completion_timeout(&atcphy->atcphy_online_event,
2436-
msecs_to_jiffies(1000));
2437-
}
2438-
24392484
return 0;
24402485
}
24412486

0 commit comments

Comments
 (0)