* [PATCH v4 0/2] Add new phy_notify_state() api
@ 2025-11-12 16:05 Peter Griffin
2025-11-12 16:05 ` [PATCH v4 1/2] phy: add " Peter Griffin
2025-11-12 16:05 ` [PATCH v4 2/2] phy: samsung: gs101-ufs: Add .notify_phystate() & hibern8 enter/exit values Peter Griffin
0 siblings, 2 replies; 5+ messages in thread
From: Peter Griffin @ 2025-11-12 16:05 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, André Draszik,
Tudor Ambarus, Alim Akhtar, Krzysztof Kozlowski
Cc: linux-phy, linux-kernel, linux-arm-kernel, linux-samsung-soc,
kernel-team, William Mcvicker, Manivannan Sadhasivam,
neil.armstrong, Peter Griffin
This series adds a new phy_notify_state() API to the phy subsystem. It is
designed to be used when some specific runtime configuration parameters
need to be changed when transitioning to the desired state which can't be
handled by phy_calibrate()or phy_power_{on|off}().
The first user of the new API is phy-samsung-ufs and phy-gs101-ufs which
need to issue some register writes when entering and exiting the hibern8
link state.
A separate patch will be sent for ufs-exynos driver to make use of this new
API in the hibern8 callbacks.
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
Changes in v4:
- Add missing 'used' word in commit description (Vinod)
- Fix 0-day compiler warning
- Link to v3: https://lore.kernel.org/r/20250813-phy-notify-pmstate-v3-0-3bda59055dd3@linaro.org
Changes in v3:
- Rename API to phy_notify_state(). (Mani/Neil)
- Remove inline kerneldoc comment (Mani)
- s/phy/PHY (Mani)
- peripheral specific enums in phy.h (Vinod)
- Link to v2: https://lore.kernel.org/r/20250703-phy-notify-pmstate-v2-0-fc1690439117@linaro.org
Changes in v2:
- Add new phy_notify_pmstate API() instead of using phy_set_mode() (Vinod)
- Link to v1: https://lore.kernel.org/r/20241002201555.3332138-1-peter.griffin@linaro.org
---
Peter Griffin (2):
phy: add new phy_notify_state() api
phy: samsung: gs101-ufs: Add .notify_phystate() & hibern8 enter/exit values
drivers/phy/phy-core.c | 25 ++++++++++++++++++++++
drivers/phy/samsung/phy-gs101-ufs.c | 28 ++++++++++++++++++++++++
drivers/phy/samsung/phy-samsung-ufs.c | 40 +++++++++++++++++++++++++++++++++++
drivers/phy/samsung/phy-samsung-ufs.h | 7 ++++++
include/linux/phy/phy.h | 19 +++++++++++++++++
5 files changed, 119 insertions(+)
---
base-commit: b179ce312bafcb8c68dc718e015aee79b7939ff0
change-id: 20250703-phy-notify-pmstate-f02ba5582f65
Best regards,
--
Peter Griffin <peter.griffin@linaro.org>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v4 1/2] phy: add new phy_notify_state() api
2025-11-12 16:05 [PATCH v4 0/2] Add new phy_notify_state() api Peter Griffin
@ 2025-11-12 16:05 ` Peter Griffin
2025-11-12 16:14 ` Russell King (Oracle)
2025-11-12 16:05 ` [PATCH v4 2/2] phy: samsung: gs101-ufs: Add .notify_phystate() & hibern8 enter/exit values Peter Griffin
1 sibling, 1 reply; 5+ messages in thread
From: Peter Griffin @ 2025-11-12 16:05 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, André Draszik,
Tudor Ambarus, Alim Akhtar, Krzysztof Kozlowski
Cc: linux-phy, linux-kernel, linux-arm-kernel, linux-samsung-soc,
kernel-team, William Mcvicker, Manivannan Sadhasivam,
neil.armstrong, Peter Griffin
Add a new phy_notify_state() api that notifies and configures a phy for a
given state transition.
This is intended to be used by phy drivers which need to do some runtime
configuration of parameters that can't be handled by phy_calibrate() or
phy_power_{on|off}().
The first usage of this API is in the Samsung UFS phy that needs to issue
some register writes when entering and exiting the hibernate link state.
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
Changes in v4
- Add missing 'used' word (Vinod)
---
drivers/phy/phy-core.c | 25 +++++++++++++++++++++++++
include/linux/phy/phy.h | 19 +++++++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 04a5a34e7a950ae94fae915673c25d476fc071c1..60be8af984bf06649ef00e695d0ed4ced597cdb9 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -520,6 +520,31 @@ int phy_notify_disconnect(struct phy *phy, int port)
}
EXPORT_SYMBOL_GPL(phy_notify_disconnect);
+/**
+ * phy_notify_state() - phy state notification
+ * @phy: the PHY returned by phy_get()
+ * @state: the PHY state
+ *
+ * Notify the PHY of a state transition. Used to notify and
+ * configure the PHY accordingly.
+ *
+ * Returns: %0 if successful, a negative error code otherwise
+ */
+int phy_notify_state(struct phy *phy, union phy_notify state)
+{
+ int ret;
+
+ if (!phy || !phy->ops->notify_phystate)
+ return 0;
+
+ mutex_lock(&phy->mutex);
+ ret = phy->ops->notify_phystate(phy, state);
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(phy_notify_state);
+
/**
* phy_configure() - Changes the phy parameters
* @phy: the phy returned by phy_get()
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 13add0c2c40721fe9ca3f0350d13c035cd25af45..664d0864c3a5042949cb121e982368fe0a97827f 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -53,6 +53,15 @@ enum phy_media {
PHY_MEDIA_DAC,
};
+enum phy_ufs_state {
+ PHY_UFS_HIBERN8_ENTER,
+ PHY_UFS_HIBERN8_EXIT,
+};
+
+union phy_notify {
+ enum phy_ufs_state ufs_state;
+};
+
/**
* union phy_configure_opts - Opaque generic phy configuration
*
@@ -83,6 +92,7 @@ union phy_configure_opts {
* @set_speed: set the speed of the phy (optional)
* @reset: resetting the phy
* @calibrate: calibrate the phy
+ * @notify_phystate: notify and configure the phy for a particular state
* @release: ops to be performed while the consumer relinquishes the PHY
* @owner: the module owner containing the ops
*/
@@ -132,6 +142,7 @@ struct phy_ops {
int (*connect)(struct phy *phy, int port);
int (*disconnect)(struct phy *phy, int port);
+ int (*notify_phystate)(struct phy *phy, union phy_notify state);
void (*release)(struct phy *phy);
struct module *owner;
};
@@ -255,6 +266,7 @@ int phy_reset(struct phy *phy);
int phy_calibrate(struct phy *phy);
int phy_notify_connect(struct phy *phy, int port);
int phy_notify_disconnect(struct phy *phy, int port);
+int phy_notify_state(struct phy *phy, union phy_notify state);
static inline int phy_get_bus_width(struct phy *phy)
{
return phy->attrs.bus_width;
@@ -412,6 +424,13 @@ static inline int phy_notify_disconnect(struct phy *phy, int index)
return -ENOSYS;
}
+static inline int phy_notify_phystate(struct phy *phy, union phy_notify state)
+{
+ if (!phy)
+ return 0;
+ return -ENOSYS;
+}
+
static inline int phy_configure(struct phy *phy,
union phy_configure_opts *opts)
{
--
2.51.2.1041.gc1ab5b90ca-goog
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 2/2] phy: samsung: gs101-ufs: Add .notify_phystate() & hibern8 enter/exit values
2025-11-12 16:05 [PATCH v4 0/2] Add new phy_notify_state() api Peter Griffin
2025-11-12 16:05 ` [PATCH v4 1/2] phy: add " Peter Griffin
@ 2025-11-12 16:05 ` Peter Griffin
1 sibling, 0 replies; 5+ messages in thread
From: Peter Griffin @ 2025-11-12 16:05 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, André Draszik,
Tudor Ambarus, Alim Akhtar, Krzysztof Kozlowski
Cc: linux-phy, linux-kernel, linux-arm-kernel, linux-samsung-soc,
kernel-team, William Mcvicker, Manivannan Sadhasivam,
neil.armstrong, Peter Griffin
Implement the .notify_phystate() callback and provide the gs101 specific
phy values that need to be programmed when entering and exiting the hibern8
state.
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
Changes in v4
- Resolve Intel 0-day warning
---
drivers/phy/samsung/phy-gs101-ufs.c | 28 ++++++++++++++++++++++++
drivers/phy/samsung/phy-samsung-ufs.c | 40 +++++++++++++++++++++++++++++++++++
drivers/phy/samsung/phy-samsung-ufs.h | 7 ++++++
3 files changed, 75 insertions(+)
diff --git a/drivers/phy/samsung/phy-gs101-ufs.c b/drivers/phy/samsung/phy-gs101-ufs.c
index 17b798da5b5761f8e367599517d2d97bf0bb6b74..a15e1f453f7f3cecd6d3aa75217633ac4b6085d0 100644
--- a/drivers/phy/samsung/phy-gs101-ufs.c
+++ b/drivers/phy/samsung/phy-gs101-ufs.c
@@ -108,12 +108,39 @@ static const struct samsung_ufs_phy_cfg tensor_gs101_post_pwr_hs_config[] = {
END_UFS_PHY_CFG,
};
+static const struct samsung_ufs_phy_cfg tensor_gs101_post_h8_enter[] = {
+ PHY_TRSV_REG_CFG_GS101(0x262, 0x08, PWR_MODE_ANY),
+ PHY_TRSV_REG_CFG_GS101(0x265, 0x0A, PWR_MODE_ANY),
+ PHY_COMN_REG_CFG(0x1, 0x8, PWR_MODE_ANY),
+ PHY_COMN_REG_CFG(0x0, 0x86, PWR_MODE_ANY),
+ PHY_COMN_REG_CFG(0x8, 0x60, PWR_MODE_HS_ANY),
+ PHY_TRSV_REG_CFG_GS101(0x222, 0x08, PWR_MODE_HS_ANY),
+ PHY_TRSV_REG_CFG_GS101(0x246, 0x01, PWR_MODE_HS_ANY),
+ END_UFS_PHY_CFG,
+};
+
+static const struct samsung_ufs_phy_cfg tensor_gs101_pre_h8_exit[] = {
+ PHY_COMN_REG_CFG(0x0, 0xC6, PWR_MODE_ANY),
+ PHY_COMN_REG_CFG(0x1, 0x0C, PWR_MODE_ANY),
+ PHY_TRSV_REG_CFG_GS101(0x262, 0x00, PWR_MODE_ANY),
+ PHY_TRSV_REG_CFG_GS101(0x265, 0x00, PWR_MODE_ANY),
+ PHY_COMN_REG_CFG(0x8, 0xE0, PWR_MODE_HS_ANY),
+ PHY_TRSV_REG_CFG_GS101(0x246, 0x03, PWR_MODE_HS_ANY),
+ PHY_TRSV_REG_CFG_GS101(0x222, 0x18, PWR_MODE_HS_ANY),
+ END_UFS_PHY_CFG,
+};
+
static const struct samsung_ufs_phy_cfg *tensor_gs101_ufs_phy_cfgs[CFG_TAG_MAX] = {
[CFG_PRE_INIT] = tensor_gs101_pre_init_cfg,
[CFG_PRE_PWR_HS] = tensor_gs101_pre_pwr_hs_config,
[CFG_POST_PWR_HS] = tensor_gs101_post_pwr_hs_config,
};
+static const struct samsung_ufs_phy_cfg *tensor_gs101_hibern8_cfgs[] = {
+ [CFG_POST_HIBERN8_ENTER] = tensor_gs101_post_h8_enter,
+ [CFG_PRE_HIBERN8_EXIT] = tensor_gs101_pre_h8_exit,
+};
+
static const char * const tensor_gs101_ufs_phy_clks[] = {
"ref_clk",
};
@@ -170,6 +197,7 @@ static int gs101_phy_wait_for_cdr_lock(struct phy *phy, u8 lane)
const struct samsung_ufs_phy_drvdata tensor_gs101_ufs_phy = {
.cfgs = tensor_gs101_ufs_phy_cfgs,
+ .cfgs_hibern8 = tensor_gs101_hibern8_cfgs,
.isol = {
.offset = TENSOR_GS101_PHY_CTRL,
.mask = TENSOR_GS101_PHY_CTRL_MASK,
diff --git a/drivers/phy/samsung/phy-samsung-ufs.c b/drivers/phy/samsung/phy-samsung-ufs.c
index f3cbe6b17b235bb181b3fae628d75822f0c9183a..ee665f26c2361ff9c3933b10ac713bbd9085b459 100644
--- a/drivers/phy/samsung/phy-samsung-ufs.c
+++ b/drivers/phy/samsung/phy-samsung-ufs.c
@@ -217,6 +217,44 @@ static int samsung_ufs_phy_set_mode(struct phy *generic_phy,
return 0;
}
+static int samsung_ufs_phy_notify_state(struct phy *phy,
+ union phy_notify state)
+{
+ struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
+ const struct samsung_ufs_phy_cfg *cfg;
+ int i, err = -EINVAL;
+
+ if (!ufs_phy->cfgs_hibern8)
+ return 0;
+
+ if (state.ufs_state == PHY_UFS_HIBERN8_ENTER)
+ cfg = ufs_phy->cfgs_hibern8[CFG_POST_HIBERN8_ENTER];
+ else if (state.ufs_state == PHY_UFS_HIBERN8_EXIT)
+ cfg = ufs_phy->cfgs_hibern8[CFG_PRE_HIBERN8_EXIT];
+ else
+ goto err_out;
+
+ for_each_phy_cfg(cfg) {
+ for_each_phy_lane(ufs_phy, i) {
+ samsung_ufs_phy_config(ufs_phy, cfg, i);
+ }
+ }
+
+ if (state.ufs_state == PHY_UFS_HIBERN8_EXIT) {
+ for_each_phy_lane(ufs_phy, i) {
+ if (ufs_phy->drvdata->wait_for_cdr) {
+ err = ufs_phy->drvdata->wait_for_cdr(phy, i);
+ if (err)
+ goto err_out;
+ }
+ }
+ }
+
+ return 0;
+err_out:
+ return err;
+}
+
static int samsung_ufs_phy_exit(struct phy *phy)
{
struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy);
@@ -233,6 +271,7 @@ static const struct phy_ops samsung_ufs_phy_ops = {
.power_off = samsung_ufs_phy_power_off,
.calibrate = samsung_ufs_phy_calibrate,
.set_mode = samsung_ufs_phy_set_mode,
+ .notify_phystate = samsung_ufs_phy_notify_state,
.owner = THIS_MODULE,
};
@@ -287,6 +326,7 @@ static int samsung_ufs_phy_probe(struct platform_device *pdev)
phy->dev = dev;
phy->drvdata = drvdata;
phy->cfgs = drvdata->cfgs;
+ phy->cfgs_hibern8 = drvdata->cfgs_hibern8;
memcpy(&phy->isol, &drvdata->isol, sizeof(phy->isol));
if (!of_property_read_u32_index(dev->of_node, "samsung,pmu-syscon", 1,
diff --git a/drivers/phy/samsung/phy-samsung-ufs.h b/drivers/phy/samsung/phy-samsung-ufs.h
index a28f148081d168344b47f2798b00cb098f0a8574..f2c2e744e5bae87c9cfcaa17f4a09456f134966a 100644
--- a/drivers/phy/samsung/phy-samsung-ufs.h
+++ b/drivers/phy/samsung/phy-samsung-ufs.h
@@ -92,6 +92,11 @@ enum {
CFG_TAG_MAX,
};
+enum {
+ CFG_POST_HIBERN8_ENTER,
+ CFG_PRE_HIBERN8_EXIT,
+};
+
struct samsung_ufs_phy_cfg {
u32 off_0;
u32 off_1;
@@ -108,6 +113,7 @@ struct samsung_ufs_phy_pmu_isol {
struct samsung_ufs_phy_drvdata {
const struct samsung_ufs_phy_cfg **cfgs;
+ const struct samsung_ufs_phy_cfg **cfgs_hibern8;
struct samsung_ufs_phy_pmu_isol isol;
const char * const *clk_list;
int num_clks;
@@ -124,6 +130,7 @@ struct samsung_ufs_phy {
struct clk_bulk_data *clks;
const struct samsung_ufs_phy_drvdata *drvdata;
const struct samsung_ufs_phy_cfg * const *cfgs;
+ const struct samsung_ufs_phy_cfg * const *cfgs_hibern8;
struct samsung_ufs_phy_pmu_isol isol;
u8 lane_cnt;
int ufs_phy_state;
--
2.51.2.1041.gc1ab5b90ca-goog
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v4 1/2] phy: add new phy_notify_state() api
2025-11-12 16:05 ` [PATCH v4 1/2] phy: add " Peter Griffin
@ 2025-11-12 16:14 ` Russell King (Oracle)
2025-11-12 16:17 ` Peter Griffin
0 siblings, 1 reply; 5+ messages in thread
From: Russell King (Oracle) @ 2025-11-12 16:14 UTC (permalink / raw)
To: Peter Griffin
Cc: Vinod Koul, Kishon Vijay Abraham I, André Draszik,
Tudor Ambarus, Alim Akhtar, Krzysztof Kozlowski, linux-phy,
linux-kernel, linux-arm-kernel, linux-samsung-soc, kernel-team,
William Mcvicker, Manivannan Sadhasivam, neil.armstrong
On Wed, Nov 12, 2025 at 04:05:58PM +0000, Peter Griffin wrote:
> +int phy_notify_state(struct phy *phy, union phy_notify state)
...
> @@ -255,6 +266,7 @@ int phy_reset(struct phy *phy);
> int phy_calibrate(struct phy *phy);
> int phy_notify_connect(struct phy *phy, int port);
> int phy_notify_disconnect(struct phy *phy, int port);
> +int phy_notify_state(struct phy *phy, union phy_notify state);
> static inline int phy_get_bus_width(struct phy *phy)
> {
> return phy->attrs.bus_width;
> @@ -412,6 +424,13 @@ static inline int phy_notify_disconnect(struct phy *phy, int index)
> return -ENOSYS;
> }
>
> +static inline int phy_notify_phystate(struct phy *phy, union phy_notify state)
Should this be phy_notify_state() ?
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v4 1/2] phy: add new phy_notify_state() api
2025-11-12 16:14 ` Russell King (Oracle)
@ 2025-11-12 16:17 ` Peter Griffin
0 siblings, 0 replies; 5+ messages in thread
From: Peter Griffin @ 2025-11-12 16:17 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: Vinod Koul, Kishon Vijay Abraham I, André Draszik,
Tudor Ambarus, Alim Akhtar, Krzysztof Kozlowski, linux-phy,
linux-kernel, linux-arm-kernel, linux-samsung-soc, kernel-team,
William Mcvicker, Manivannan Sadhasivam, neil.armstrong
Hi Russell,
On Wed, 12 Nov 2025 at 16:14, Russell King (Oracle)
<linux@armlinux.org.uk> wrote:
>
> On Wed, Nov 12, 2025 at 04:05:58PM +0000, Peter Griffin wrote:
> > +int phy_notify_state(struct phy *phy, union phy_notify state)
> ...
> > @@ -255,6 +266,7 @@ int phy_reset(struct phy *phy);
> > int phy_calibrate(struct phy *phy);
> > int phy_notify_connect(struct phy *phy, int port);
> > int phy_notify_disconnect(struct phy *phy, int port);
> > +int phy_notify_state(struct phy *phy, union phy_notify state);
> > static inline int phy_get_bus_width(struct phy *phy)
> > {
> > return phy->attrs.bus_width;
> > @@ -412,6 +424,13 @@ static inline int phy_notify_disconnect(struct phy *phy, int index)
> > return -ENOSYS;
> > }
> >
> > +static inline int phy_notify_phystate(struct phy *phy, union phy_notify state)
>
> Should this be phy_notify_state() ?
Yes, that's a good point! Let me send a new version fixing that.
Peter
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-11-12 16:17 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-12 16:05 [PATCH v4 0/2] Add new phy_notify_state() api Peter Griffin
2025-11-12 16:05 ` [PATCH v4 1/2] phy: add " Peter Griffin
2025-11-12 16:14 ` Russell King (Oracle)
2025-11-12 16:17 ` Peter Griffin
2025-11-12 16:05 ` [PATCH v4 2/2] phy: samsung: gs101-ufs: Add .notify_phystate() & hibern8 enter/exit values Peter Griffin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).