1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018 MediaTek Inc.
* Copyright (c) 2026 BayLibre, SAS
* Author: Jie Qiu <[email protected]>
*/
#include <dm.h>
#include <dm/device_compat.h>
#include "phy-mtk-hdmi.h"
static int mtk_hdmi_phy_power_on(struct phy *phy)
{
struct mtk_hdmi_phy *hdmi_phy = dev_get_priv(phy->dev);
int ret;
/*
* The 5V output is a regulator in the Linux driver, controlled by the
* HDMI connector. U-Boot has no such consumer, so enable it here.
*/
if (hdmi_phy->conf->power_control)
hdmi_phy->conf->power_control(hdmi_phy, true);
/* Equivalent of clk_prepare_enable() on the kernel PLL clock. */
ret = hdmi_phy->conf->pll_prepare(hdmi_phy);
if (ret)
return ret;
hdmi_phy->conf->hdmi_phy_enable_tmds(hdmi_phy);
return 0;
}
static int mtk_hdmi_phy_power_off(struct phy *phy)
{
struct mtk_hdmi_phy *hdmi_phy = dev_get_priv(phy->dev);
hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy);
hdmi_phy->conf->pll_unprepare(hdmi_phy);
if (hdmi_phy->conf->power_control)
hdmi_phy->conf->power_control(hdmi_phy, false);
return 0;
}
static int mtk_hdmi_phy_configure(struct phy *phy, void *opts)
{
struct mtk_hdmi_phy *hdmi_phy = dev_get_priv(phy->dev);
if (hdmi_phy->conf->hdmi_phy_configure)
return hdmi_phy->conf->hdmi_phy_configure(phy, opts);
return 0;
}
static int mtk_hdmi_phy_probe(struct udevice *dev)
{
struct mtk_hdmi_phy *hdmi_phy = dev_get_priv(dev);
int ret;
hdmi_phy->dev = dev;
hdmi_phy->conf =
(const struct mtk_hdmi_phy_conf *)dev_get_driver_data(dev);
hdmi_phy->regs = dev_read_addr_ptr(dev);
if (!hdmi_phy->regs)
return -EINVAL;
ret = clk_get_by_name(dev, "pll_ref", &hdmi_phy->pll_ref);
if (ret) {
dev_err(dev, "Failed to get PLL reference clock: %d\n", ret);
return ret;
}
ret = clk_enable(&hdmi_phy->pll_ref);
if (ret) {
dev_err(dev, "Failed to enable PLL reference clock: %d\n", ret);
return ret;
}
return 0;
}
static const struct phy_ops mtk_hdmi_phy_ops = {
.power_on = mtk_hdmi_phy_power_on,
.power_off = mtk_hdmi_phy_power_off,
.configure = mtk_hdmi_phy_configure,
};
static const struct udevice_id mtk_hdmi_phy_match[] = {
{ .compatible = "mediatek,mt8195-hdmi-phy",
.data = (ulong)&mtk_hdmi_phy_8195_conf,
},
{ /* sentinel */ }
};
U_BOOT_DRIVER(mtk_hdmi_phy) = {
.name = "mtk-hdmi-phy",
.id = UCLASS_PHY,
.of_match = mtk_hdmi_phy_match,
.ops = &mtk_hdmi_phy_ops,
.probe = mtk_hdmi_phy_probe,
.priv_auto = sizeof(struct mtk_hdmi_phy),
};
|