Skip to content

Commit 3691411

Browse files
Andrzej Pietrasiewiczkishon
authored andcommitted
drivers: phy: add calibrate method
Some quirky UDCs (like dwc3 on Exynos) need to have their phys calibrated e.g. for using super speed. This patch adds a new phy_calibrate() method. When the calibration should be used is dependent on actual chip. In case of dwc3 on Exynos the calibration must happen after usb_add_hcd() (while in host mode), because certain phy parameters like Tx LOS levels and boost levels need to be calibrated further post initialization of xHCI controller, to get SuperSpeed operations working. But an hcd must be prepared first in order to pass it to usb_add_hcd(), so, in particular, dwc3 registers must be available first, and in order for the latter to happen the phys must be initialized. This poses a chicken and egg problem if the calibration were to be performed in phy_init(). To break the circular dependency a separate method is added which can be called at a desired moment after phy intialization. Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
1 parent 052553a commit 3691411

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

drivers/phy/phy-core.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,21 @@ int phy_reset(struct phy *phy)
372372
}
373373
EXPORT_SYMBOL_GPL(phy_reset);
374374

375+
int phy_calibrate(struct phy *phy)
376+
{
377+
int ret;
378+
379+
if (!phy || !phy->ops->calibrate)
380+
return 0;
381+
382+
mutex_lock(&phy->mutex);
383+
ret = phy->ops->calibrate(phy);
384+
mutex_unlock(&phy->mutex);
385+
386+
return ret;
387+
}
388+
EXPORT_SYMBOL_GPL(phy_calibrate);
389+
375390
/**
376391
* _of_phy_get() - lookup and obtain a reference to a phy by phandle
377392
* @np: device_node for which to get the phy

include/linux/phy/phy.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ enum phy_mode {
4141
* @power_off: powering off the phy
4242
* @set_mode: set the mode of the phy
4343
* @reset: resetting the phy
44+
* @calibrate: calibrate the phy
4445
* @owner: the module owner containing the ops
4546
*/
4647
struct phy_ops {
@@ -50,6 +51,7 @@ struct phy_ops {
5051
int (*power_off)(struct phy *phy);
5152
int (*set_mode)(struct phy *phy, enum phy_mode mode);
5253
int (*reset)(struct phy *phy);
54+
int (*calibrate)(struct phy *phy);
5355
struct module *owner;
5456
};
5557

@@ -143,6 +145,7 @@ int phy_power_on(struct phy *phy);
143145
int phy_power_off(struct phy *phy);
144146
int phy_set_mode(struct phy *phy, enum phy_mode mode);
145147
int phy_reset(struct phy *phy);
148+
int phy_calibrate(struct phy *phy);
146149
static inline int phy_get_bus_width(struct phy *phy)
147150
{
148151
return phy->attrs.bus_width;
@@ -264,6 +267,13 @@ static inline int phy_reset(struct phy *phy)
264267
return -ENOSYS;
265268
}
266269

270+
static inline int phy_calibrate(struct phy *phy)
271+
{
272+
if (!phy)
273+
return 0;
274+
return -ENOSYS;
275+
}
276+
267277
static inline int phy_get_bus_width(struct phy *phy)
268278
{
269279
return -ENOSYS;

0 commit comments

Comments
 (0)