1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
3*4882a593Smuzhiyun * Written by Jean-Jacques Hiblot <jjhiblot@ti.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #ifndef __GENERIC_PHY_H
9*4882a593Smuzhiyun #define __GENERIC_PHY_H
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <generic-phy-dp.h>
12*4882a593Smuzhiyun #include <generic-phy-mipi-dphy.h>
13*4882a593Smuzhiyun #include <generic-phy-pcie.h>
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun enum phy_mode {
16*4882a593Smuzhiyun PHY_MODE_INVALID,
17*4882a593Smuzhiyun PHY_MODE_DP,
18*4882a593Smuzhiyun };
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /**
21*4882a593Smuzhiyun * union phy_configure_opts - Opaque generic phy configuration
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun * @mipi_dphy: Configuration set applicable for phys supporting
24*4882a593Smuzhiyun * the MIPI_DPHY phy mode.
25*4882a593Smuzhiyun * @dp: Configuration set applicable for phys supporting
26*4882a593Smuzhiyun * the DisplayPort protocol.
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyun union phy_configure_opts {
29*4882a593Smuzhiyun struct phy_configure_opts_mipi_dphy mipi_dphy;
30*4882a593Smuzhiyun struct phy_configure_opts_dp dp;
31*4882a593Smuzhiyun struct phy_configure_opts_pcie pcie;
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun /**
35*4882a593Smuzhiyun * struct phy_attrs - represents phy attributes
36*4882a593Smuzhiyun * @bus_width: Data path width implemented by PHY
37*4882a593Smuzhiyun * @max_link_rate: Maximum link rate supported by PHY (in Mbps)
38*4882a593Smuzhiyun * @mode: PHY mode
39*4882a593Smuzhiyun */
40*4882a593Smuzhiyun struct phy_attrs {
41*4882a593Smuzhiyun u32 bus_width;
42*4882a593Smuzhiyun u32 max_link_rate;
43*4882a593Smuzhiyun enum phy_mode mode;
44*4882a593Smuzhiyun };
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun /**
47*4882a593Smuzhiyun * struct phy - A handle to (allowing control of) a single phy port.
48*4882a593Smuzhiyun *
49*4882a593Smuzhiyun * Clients provide storage for phy handles. The content of the structure is
50*4882a593Smuzhiyun * managed solely by the PHY API and PHY drivers. A phy struct is
51*4882a593Smuzhiyun * initialized by "get"ing the phy struct. The phy struct is passed to all
52*4882a593Smuzhiyun * other phy APIs to identify which PHY port to operate upon.
53*4882a593Smuzhiyun *
54*4882a593Smuzhiyun * @dev: The device which implements the PHY port.
55*4882a593Smuzhiyun * @id: The PHY ID within the provider.
56*4882a593Smuzhiyun *
57*4882a593Smuzhiyun */
58*4882a593Smuzhiyun struct phy {
59*4882a593Smuzhiyun struct udevice *dev;
60*4882a593Smuzhiyun unsigned long id;
61*4882a593Smuzhiyun struct phy_attrs attrs;
62*4882a593Smuzhiyun };
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun /*
65*4882a593Smuzhiyun * struct udevice_ops - set of function pointers for phy operations
66*4882a593Smuzhiyun * @init: operation to be performed for initializing phy (optional)
67*4882a593Smuzhiyun * @exit: operation to be performed while exiting (optional)
68*4882a593Smuzhiyun * @reset: reset the phy (optional).
69*4882a593Smuzhiyun * @power_on: powering on the phy (optional)
70*4882a593Smuzhiyun * @power_off: powering off the phy (optional)
71*4882a593Smuzhiyun * @set_mode: set the mode of the phy
72*4882a593Smuzhiyun */
73*4882a593Smuzhiyun struct phy_ops {
74*4882a593Smuzhiyun /**
75*4882a593Smuzhiyun * of_xlate - Translate a client's device-tree (OF) phy specifier.
76*4882a593Smuzhiyun *
77*4882a593Smuzhiyun * The PHY core calls this function as the first step in implementing
78*4882a593Smuzhiyun * a client's generic_phy_get_by_*() call.
79*4882a593Smuzhiyun *
80*4882a593Smuzhiyun * If this function pointer is set to NULL, the PHY core will use a
81*4882a593Smuzhiyun * default implementation, which assumes #phy-cells = <0> or
82*4882a593Smuzhiyun * #phy-cells = <1>, and in the later case that the DT cell
83*4882a593Smuzhiyun * contains a simple integer PHY port ID.
84*4882a593Smuzhiyun *
85*4882a593Smuzhiyun * @phy: The phy struct to hold the translation result.
86*4882a593Smuzhiyun * @args: The phy specifier values from device tree.
87*4882a593Smuzhiyun * @return 0 if OK, or a negative error code.
88*4882a593Smuzhiyun */
89*4882a593Smuzhiyun int (*of_xlate)(struct phy *phy, struct ofnode_phandle_args *args);
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /**
92*4882a593Smuzhiyun * init - initialize the hardware.
93*4882a593Smuzhiyun *
94*4882a593Smuzhiyun * Hardware intialization should not be done in during probe() but
95*4882a593Smuzhiyun * should be implemented in this init() function. It could be starting
96*4882a593Smuzhiyun * PLL, taking a controller out of reset, routing, etc. This function
97*4882a593Smuzhiyun * is typically called only once per PHY port.
98*4882a593Smuzhiyun * If power_on() is not implemented, it must power up the phy.
99*4882a593Smuzhiyun *
100*4882a593Smuzhiyun * @phy: the PHY port to initialize
101*4882a593Smuzhiyun * @return 0 if OK, or a negative error code.
102*4882a593Smuzhiyun */
103*4882a593Smuzhiyun int (*init)(struct phy *phy);
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun /**
106*4882a593Smuzhiyun * exit - de-initialize the PHY device
107*4882a593Smuzhiyun *
108*4882a593Smuzhiyun * Hardware de-intialization should be done here. Every step done in
109*4882a593Smuzhiyun * init() should be undone here.
110*4882a593Smuzhiyun * This could be used to suspend the phy to reduce power consumption or
111*4882a593Smuzhiyun * to put the phy in a known condition before booting the OS (though it
112*4882a593Smuzhiyun * is NOT called automatically before booting the OS)
113*4882a593Smuzhiyun * If power_off() is not implemented, it must power down the phy.
114*4882a593Smuzhiyun *
115*4882a593Smuzhiyun * @phy: PHY port to be de-initialized
116*4882a593Smuzhiyun * @return 0 if OK, or a negative error code
117*4882a593Smuzhiyun */
118*4882a593Smuzhiyun int (*exit)(struct phy *phy);
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun /**
121*4882a593Smuzhiyun * reset - resets a PHY device without shutting down
122*4882a593Smuzhiyun *
123*4882a593Smuzhiyun * @phy: PHY port to be reset
124*4882a593Smuzhiyun *
125*4882a593Smuzhiyun * During runtime, the PHY may need to be reset in order to
126*4882a593Smuzhiyun * re-establish connection etc without being shut down or exit.
127*4882a593Smuzhiyun *
128*4882a593Smuzhiyun * @return 0 if OK, or a negative error code
129*4882a593Smuzhiyun */
130*4882a593Smuzhiyun int (*reset)(struct phy *phy);
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun /**
133*4882a593Smuzhiyun * @configure:
134*4882a593Smuzhiyun *
135*4882a593Smuzhiyun * Optional.
136*4882a593Smuzhiyun *
137*4882a593Smuzhiyun * Used to change the PHY parameters. phy_init() must have
138*4882a593Smuzhiyun * been called on the phy.
139*4882a593Smuzhiyun *
140*4882a593Smuzhiyun * Returns: 0 if successful, an negative error code otherwise
141*4882a593Smuzhiyun */
142*4882a593Smuzhiyun int (*configure)(struct phy *phy, union phy_configure_opts *opts);
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun /**
145*4882a593Smuzhiyun * @validate:
146*4882a593Smuzhiyun *
147*4882a593Smuzhiyun * Optional.
148*4882a593Smuzhiyun *
149*4882a593Smuzhiyun * Used to check that the current set of parameters can be
150*4882a593Smuzhiyun * handled by the phy. Implementations are free to tune the
151*4882a593Smuzhiyun * parameters passed as arguments if needed by some
152*4882a593Smuzhiyun * implementation detail or constraints. It must not change
153*4882a593Smuzhiyun * any actual configuration of the PHY, so calling it as many
154*4882a593Smuzhiyun * times as deemed fit by the consumer must have no side
155*4882a593Smuzhiyun * effect.
156*4882a593Smuzhiyun *
157*4882a593Smuzhiyun * Returns: 0 if the configuration can be applied, an negative
158*4882a593Smuzhiyun * error code otherwise
159*4882a593Smuzhiyun */
160*4882a593Smuzhiyun int (*validate)(struct phy *phy, enum phy_mode mode, int submode,
161*4882a593Smuzhiyun union phy_configure_opts *opts);
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun /**
164*4882a593Smuzhiyun * power_on - power on a PHY device
165*4882a593Smuzhiyun *
166*4882a593Smuzhiyun * @phy: PHY port to be powered on
167*4882a593Smuzhiyun *
168*4882a593Smuzhiyun * During runtime, the PHY may need to be powered on or off several
169*4882a593Smuzhiyun * times. This function is used to power on the PHY. It relies on the
170*4882a593Smuzhiyun * setup done in init(). If init() is not implemented, it must take care
171*4882a593Smuzhiyun * of setting up the context (PLLs, ...)
172*4882a593Smuzhiyun *
173*4882a593Smuzhiyun * @return 0 if OK, or a negative error code
174*4882a593Smuzhiyun */
175*4882a593Smuzhiyun int (*power_on)(struct phy *phy);
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun /**
178*4882a593Smuzhiyun * power_off - power off a PHY device
179*4882a593Smuzhiyun *
180*4882a593Smuzhiyun * @phy: PHY port to be powered off
181*4882a593Smuzhiyun *
182*4882a593Smuzhiyun * During runtime, the PHY may need to be powered on or off several
183*4882a593Smuzhiyun * times. This function is used to power off the PHY. Except if
184*4882a593Smuzhiyun * init()/deinit() are not implemented, it must not de-initialize
185*4882a593Smuzhiyun * everything.
186*4882a593Smuzhiyun *
187*4882a593Smuzhiyun * @return 0 if OK, or a negative error code
188*4882a593Smuzhiyun */
189*4882a593Smuzhiyun int (*power_off)(struct phy *phy);
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun int (*set_mode)(struct phy *phy, enum phy_mode mode, int submode);
192*4882a593Smuzhiyun };
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun #ifdef CONFIG_PHY
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun /**
197*4882a593Smuzhiyun * generic_phy_init() - initialize the PHY port
198*4882a593Smuzhiyun *
199*4882a593Smuzhiyun * @phy: the PHY port to initialize
200*4882a593Smuzhiyun * @return 0 if OK, or a negative error code
201*4882a593Smuzhiyun */
202*4882a593Smuzhiyun int generic_phy_init(struct phy *phy);
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun /**
205*4882a593Smuzhiyun * generic_phy_init() - de-initialize the PHY device
206*4882a593Smuzhiyun *
207*4882a593Smuzhiyun * @phy: PHY port to be de-initialized
208*4882a593Smuzhiyun * @return 0 if OK, or a negative error code
209*4882a593Smuzhiyun */
210*4882a593Smuzhiyun int generic_phy_exit(struct phy *phy);
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun /**
213*4882a593Smuzhiyun * generic_phy_reset() - resets a PHY device without shutting down
214*4882a593Smuzhiyun *
215*4882a593Smuzhiyun * @phy: PHY port to be reset
216*4882a593Smuzhiyun *@return 0 if OK, or a negative error code
217*4882a593Smuzhiyun */
218*4882a593Smuzhiyun int generic_phy_reset(struct phy *phy);
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun /**
221*4882a593Smuzhiyun * generic_phy_configure() - change the PHY parameters
222*4882a593Smuzhiyun *
223*4882a593Smuzhiyun * @phy: PHY port to be configure
224*4882a593Smuzhiyun * @return 0 if OK, or a negative error code
225*4882a593Smuzhiyun */
226*4882a593Smuzhiyun int generic_phy_configure(struct phy *phy, union phy_configure_opts *opts);
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun /**
229*4882a593Smuzhiyun * generic_phy_validate() - validate the PHY parameters
230*4882a593Smuzhiyun *
231*4882a593Smuzhiyun * @phy: PHY port to be validate
232*4882a593Smuzhiyun * @return 0 if OK, or a negative error code
233*4882a593Smuzhiyun */
234*4882a593Smuzhiyun int generic_phy_validate(struct phy *phy, enum phy_mode mode, int submode,
235*4882a593Smuzhiyun union phy_configure_opts *opts);
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun /**
238*4882a593Smuzhiyun * generic_phy_power_on() - power on a PHY device
239*4882a593Smuzhiyun *
240*4882a593Smuzhiyun * @phy: PHY port to be powered on
241*4882a593Smuzhiyun * @return 0 if OK, or a negative error code
242*4882a593Smuzhiyun */
243*4882a593Smuzhiyun int generic_phy_power_on(struct phy *phy);
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun /**
246*4882a593Smuzhiyun * generic_phy_power_off() - power off a PHY device
247*4882a593Smuzhiyun *
248*4882a593Smuzhiyun * @phy: PHY port to be powered off
249*4882a593Smuzhiyun * @return 0 if OK, or a negative error code
250*4882a593Smuzhiyun */
251*4882a593Smuzhiyun int generic_phy_power_off(struct phy *phy);
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun int generic_phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode);
254*4882a593Smuzhiyun #define generic_phy_set_mode(phy, mode) \
255*4882a593Smuzhiyun generic_phy_set_mode_ext(phy, mode, 0)
256*4882a593Smuzhiyun
generic_phy_get_mode(struct phy * phy)257*4882a593Smuzhiyun static inline enum phy_mode generic_phy_get_mode(struct phy *phy)
258*4882a593Smuzhiyun {
259*4882a593Smuzhiyun return phy->attrs.mode;
260*4882a593Smuzhiyun }
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun /**
263*4882a593Smuzhiyun * generic_phy_get_by_index() - Get a PHY device by integer index.
264*4882a593Smuzhiyun *
265*4882a593Smuzhiyun * @user: the client device
266*4882a593Smuzhiyun * @index: The index in the list of available PHYs
267*4882a593Smuzhiyun * @phy: A pointer to the PHY port
268*4882a593Smuzhiyun *
269*4882a593Smuzhiyun * This looks up a PHY device for a client device based on its position in the
270*4882a593Smuzhiyun * list of the possible PHYs.
271*4882a593Smuzhiyun *
272*4882a593Smuzhiyun * example:
273*4882a593Smuzhiyun * usb1: usb_otg_ss@xxx {
274*4882a593Smuzhiyun * compatible = "xxx";
275*4882a593Smuzhiyun * reg = <xxx>;
276*4882a593Smuzhiyun * .
277*4882a593Smuzhiyun * .
278*4882a593Smuzhiyun * phys = <&usb2_phy>, <&usb3_phy>;
279*4882a593Smuzhiyun * .
280*4882a593Smuzhiyun * .
281*4882a593Smuzhiyun * };
282*4882a593Smuzhiyun * the USB2 phy can be accessed by passing index '0' and the USB3 phy can
283*4882a593Smuzhiyun * be accessed by passing index '1'
284*4882a593Smuzhiyun *
285*4882a593Smuzhiyun * @return 0 if OK, or a negative error code
286*4882a593Smuzhiyun */
287*4882a593Smuzhiyun int generic_phy_get_by_index(struct udevice *user, int index,
288*4882a593Smuzhiyun struct phy *phy);
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun /**
291*4882a593Smuzhiyun * generic_phy_get_by_name() - Get a PHY device by its name.
292*4882a593Smuzhiyun *
293*4882a593Smuzhiyun * @user: the client device
294*4882a593Smuzhiyun * @phy_name: The name of the PHY in the list of possible PHYs
295*4882a593Smuzhiyun * @phy: A pointer to the PHY port
296*4882a593Smuzhiyun *
297*4882a593Smuzhiyun * This looks up a PHY device for a client device in the
298*4882a593Smuzhiyun * list of the possible PHYs based on its name.
299*4882a593Smuzhiyun *
300*4882a593Smuzhiyun * example:
301*4882a593Smuzhiyun * usb1: usb_otg_ss@xxx {
302*4882a593Smuzhiyun * compatible = "xxx";
303*4882a593Smuzhiyun * reg = <xxx>;
304*4882a593Smuzhiyun * .
305*4882a593Smuzhiyun * .
306*4882a593Smuzhiyun * phys = <&usb2_phy>, <&usb3_phy>;
307*4882a593Smuzhiyun * phy-names = "usb2phy", "usb3phy";
308*4882a593Smuzhiyun * .
309*4882a593Smuzhiyun * .
310*4882a593Smuzhiyun * };
311*4882a593Smuzhiyun * the USB3 phy can be accessed using "usb3phy", and USB2 by using "usb2phy"
312*4882a593Smuzhiyun *
313*4882a593Smuzhiyun * @return 0 if OK, or a negative error code
314*4882a593Smuzhiyun */
315*4882a593Smuzhiyun int generic_phy_get_by_name(struct udevice *user, const char *phy_name,
316*4882a593Smuzhiyun struct phy *phy);
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun #else /* CONFIG_PHY */
319*4882a593Smuzhiyun
generic_phy_init(struct phy * phy)320*4882a593Smuzhiyun static inline int generic_phy_init(struct phy *phy)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun return 0;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
generic_phy_exit(struct phy * phy)325*4882a593Smuzhiyun static inline int generic_phy_exit(struct phy *phy)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun return 0;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun
generic_phy_reset(struct phy * phy)330*4882a593Smuzhiyun static inline int generic_phy_reset(struct phy *phy)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun return 0;
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun
generic_phy_configure(struct phy * phy,union phy_configure_opts * opts)335*4882a593Smuzhiyun static inline int generic_phy_configure(struct phy *phy,
336*4882a593Smuzhiyun union phy_configure_opts *opts)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun return 0;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun
generic_phy_validate(struct phy * phy,enum phy_mode mode,int submode,union phy_configure_opts * opts)341*4882a593Smuzhiyun static inline int generic_phy_validate(struct phy *phy, enum phy_mode mode,
342*4882a593Smuzhiyun int submode,
343*4882a593Smuzhiyun union phy_configure_opts *opts)
344*4882a593Smuzhiyun {
345*4882a593Smuzhiyun return 0;
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun
generic_phy_power_on(struct phy * phy)348*4882a593Smuzhiyun static inline int generic_phy_power_on(struct phy *phy)
349*4882a593Smuzhiyun {
350*4882a593Smuzhiyun return 0;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun
generic_phy_power_off(struct phy * phy)353*4882a593Smuzhiyun static inline int generic_phy_power_off(struct phy *phy)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun return 0;
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun
generic_phy_get_by_index(struct udevice * user,int index,struct phy * phy)358*4882a593Smuzhiyun static inline int generic_phy_get_by_index(struct udevice *user, int index,
359*4882a593Smuzhiyun struct phy *phy)
360*4882a593Smuzhiyun {
361*4882a593Smuzhiyun return 0;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun
generic_phy_get_by_name(struct udevice * user,const char * phy_name,struct phy * phy)364*4882a593Smuzhiyun static inline int generic_phy_get_by_name(struct udevice *user, const char *phy_name,
365*4882a593Smuzhiyun struct phy *phy)
366*4882a593Smuzhiyun {
367*4882a593Smuzhiyun return 0;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun
generic_phy_set_mode_ext(struct phy * phy,enum phy_mode mode,int submode)370*4882a593Smuzhiyun static inline int generic_phy_set_mode_ext(struct phy *phy, enum phy_mode mode,
371*4882a593Smuzhiyun int submode)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun return 0;
374*4882a593Smuzhiyun }
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun #define generic_phy_set_mode(phy, mode) \
377*4882a593Smuzhiyun generic_phy_set_mode_ext(phy, mode, 0)
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun #endif /* CONFIG_PHY */
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun /**
382*4882a593Smuzhiyun * generic_phy_valid() - check if PHY port is valid
383*4882a593Smuzhiyun *
384*4882a593Smuzhiyun * @phy: the PHY port to check
385*4882a593Smuzhiyun * @return TRUE if valid, or FALSE
386*4882a593Smuzhiyun */
generic_phy_valid(struct phy * phy)387*4882a593Smuzhiyun static inline bool generic_phy_valid(struct phy *phy)
388*4882a593Smuzhiyun {
389*4882a593Smuzhiyun return phy && phy->dev;
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun #endif /*__GENERIC_PHY_H */
393