Skip to content

Commit 45a13cc

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 e4ecbf7 commit 45a13cc

1 file changed

Lines changed: 55 additions & 13 deletions

File tree

drivers/phy/apple/atc.c

Lines changed: 55 additions & 13 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,55 @@ 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)
1784-
return 0;
1810+
struct apple_atcphy *atcphy = phy_get_drvdata(phy);
1811+
1812+
dev_info(atcphy->dev, "%s(mode=%u, submode=%d)\n", __func__, mode, submode);
1813+
1814+
switch (mode) {
1815+
case PHY_MODE_INVALID:
1816+
if (atcphy->mode == APPLE_ATCPHY_MODE_OFF)
1817+
return 0;
1818+
return atcphy_dpphy_mux_set(atcphy, APPLE_ATCPHY_MODE_OFF);
1819+
case PHY_MODE_DP:
1820+
/* TODO: does this get called for DP-altmode? */
1821+
if (atcphy->mode == APPLE_ATCPHY_MODE_USB3_DP ||
1822+
atcphy->mode == APPLE_ATCPHY_MODE_DP)
1823+
return 0;
1824+
return atcphy_dpphy_mux_set(atcphy, APPLE_ATCPHY_MODE_DP);
1825+
default:
1826+
break;
1827+
}
1828+
17851829
return -EINVAL;
17861830
}
17871831

@@ -1791,6 +1835,11 @@ static int atcphy_dpphy_validate(struct phy *phy, enum phy_mode mode,
17911835
struct phy_configure_opts_dp *opts = &opts_->dp;
17921836
struct apple_atcphy *atcphy = phy_get_drvdata(phy);
17931837

1838+
if (mode == PHY_MODE_INVALID) {
1839+
memset(opts, 0, sizeof(*opts));
1840+
return 0;
1841+
}
1842+
17941843
if (mode != PHY_MODE_DP)
17951844
return -EINVAL;
17961845
if (submode != 0)
@@ -1836,9 +1885,9 @@ static int atcphy_dpphy_configure(struct phy *phy,
18361885
if (opts->set_lanes) {
18371886
if (((atcphy->mode == APPLE_ATCPHY_MODE_DP && opts->lanes != 4) ||
18381887
(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);
1888+
(atcphy->mode == APPLE_ATCPHY_MODE_OFF && opts->lanes != 0))
1889+
dev_warn(atcphy->dev, "Unexpected lane count %u for mode %u\n",
1890+
opts->lanes, atcphy->mode);
18421891

18431892
}
18441893

@@ -2429,13 +2478,6 @@ static int atcphy_probe(struct platform_device *pdev)
24292478
if (ret)
24302479
return ret;
24312480

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-
24392481
return 0;
24402482
}
24412483

0 commit comments

Comments
 (0)