xref: /linux/Documentation/translations/zh_CN/driver-api/phy/phy.rst (revision 7354eb7f1558466e92e926802d36e69e42938ea9)
1.. SPDX-License-Identifier: GPL-2.0
2.. include:: ../../disclaimer-zh_CN.rst
3
4:Original: Documentation/driver-api/phy/phy.rst
5
6:翻译:
7
8 司延腾 Yanteng Si <siyanteng@loongson.cn>
9
10=========
11PHY子系统
12=========
13
14:作者: Kishon Vijay Abraham I <kishon@ti.com>
15
16本文档解释了 PHY 的通用框架和提供的API,以及使用方法。
17
18简介
19====
20
21*PHY* 是物理层的缩写,它被用来把设备连接到一个物理媒介,例如USB控制器
22有一个提供序列化、反序列化、编码、解码和负责获取所需的数据传输速率的 PHY。
23注意,有些USB控制器内嵌了 PHY 的功能,其它的则使用了一个外置的PHY,此外
24使用 PHY 的设备还有无线网、以太网、SATA等(控制器)。
25
26创建这个框架的目的是将遍布 Linux 内核的 PHY 驱动程序融入到 drivers/phy27以增加代码的可复用性,进而提高代码的可维护性。
28
29该框架仅适用于使用外部 PHY(PHY 功能未嵌入控制器内)的设备。
30
31注册/注销PHY provider
32=====================
33
34PHY provider是指实现一个或多个 PHY 实例的实体。对于 PHY provider 仅
35实现单个 PHY 实例的简单情况,框架在 of_phy_simple_xlate 中提供其自己
36的 of_xlate 实现。如果 PHY provider 实现多个实例,则应提供其自己的
37of_xlate 实现。of_xlate 仅用于 dt 启动情况。
38
39::
40
41	#define of_phy_provider_register(dev, xlate)    \
42		__of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate))
43
44	#define devm_of_phy_provider_register(dev, xlate)       \
45		__devm_of_phy_provider_register((dev), NULL, THIS_MODULE,
46						(xlate))
47
48of_phy_provider_register 和 devm_of_phy_provider_register 宏
49可用于注册 phy_provider,它以 device 和 of_xlate 作为参数。对于 dt
50启动情况,所有 PHY provider 都应使用上述两个宏之一来注册 PHY provider。
51
52与 PHY provider 关联的设备树节点通常包含一组子节点,每个子节点代表一个
53PHY。某些绑定可能会为了上下文和可扩展性将子节点嵌套在特别的层级中,在这种
54情况下,可以使用低级别的 of_phy_provider_register_full() 和
55devm_of_phy_provider_register_full() 宏来覆盖包含子节点的节点。
56
57::
58
59	#define of_phy_provider_register_full(dev, children, xlate) \
60		__of_phy_provider_register(dev, children, THIS_MODULE, xlate)
61
62	#define devm_of_phy_provider_register_full(dev, children, xlate) \
63		__devm_of_phy_provider_register_full(dev, children,
64						     THIS_MODULE, xlate)
65
66	void devm_of_phy_provider_unregister(struct device *dev,
67		struct phy_provider *phy_provider);
68	void of_phy_provider_unregister(struct phy_provider *phy_provider);
69
70devm_of_phy_provider_unregister 和 of_phy_provider_unregister
71可以被用来注销PHY.
72
73创建PHY
74=======
75
76PHY 驱动程序应创建 PHY,以便其他外围(芯片)控制器能够使用它。PHY 框架
77提供了 2 个 API 来创建 PHY。
78
79::
80
81	struct phy *phy_create(struct device *dev, struct device_node *node,
82			       const struct phy_ops *ops);
83	struct phy *devm_phy_create(struct device *dev,
84				    struct device_node *node,
85				    const struct phy_ops *ops);
86
87PHY 驱动程序可以使用上述两个 API 之一,通过传递设备指针和 phy_ops
88来创建 PHY。
89
90phy_ops 是一组用于执行 PHY 操作(例如 init、exit、power_on 和
91power_off)的函数指针。
92
93在 phy_ops 中,PHY provider驱动程序在创建 PHY 后使用 phy_set_drvdata()
94设置私有数据,使用 phy_get_drvdata() 获取私有数据。
95
96获取对 PHY 的引用
97=================
98
99控制器必须先获取对 PHY 的引用,然后才能使用 PHY。此框架提供以下 API
100来获取对 PHY 的引用。
101
102::
103
104	struct phy *phy_get(struct device *dev, const char *string);
105	struct phy *devm_phy_get(struct device *dev, const char *string);
106	struct phy *devm_phy_optional_get(struct device *dev,
107					  const char *string);
108	struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
109				    const char *con_id);
110	struct phy *devm_of_phy_optional_get(struct device *dev,
111					     struct device_node *np,
112					     const char *con_id);
113	struct phy *devm_of_phy_get_by_index(struct device *dev,
114					     struct device_node *np,
115					     int index);
116
117phy_get、devm_phy_get 和 devm_phy_optional_get 可用于在 dt
118启动的情况下获取 PHY,字符串参数应包含 dt 数据中给出的 phy 名称,在
119非 dt 启动的情况下,它应包含 PHY 的标签。两个 devm_phy_get 在成功
120获取 PHY 后使用 devres 将设备与 PHY 关联。在驱动程序分离时,将在
121devres 数据上调用 release 函数并释放 devres 数据。当 phy 是可选
122的时,应使用 _optional_get 变体。这些函数永远不会返回 -ENODEV,而
123是在找不到 phy 时返回 NULL。一些通用驱动程序(例如 ehci)可能使用
124多个 phy。在这种情况下,devm_of_phy_get 或 devm_of_phy_get_by_index
125用于根据名称或索引获取 phy 引用。
126
127需要注意的是,NULL 是有效的 phy 引用。NULL phy 上的所有 phy 使用
128者调用都将成为 NOP。也就是说释放调用,当应用于 NULL phy 时,release
129调用、phy_init()/phy_exit() 调用、phy_power_on()/phy_power_off()
130调用都是 NOP。NULL phy 在处理可选的 phy 设备中很有用。
131
132API的调用顺序
133=============
134
135通常,调用顺序应该是::
136
137    [devm_][of_]phy_get()
138    phy_init()
139    phy_power_on()
140    [phy_set_mode[_ext]()]
141    ...
142    phy_power_off()
143    phy_exit()
144    [[of_]phy_put()]
145
146一些PHY驱动可能没有实现 :c:func:`phy_init` 或 :c:func:`phy_power_on`,
147但是控制器应该总是调用这些函数以兼容其它PHY,有些PHY可能要求
148:c:func:`phy_set_mode <phy_set_mode_ext>` 而其他 PHY 可能使用
149默认模式(通常通过设备树或其他固件配置)。出于兼容性考虑,如果您知道将
150使用哪种模式,则应始终调用此函数。通常,应在 :c:func:`phy_power_on`
151之后调用此函数,尽管某些 PHY 驱动程序可能随时允许调用它。
152
153释放对 PHY 的引用
154=================
155
156当控制器不再需要 PHY 时,它必须使用上一节中提到的 API 释放对已获得
157的 PHY 的引用。PHY 框架提供了 2 个 API 来释放对 PHY 的引用。
158
159::
160
161	void phy_put(struct phy *phy);
162	void devm_phy_put(struct device *dev, struct phy *phy);
163
164这两个 API 都用于释放对 PHY 的引用,并且 devm_phy_put 会销毁与此
165PHY 关联的设备资源。
166
167销毁 PHY
168========
169
170当创建 PHY 的驱动程序被卸载时,它应该使用以下 2 个 API 之一销毁其创
171建的 PHY::
172
173	void phy_destroy(struct phy *phy);
174	void devm_phy_destroy(struct device *dev, struct phy *phy);
175
176这两个 API 都会销毁 PHY,并且 devm_phy_destroy 会销毁与此 PHY 关
177联的 devres。
178
179PM Runtime
180==========
181
182这个子系统启用了pm runtime。 所以,在创建PHY 时,将调用此子系统创建的
183phy 设备的 pm_runtime_enable 函数,在销毁 PHY 时,将调用
184pm_runtime_disable。请注意,此子系统创建的 phy 设备将是调用 phy_create
185(PHY provider 设备)的设备的子设备。
186
187因此,由于父子关系,此子系统创建的 phy_device 的 pm_runtime_get_sync
188调用 PHY provider 设备的 pm_runtime_get_sync。还应注意,
189phy_power_on 和 phy_power_off 分别执行 phy_pm_runtime_get_sync 和
190phy_pm_runtime_put。有导出的 API,如 phy_pm_runtime_get、
191phy_pm_runtime_get_sync、phy_pm_runtime_put、phy_pm_runtime_put_sync、
192phy_pm_runtime_allow 和 phy_pm_runtime_forbid,用于执行 PM 操作。
193
194PHY映射
195=======
196
197为了在没有 DeviceTree 帮助的情况下获取对 PHY 的引用,框架提供了可与
198clkdev 进行比较的查找,允许将 clk 结构体绑定到设备。当 struct phy 的
199句柄已存在时,可以在运行时进行查找。
200
201该框架提供以下 API 用于注册和注销查找::
202
203	int phy_create_lookup(struct phy *phy, const char *con_id,
204			      const char *dev_id);
205	void phy_remove_lookup(struct phy *phy, const char *con_id,
206			       const char *dev_id);
207
208DeviceTree绑定
209==============
210
211PHY dt 绑定的文档可以在以下位置找到 @
212Documentation/devicetree/bindings/phy/phy-bindings.txt
213