diff options
Diffstat (limited to 'include/linux/phy')
| -rw-r--r-- | include/linux/phy/phy-mipi-dphy.h | 285 | ||||
| -rw-r--r-- | include/linux/phy/phy.h | 85 | 
2 files changed, 362 insertions, 8 deletions
diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h new file mode 100644 index 000000000000..c08aacc0ac35 --- /dev/null +++ b/include/linux/phy/phy-mipi-dphy.h @@ -0,0 +1,285 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Cadence Design Systems Inc. + */ + +#ifndef __PHY_MIPI_DPHY_H_ +#define __PHY_MIPI_DPHY_H_ + +#include <video/videomode.h> + +/** + * struct phy_configure_opts_mipi_dphy - MIPI D-PHY configuration set + * + * This structure is used to represent the configuration state of a + * MIPI D-PHY phy. + */ +struct phy_configure_opts_mipi_dphy { +	/** +	 * @clk_miss: +	 * +	 * Timeout, in picoseconds, for receiver to detect absence of +	 * Clock transitions and disable the Clock Lane HS-RX. +	 * +	 * Maximum value: 60000 ps +	 */ +	unsigned int		clk_miss; + +	/** +	 * @clk_post: +	 * +	 * Time, in picoseconds, that the transmitter continues to +	 * send HS clock after the last associated Data Lane has +	 * transitioned to LP Mode. Interval is defined as the period +	 * from the end of @hs_trail to the beginning of @clk_trail. +	 * +	 * Minimum value: 60000 ps + 52 * @hs_clk_rate period in ps +	 */ +	unsigned int		clk_post; + +	/** +	 * @clk_pre: +	 * +	 * Time, in UI, that the HS clock shall be driven by +	 * the transmitter prior to any associated Data Lane beginning +	 * the transition from LP to HS mode. +	 * +	 * Minimum value: 8 UI +	 */ +	unsigned int		clk_pre; + +	/** +	 * @clk_prepare: +	 * +	 * Time, in picoseconds, that the transmitter drives the Clock +	 * Lane LP-00 Line state immediately before the HS-0 Line +	 * state starting the HS transmission. +	 * +	 * Minimum value: 38000 ps +	 * Maximum value: 95000 ps +	 */ +	unsigned int		clk_prepare; + +	/** +	 * @clk_settle: +	 * +	 * Time interval, in picoseconds, during which the HS receiver +	 * should ignore any Clock Lane HS transitions, starting from +	 * the beginning of @clk_prepare. +	 * +	 * Minimum value: 95000 ps +	 * Maximum value: 300000 ps +	 */ +	unsigned int		clk_settle; + +	/** +	 * @clk_term_en: +	 * +	 * Time, in picoseconds, for the Clock Lane receiver to enable +	 * the HS line termination. +	 * +	 * Maximum value: 38000 ps +	 */ +	unsigned int		clk_term_en; + +	/** +	 * @clk_trail: +	 * +	 * Time, in picoseconds, that the transmitter drives the HS-0 +	 * state after the last payload clock bit of a HS transmission +	 * burst. +	 * +	 * Minimum value: 60000 ps +	 */ +	unsigned int		clk_trail; + +	/** +	 * @clk_zero: +	 * +	 * Time, in picoseconds, that the transmitter drives the HS-0 +	 * state prior to starting the Clock. +	 */ +	unsigned int		clk_zero; + +	/** +	 * @d_term_en: +	 * +	 * Time, in picoseconds, for the Data Lane receiver to enable +	 * the HS line termination. +	 * +	 * Maximum value: 35000 ps + 4 * @hs_clk_rate period in ps +	 */ +	unsigned int		d_term_en; + +	/** +	 * @eot: +	 * +	 * Transmitted time interval, in picoseconds, from the start +	 * of @hs_trail or @clk_trail, to the start of the LP- 11 +	 * state following a HS burst. +	 * +	 * Maximum value: 105000 ps + 12 * @hs_clk_rate period in ps +	 */ +	unsigned int		eot; + +	/** +	 * @hs_exit: +	 * +	 * Time, in picoseconds, that the transmitter drives LP-11 +	 * following a HS burst. +	 * +	 * Minimum value: 100000 ps +	 */ +	unsigned int		hs_exit; + +	/** +	 * @hs_prepare: +	 * +	 * Time, in picoseconds, that the transmitter drives the Data +	 * Lane LP-00 Line state immediately before the HS-0 Line +	 * state starting the HS transmission. +	 * +	 * Minimum value: 40000 ps + 4 * @hs_clk_rate period in ps +	 * Maximum value: 85000 ps + 6 * @hs_clk_rate period in ps +	 */ +	unsigned int		hs_prepare; + +	/** +	 * @hs_settle: +	 * +	 * Time interval, in picoseconds, during which the HS receiver +	 * shall ignore any Data Lane HS transitions, starting from +	 * the beginning of @hs_prepare. +	 * +	 * Minimum value: 85000 ps + 6 * @hs_clk_rate period in ps +	 * Maximum value: 145000 ps + 10 * @hs_clk_rate period in ps +	 */ +	unsigned int		hs_settle; + +	/** +	 * @hs_skip: +	 * +	 * Time interval, in picoseconds, during which the HS-RX +	 * should ignore any transitions on the Data Lane, following a +	 * HS burst. The end point of the interval is defined as the +	 * beginning of the LP-11 state following the HS burst. +	 * +	 * Minimum value: 40000 ps +	 * Maximum value: 55000 ps + 4 * @hs_clk_rate period in ps +	 */ +	unsigned int		hs_skip; + +	/** +	 * @hs_trail: +	 * +	 * Time, in picoseconds, that the transmitter drives the +	 * flipped differential state after last payload data bit of a +	 * HS transmission burst +	 * +	 * Minimum value: max(8 * @hs_clk_rate period in ps, +	 *		      60000 ps + 4 * @hs_clk_rate period in ps) +	 */ +	unsigned int		hs_trail; + +	/** +	 * @hs_zero: +	 * +	 * Time, in picoseconds, that the transmitter drives the HS-0 +	 * state prior to transmitting the Sync sequence. +	 */ +	unsigned int		hs_zero; + +	/** +	 * @init: +	 * +	 * Time, in picoseconds for the initialization period to +	 * complete. +	 * +	 * Minimum value: 100000000 ps +	 */ +	unsigned int		init; + +	/** +	 * @lpx: +	 * +	 * Transmitted length, in picoseconds, of any Low-Power state +	 * period. +	 * +	 * Minimum value: 50000 ps +	 */ +	unsigned int		lpx; + +	/** +	 * @ta_get: +	 * +	 * Time, in picoseconds, that the new transmitter drives the +	 * Bridge state (LP-00) after accepting control during a Link +	 * Turnaround. +	 * +	 * Value: 5 * @lpx +	 */ +	unsigned int		ta_get; + +	/** +	 * @ta_go: +	 * +	 * Time, in picoseconds, that the transmitter drives the +	 * Bridge state (LP-00) before releasing control during a Link +	 * Turnaround. +	 * +	 * Value: 4 * @lpx +	 */ +	unsigned int		ta_go; + +	/** +	 * @ta_sure: +	 * +	 * Time, in picoseconds, that the new transmitter waits after +	 * the LP-10 state before transmitting the Bridge state +	 * (LP-00) during a Link Turnaround. +	 * +	 * Minimum value: @lpx +	 * Maximum value: 2 * @lpx +	 */ +	unsigned int		ta_sure; + +	/** +	 * @wakeup: +	 * +	 * Time, in picoseconds, that a transmitter drives a Mark-1 +	 * state prior to a Stop state in order to initiate an exit +	 * from ULPS. +	 * +	 * Minimum value: 1000000000 ps +	 */ +	unsigned int		wakeup; + +	/** +	 * @hs_clk_rate: +	 * +	 * Clock rate, in Hertz, of the high-speed clock. +	 */ +	unsigned long		hs_clk_rate; + +	/** +	 * @lp_clk_rate: +	 * +	 * Clock rate, in Hertz, of the low-power clock. +	 */ +	unsigned long		lp_clk_rate; + +	/** +	 * @lanes: +	 * +	 * Number of active data lanes used for the transmissions. +	 */ +	unsigned char		lanes; +}; + +int phy_mipi_dphy_get_default_config(unsigned long pixel_clock, +				     unsigned int bpp, +				     unsigned int lanes, +				     struct phy_configure_opts_mipi_dphy *cfg); +int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg); + +#endif /* __PHY_MIPI_DPHY_H_ */ diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 03b319f89a34..e8e118d70fd7 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -20,6 +20,8 @@  #include <linux/pm_runtime.h>  #include <linux/regulator/consumer.h> +#include <linux/phy/phy-mipi-dphy.h> +  struct phy;  enum phy_mode { @@ -35,13 +37,21 @@ enum phy_mode {  	PHY_MODE_USB_DEVICE_HS,  	PHY_MODE_USB_DEVICE_SS,  	PHY_MODE_USB_OTG, -	PHY_MODE_SGMII, -	PHY_MODE_2500SGMII, -	PHY_MODE_QSGMII, -	PHY_MODE_10GKR,  	PHY_MODE_UFS_HS_A,  	PHY_MODE_UFS_HS_B,  	PHY_MODE_PCIE, +	PHY_MODE_ETHERNET, +	PHY_MODE_MIPI_DPHY, +}; + +/** + * union phy_configure_opts - Opaque generic phy configuration + * + * @mipi_dphy:	Configuration set applicable for phys supporting + *		the MIPI_DPHY phy mode. + */ +union phy_configure_opts { +	struct phy_configure_opts_mipi_dphy	mipi_dphy;  };  /** @@ -60,7 +70,38 @@ struct phy_ops {  	int	(*exit)(struct phy *phy);  	int	(*power_on)(struct phy *phy);  	int	(*power_off)(struct phy *phy); -	int	(*set_mode)(struct phy *phy, enum phy_mode mode); +	int	(*set_mode)(struct phy *phy, enum phy_mode mode, int submode); + +	/** +	 * @configure: +	 * +	 * Optional. +	 * +	 * Used to change the PHY parameters. phy_init() must have +	 * been called on the phy. +	 * +	 * Returns: 0 if successful, an negative error code otherwise +	 */ +	int	(*configure)(struct phy *phy, union phy_configure_opts *opts); + +	/** +	 * @validate: +	 * +	 * Optional. +	 * +	 * Used to check that the current set of parameters can be +	 * handled by the phy. Implementations are free to tune the +	 * parameters passed as arguments if needed by some +	 * implementation detail or constraints. It must not change +	 * any actual configuration of the PHY, so calling it as many +	 * times as deemed fit by the consumer must have no side +	 * effect. +	 * +	 * Returns: 0 if the configuration can be applied, an negative +	 * error code otherwise +	 */ +	int	(*validate)(struct phy *phy, enum phy_mode mode, int submode, +			    union phy_configure_opts *opts);  	int	(*reset)(struct phy *phy);  	int	(*calibrate)(struct phy *phy);  	struct module *owner; @@ -69,6 +110,7 @@ struct phy_ops {  /**   * struct phy_attrs - represents phy attributes   * @bus_width: Data path width implemented by PHY + * @mode: PHY mode   */  struct phy_attrs {  	u32			bus_width; @@ -80,7 +122,6 @@ struct phy_attrs {   * @dev: phy device   * @id: id of the phy device   * @ops: function pointers for performing phy operations - * @init_data: list of PHY consumers (non-dt only)   * @mutex: mutex to protect phy_ops   * @init_count: used to protect when the PHY is used by multiple consumers   * @power_count: used to protect when the PHY is used by multiple consumers @@ -164,7 +205,13 @@ int phy_init(struct phy *phy);  int phy_exit(struct phy *phy);  int phy_power_on(struct phy *phy);  int phy_power_off(struct phy *phy); -int phy_set_mode(struct phy *phy, enum phy_mode mode); +int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode); +#define phy_set_mode(phy, mode) \ +	phy_set_mode_ext(phy, mode, 0) +int phy_configure(struct phy *phy, union phy_configure_opts *opts); +int phy_validate(struct phy *phy, enum phy_mode mode, int submode, +		 union phy_configure_opts *opts); +  static inline enum phy_mode phy_get_mode(struct phy *phy)  {  	return phy->attrs.mode; @@ -278,13 +325,17 @@ static inline int phy_power_off(struct phy *phy)  	return -ENOSYS;  } -static inline int phy_set_mode(struct phy *phy, enum phy_mode mode) +static inline int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, +				   int submode)  {  	if (!phy)  		return 0;  	return -ENOSYS;  } +#define phy_set_mode(phy, mode) \ +	phy_set_mode_ext(phy, mode, 0) +  static inline enum phy_mode phy_get_mode(struct phy *phy)  {  	return PHY_MODE_INVALID; @@ -304,6 +355,24 @@ static inline int phy_calibrate(struct phy *phy)  	return -ENOSYS;  } +static inline int phy_configure(struct phy *phy, +				union phy_configure_opts *opts) +{ +	if (!phy) +		return 0; + +	return -ENOSYS; +} + +static inline int phy_validate(struct phy *phy, enum phy_mode mode, int submode, +			       union phy_configure_opts *opts) +{ +	if (!phy) +		return 0; + +	return -ENOSYS; +} +  static inline int phy_get_bus_width(struct phy *phy)  {  	return -ENOSYS;  | 
