xref: /openbmc/u-boot/include/generic-phy.h (revision b2f90c46)
183d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */
272e5016fSJean-Jacques Hiblot /*
372e5016fSJean-Jacques Hiblot  * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
472e5016fSJean-Jacques Hiblot  * Written by Jean-Jacques Hiblot  <jjhiblot@ti.com>
572e5016fSJean-Jacques Hiblot  */
672e5016fSJean-Jacques Hiblot 
772e5016fSJean-Jacques Hiblot #ifndef __GENERIC_PHY_H
872e5016fSJean-Jacques Hiblot #define __GENERIC_PHY_H
972e5016fSJean-Jacques Hiblot 
10*a265e5efSMarek Vasut struct ofnode_phandle_args;
1172e5016fSJean-Jacques Hiblot 
1272e5016fSJean-Jacques Hiblot /**
1372e5016fSJean-Jacques Hiblot  * struct phy - A handle to (allowing control of) a single phy port.
1472e5016fSJean-Jacques Hiblot  *
1572e5016fSJean-Jacques Hiblot  * Clients provide storage for phy handles. The content of the structure is
1672e5016fSJean-Jacques Hiblot  * managed solely by the PHY API and PHY drivers. A phy struct is
1772e5016fSJean-Jacques Hiblot  * initialized by "get"ing the phy struct. The phy struct is passed to all
1872e5016fSJean-Jacques Hiblot  * other phy APIs to identify which PHY port to operate upon.
1972e5016fSJean-Jacques Hiblot  *
2072e5016fSJean-Jacques Hiblot  * @dev: The device which implements the PHY port.
2172e5016fSJean-Jacques Hiblot  * @id: The PHY ID within the provider.
2272e5016fSJean-Jacques Hiblot  *
2372e5016fSJean-Jacques Hiblot  */
2472e5016fSJean-Jacques Hiblot struct phy {
2572e5016fSJean-Jacques Hiblot 	struct udevice *dev;
2672e5016fSJean-Jacques Hiblot 	unsigned long id;
2772e5016fSJean-Jacques Hiblot };
2872e5016fSJean-Jacques Hiblot 
2972e5016fSJean-Jacques Hiblot /*
3072e5016fSJean-Jacques Hiblot  * struct udevice_ops - set of function pointers for phy operations
3172e5016fSJean-Jacques Hiblot  * @init: operation to be performed for initializing phy (optional)
3272e5016fSJean-Jacques Hiblot  * @exit: operation to be performed while exiting (optional)
3372e5016fSJean-Jacques Hiblot  * @reset: reset the phy (optional).
3472e5016fSJean-Jacques Hiblot  * @power_on: powering on the phy (optional)
3572e5016fSJean-Jacques Hiblot  * @power_off: powering off the phy (optional)
3672e5016fSJean-Jacques Hiblot  */
3772e5016fSJean-Jacques Hiblot struct phy_ops {
3872e5016fSJean-Jacques Hiblot 	/**
3972e5016fSJean-Jacques Hiblot 	 * of_xlate - Translate a client's device-tree (OF) phy specifier.
4072e5016fSJean-Jacques Hiblot 	 *
4172e5016fSJean-Jacques Hiblot 	 * The PHY core calls this function as the first step in implementing
4272e5016fSJean-Jacques Hiblot 	 * a client's generic_phy_get_by_*() call.
4372e5016fSJean-Jacques Hiblot 	 *
4472e5016fSJean-Jacques Hiblot 	 * If this function pointer is set to NULL, the PHY core will use a
4572e5016fSJean-Jacques Hiblot 	 * default implementation, which assumes #phy-cells = <0> or
4672e5016fSJean-Jacques Hiblot 	 * #phy-cells = <1>, and in the later case that the DT cell
4772e5016fSJean-Jacques Hiblot 	 * contains a simple integer PHY port ID.
4872e5016fSJean-Jacques Hiblot 	 *
4972e5016fSJean-Jacques Hiblot 	 * @phy:	The phy struct to hold the translation result.
5072e5016fSJean-Jacques Hiblot 	 * @args:	The phy specifier values from device tree.
5172e5016fSJean-Jacques Hiblot 	 * @return 0 if OK, or a negative error code.
5272e5016fSJean-Jacques Hiblot 	 */
5323558bb6SSimon Glass 	int	(*of_xlate)(struct phy *phy, struct ofnode_phandle_args *args);
5472e5016fSJean-Jacques Hiblot 
5572e5016fSJean-Jacques Hiblot 	/**
5672e5016fSJean-Jacques Hiblot 	 * init - initialize the hardware.
5772e5016fSJean-Jacques Hiblot 	 *
5872e5016fSJean-Jacques Hiblot 	 * Hardware intialization should not be done in during probe() but
5972e5016fSJean-Jacques Hiblot 	 * should be implemented in this init() function. It could be starting
6072e5016fSJean-Jacques Hiblot 	 * PLL, taking a controller out of reset, routing, etc. This function
6172e5016fSJean-Jacques Hiblot 	 * is typically called only once per PHY port.
6272e5016fSJean-Jacques Hiblot 	 * If power_on() is not implemented, it must power up the phy.
6372e5016fSJean-Jacques Hiblot 	 *
6472e5016fSJean-Jacques Hiblot 	 * @phy:	the PHY port to initialize
6572e5016fSJean-Jacques Hiblot 	 * @return 0 if OK, or a negative error code.
6672e5016fSJean-Jacques Hiblot 	 */
6772e5016fSJean-Jacques Hiblot 	int	(*init)(struct phy *phy);
6872e5016fSJean-Jacques Hiblot 
6972e5016fSJean-Jacques Hiblot 	/**
7072e5016fSJean-Jacques Hiblot 	* exit - de-initialize the PHY device
7172e5016fSJean-Jacques Hiblot 	*
7272e5016fSJean-Jacques Hiblot 	* Hardware de-intialization should be done here. Every step done in
7372e5016fSJean-Jacques Hiblot 	* init() should be undone here.
7472e5016fSJean-Jacques Hiblot 	* This could be used to suspend the phy to reduce power consumption or
7572e5016fSJean-Jacques Hiblot 	* to put the phy in a known condition before booting the OS (though it
7672e5016fSJean-Jacques Hiblot 	* is NOT called automatically before booting the OS)
7772e5016fSJean-Jacques Hiblot 	* If power_off() is not implemented, it must power down the phy.
7872e5016fSJean-Jacques Hiblot 	*
7972e5016fSJean-Jacques Hiblot 	* @phy:	PHY port to be de-initialized
8072e5016fSJean-Jacques Hiblot 	* @return 0 if OK, or a negative error code
8172e5016fSJean-Jacques Hiblot 	*/
8272e5016fSJean-Jacques Hiblot 	int	(*exit)(struct phy *phy);
8372e5016fSJean-Jacques Hiblot 
8472e5016fSJean-Jacques Hiblot 	/**
8572e5016fSJean-Jacques Hiblot 	* reset - resets a PHY device without shutting down
8672e5016fSJean-Jacques Hiblot 	*
8772e5016fSJean-Jacques Hiblot 	* @phy:	PHY port to be reset
8872e5016fSJean-Jacques Hiblot 	*
8972e5016fSJean-Jacques Hiblot 	* During runtime, the PHY may need to be reset in order to
9072e5016fSJean-Jacques Hiblot 	* re-establish connection etc without being shut down or exit.
9172e5016fSJean-Jacques Hiblot 	*
9272e5016fSJean-Jacques Hiblot 	* @return 0 if OK, or a negative error code
9372e5016fSJean-Jacques Hiblot 	*/
9472e5016fSJean-Jacques Hiblot 	int	(*reset)(struct phy *phy);
9572e5016fSJean-Jacques Hiblot 
9672e5016fSJean-Jacques Hiblot 	/**
9772e5016fSJean-Jacques Hiblot 	* power_on - power on a PHY device
9872e5016fSJean-Jacques Hiblot 	*
9972e5016fSJean-Jacques Hiblot 	* @phy:	PHY port to be powered on
10072e5016fSJean-Jacques Hiblot 	*
10172e5016fSJean-Jacques Hiblot 	* During runtime, the PHY may need to be powered on or off several
10272e5016fSJean-Jacques Hiblot 	* times. This function is used to power on the PHY. It relies on the
10372e5016fSJean-Jacques Hiblot 	* setup done in init(). If init() is not implemented, it must take care
10472e5016fSJean-Jacques Hiblot 	* of setting up the context (PLLs, ...)
10572e5016fSJean-Jacques Hiblot 	*
10672e5016fSJean-Jacques Hiblot 	* @return 0 if OK, or a negative error code
10772e5016fSJean-Jacques Hiblot 	*/
10872e5016fSJean-Jacques Hiblot 	int	(*power_on)(struct phy *phy);
10972e5016fSJean-Jacques Hiblot 
11072e5016fSJean-Jacques Hiblot 	/**
11172e5016fSJean-Jacques Hiblot 	* power_off - power off a PHY device
11272e5016fSJean-Jacques Hiblot 	*
11372e5016fSJean-Jacques Hiblot 	* @phy:	PHY port to be powered off
11472e5016fSJean-Jacques Hiblot 	*
11572e5016fSJean-Jacques Hiblot 	* During runtime, the PHY may need to be powered on or off several
11672e5016fSJean-Jacques Hiblot 	* times. This function is used to power off the PHY. Except if
11772e5016fSJean-Jacques Hiblot 	* init()/deinit() are not implemented, it must not de-initialize
11872e5016fSJean-Jacques Hiblot 	* everything.
11972e5016fSJean-Jacques Hiblot 	*
12072e5016fSJean-Jacques Hiblot 	* @return 0 if OK, or a negative error code
12172e5016fSJean-Jacques Hiblot 	*/
12272e5016fSJean-Jacques Hiblot 	int	(*power_off)(struct phy *phy);
12372e5016fSJean-Jacques Hiblot };
12472e5016fSJean-Jacques Hiblot 
125d9fb7becSPatrice Chotard #ifdef CONFIG_PHY
12672e5016fSJean-Jacques Hiblot 
12772e5016fSJean-Jacques Hiblot /**
12872e5016fSJean-Jacques Hiblot  * generic_phy_init() - initialize the PHY port
12972e5016fSJean-Jacques Hiblot  *
13072e5016fSJean-Jacques Hiblot  * @phy:	the PHY port to initialize
13172e5016fSJean-Jacques Hiblot  * @return 0 if OK, or a negative error code
13272e5016fSJean-Jacques Hiblot  */
13372e5016fSJean-Jacques Hiblot int generic_phy_init(struct phy *phy);
13472e5016fSJean-Jacques Hiblot 
13572e5016fSJean-Jacques Hiblot /**
13672e5016fSJean-Jacques Hiblot  * generic_phy_init() - de-initialize the PHY device
13772e5016fSJean-Jacques Hiblot  *
13872e5016fSJean-Jacques Hiblot  * @phy:	PHY port to be de-initialized
13972e5016fSJean-Jacques Hiblot  * @return 0 if OK, or a negative error code
14072e5016fSJean-Jacques Hiblot  */
14172e5016fSJean-Jacques Hiblot int generic_phy_exit(struct phy *phy);
14272e5016fSJean-Jacques Hiblot 
14372e5016fSJean-Jacques Hiblot /**
14472e5016fSJean-Jacques Hiblot  * generic_phy_reset() - resets a PHY device without shutting down
14572e5016fSJean-Jacques Hiblot  *
14672e5016fSJean-Jacques Hiblot  * @phy:	PHY port to be reset
14772e5016fSJean-Jacques Hiblot  *@return 0 if OK, or a negative error code
14872e5016fSJean-Jacques Hiblot  */
14972e5016fSJean-Jacques Hiblot int generic_phy_reset(struct phy *phy);
15072e5016fSJean-Jacques Hiblot 
15172e5016fSJean-Jacques Hiblot /**
15272e5016fSJean-Jacques Hiblot  * generic_phy_power_on() - power on a PHY device
15372e5016fSJean-Jacques Hiblot  *
15472e5016fSJean-Jacques Hiblot  * @phy:	PHY port to be powered on
15572e5016fSJean-Jacques Hiblot  * @return 0 if OK, or a negative error code
15672e5016fSJean-Jacques Hiblot  */
15772e5016fSJean-Jacques Hiblot int generic_phy_power_on(struct phy *phy);
15872e5016fSJean-Jacques Hiblot 
15972e5016fSJean-Jacques Hiblot /**
16072e5016fSJean-Jacques Hiblot  * generic_phy_power_off() - power off a PHY device
16172e5016fSJean-Jacques Hiblot  *
16272e5016fSJean-Jacques Hiblot  * @phy:	PHY port to be powered off
16372e5016fSJean-Jacques Hiblot  * @return 0 if OK, or a negative error code
16472e5016fSJean-Jacques Hiblot  */
16572e5016fSJean-Jacques Hiblot int generic_phy_power_off(struct phy *phy);
16672e5016fSJean-Jacques Hiblot 
16772e5016fSJean-Jacques Hiblot 
16872e5016fSJean-Jacques Hiblot /**
16972e5016fSJean-Jacques Hiblot  * generic_phy_get_by_index() - Get a PHY device by integer index.
17072e5016fSJean-Jacques Hiblot  *
17172e5016fSJean-Jacques Hiblot  * @user:	the client device
17272e5016fSJean-Jacques Hiblot  * @index:	The index in the list of available PHYs
17372e5016fSJean-Jacques Hiblot  * @phy:	A pointer to the PHY port
17472e5016fSJean-Jacques Hiblot  *
17572e5016fSJean-Jacques Hiblot  * This looks up a PHY device for a client device based on its position in the
17672e5016fSJean-Jacques Hiblot  * list of the possible PHYs.
17772e5016fSJean-Jacques Hiblot  *
17872e5016fSJean-Jacques Hiblot  * example:
17972e5016fSJean-Jacques Hiblot  * usb1: usb_otg_ss@xxx {
18072e5016fSJean-Jacques Hiblot  *       compatible = "xxx";
18172e5016fSJean-Jacques Hiblot  *       reg = <xxx>;
18272e5016fSJean-Jacques Hiblot  *   .
18372e5016fSJean-Jacques Hiblot  *   .
18472e5016fSJean-Jacques Hiblot  *   phys = <&usb2_phy>, <&usb3_phy>;
18572e5016fSJean-Jacques Hiblot  *   .
18672e5016fSJean-Jacques Hiblot  *   .
18772e5016fSJean-Jacques Hiblot  * };
18872e5016fSJean-Jacques Hiblot  * the USB2 phy can be accessed by passing index '0' and the USB3 phy can
18972e5016fSJean-Jacques Hiblot  * be accessed by passing index '1'
19072e5016fSJean-Jacques Hiblot  *
19172e5016fSJean-Jacques Hiblot  * @return 0 if OK, or a negative error code
19272e5016fSJean-Jacques Hiblot  */
19372e5016fSJean-Jacques Hiblot int generic_phy_get_by_index(struct udevice *user, int index,
19472e5016fSJean-Jacques Hiblot 			     struct phy *phy);
19572e5016fSJean-Jacques Hiblot 
19672e5016fSJean-Jacques Hiblot /**
19772e5016fSJean-Jacques Hiblot  * generic_phy_get_by_name() - Get a PHY device by its name.
19872e5016fSJean-Jacques Hiblot  *
19972e5016fSJean-Jacques Hiblot  * @user:	the client device
20072e5016fSJean-Jacques Hiblot  * @phy_name:	The name of the PHY in the list of possible PHYs
20172e5016fSJean-Jacques Hiblot  * @phy:	A pointer to the PHY port
20272e5016fSJean-Jacques Hiblot  *
20372e5016fSJean-Jacques Hiblot  * This looks up a PHY device for a client device in the
20472e5016fSJean-Jacques Hiblot  * list of the possible PHYs based on its name.
20572e5016fSJean-Jacques Hiblot  *
20672e5016fSJean-Jacques Hiblot  * example:
20772e5016fSJean-Jacques Hiblot  * usb1: usb_otg_ss@xxx {
20872e5016fSJean-Jacques Hiblot  *       compatible = "xxx";
20972e5016fSJean-Jacques Hiblot  *       reg = <xxx>;
21072e5016fSJean-Jacques Hiblot  *   .
21172e5016fSJean-Jacques Hiblot  *   .
21272e5016fSJean-Jacques Hiblot  *   phys = <&usb2_phy>, <&usb3_phy>;
21372e5016fSJean-Jacques Hiblot  *   phy-names = "usb2phy", "usb3phy";
21472e5016fSJean-Jacques Hiblot  *   .
21572e5016fSJean-Jacques Hiblot  *   .
21672e5016fSJean-Jacques Hiblot  * };
21772e5016fSJean-Jacques Hiblot  * the USB3 phy can be accessed using "usb3phy", and USB2 by using "usb2phy"
21872e5016fSJean-Jacques Hiblot  *
21972e5016fSJean-Jacques Hiblot  * @return 0 if OK, or a negative error code
22072e5016fSJean-Jacques Hiblot  */
22172e5016fSJean-Jacques Hiblot int generic_phy_get_by_name(struct udevice *user, const char *phy_name,
22272e5016fSJean-Jacques Hiblot 			    struct phy *phy);
22372e5016fSJean-Jacques Hiblot 
224d9fb7becSPatrice Chotard #else /* CONFIG_PHY */
225d9fb7becSPatrice Chotard 
generic_phy_init(struct phy * phy)226d9fb7becSPatrice Chotard static inline int generic_phy_init(struct phy *phy)
227d9fb7becSPatrice Chotard {
228d9fb7becSPatrice Chotard 	return 0;
229d9fb7becSPatrice Chotard }
230d9fb7becSPatrice Chotard 
generic_phy_exit(struct phy * phy)231d9fb7becSPatrice Chotard static inline int generic_phy_exit(struct phy *phy)
232d9fb7becSPatrice Chotard {
233d9fb7becSPatrice Chotard 	return 0;
234d9fb7becSPatrice Chotard }
235d9fb7becSPatrice Chotard 
generic_phy_reset(struct phy * phy)236d9fb7becSPatrice Chotard static inline int generic_phy_reset(struct phy *phy)
237d9fb7becSPatrice Chotard {
238d9fb7becSPatrice Chotard 	return 0;
239d9fb7becSPatrice Chotard }
240d9fb7becSPatrice Chotard 
generic_phy_power_on(struct phy * phy)241d9fb7becSPatrice Chotard static inline int generic_phy_power_on(struct phy *phy)
242d9fb7becSPatrice Chotard {
243d9fb7becSPatrice Chotard 	return 0;
244d9fb7becSPatrice Chotard }
245d9fb7becSPatrice Chotard 
generic_phy_power_off(struct phy * phy)246d9fb7becSPatrice Chotard static inline int generic_phy_power_off(struct phy *phy)
247d9fb7becSPatrice Chotard {
248d9fb7becSPatrice Chotard 	return 0;
249d9fb7becSPatrice Chotard }
250d9fb7becSPatrice Chotard 
generic_phy_get_by_index(struct udevice * user,int index,struct phy * phy)251d9fb7becSPatrice Chotard static inline int generic_phy_get_by_index(struct udevice *user, int index,
252d9fb7becSPatrice Chotard 			     struct phy *phy)
253d9fb7becSPatrice Chotard {
254d9fb7becSPatrice Chotard 	return 0;
255d9fb7becSPatrice Chotard }
256d9fb7becSPatrice Chotard 
generic_phy_get_by_name(struct udevice * user,const char * phy_name,struct phy * phy)257d9fb7becSPatrice Chotard static inline int generic_phy_get_by_name(struct udevice *user, const char *phy_name,
258d9fb7becSPatrice Chotard 			    struct phy *phy)
259d9fb7becSPatrice Chotard {
260d9fb7becSPatrice Chotard 	return 0;
261d9fb7becSPatrice Chotard }
262d9fb7becSPatrice Chotard 
263d9fb7becSPatrice Chotard #endif /* CONFIG_PHY */
264d9fb7becSPatrice Chotard 
265b94888b4SPatrice Chotard /**
266b94888b4SPatrice Chotard  * generic_phy_valid() - check if PHY port is valid
267b94888b4SPatrice Chotard  *
268b94888b4SPatrice Chotard  * @phy:	the PHY port to check
269b94888b4SPatrice Chotard  * @return TRUE if valid, or FALSE
270b94888b4SPatrice Chotard  */
generic_phy_valid(struct phy * phy)271b94888b4SPatrice Chotard static inline bool generic_phy_valid(struct phy *phy)
272b94888b4SPatrice Chotard {
273b94888b4SPatrice Chotard 	return phy->dev != NULL;
274b94888b4SPatrice Chotard }
275b94888b4SPatrice Chotard 
27672e5016fSJean-Jacques Hiblot #endif /*__GENERIC_PHY_H */
277