All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 net-next 0/1 ] net: phy: air_en8811h: Add clk provider for CKO pin
@ 2025-03-16 14:18 Lucien.Jheng
  2025-03-16 14:19 ` [PATCH v3 net-next PATCH 1/1] " Lucien.Jheng
  0 siblings, 1 reply; 4+ messages in thread
From: Lucien.Jheng @ 2025-03-16 14:18 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, kuba, davem, edumazet, pabeni, daniel,
	ericwouds
  Cc: netdev, linux-kernel, joseph.lin, wenshin.chung, Lucien.Jheng

This patch adds clk provider for the CKO pin of the Airoha en8811h PHY.

Change in PATCH v3:
air_en8811h.c:
 * Add clk provider for CKO pin

Lucien.Jheng (1):
  net: phy: air_en8811h: Add clk provider for CKO pin

 drivers/net/phy/air_en8811h.c | 95 +++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3 net-next PATCH 1/1] net: phy: air_en8811h: Add clk provider for CKO pin
  2025-03-16 14:18 [PATCH v3 net-next 0/1 ] net: phy: air_en8811h: Add clk provider for CKO pin Lucien.Jheng
@ 2025-03-16 14:19 ` Lucien.Jheng
  2025-03-16 16:31   ` Daniel Golle
  2025-03-16 20:15   ` Russell King (Oracle)
  0 siblings, 2 replies; 4+ messages in thread
From: Lucien.Jheng @ 2025-03-16 14:19 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, kuba, davem, edumazet, pabeni, daniel,
	ericwouds
  Cc: netdev, linux-kernel, joseph.lin, wenshin.chung, Lucien.Jheng

The EN8811H generates 25MHz or 50MHz clocks on its CKO pin, selected by GPIO3 hardware trap.
Register 0xcf914, read via buckpbus API, shows the frequency with bit 12: 0 for 25MHz, 1 for 50MHz.
CKO clock output is active from power-up through md32 firmware loading.

Signed-off-by: Lucien.Jheng <lucienX123@gmail.com>
---
 drivers/net/phy/air_en8811h.c | 95 +++++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)

diff --git a/drivers/net/phy/air_en8811h.c b/drivers/net/phy/air_en8811h.c
index e9fd24cb7270..ed90ccefe842 100644
--- a/drivers/net/phy/air_en8811h.c
+++ b/drivers/net/phy/air_en8811h.c
@@ -16,6 +16,7 @@
 #include <linux/property.h>
 #include <linux/wordpart.h>
 #include <linux/unaligned.h>
+#include <linux/clk-provider.h>
 
 #define EN8811H_PHY_ID		0x03a2a411
 
@@ -112,6 +113,11 @@
 #define   EN8811H_POLARITY_TX_NORMAL		BIT(0)
 #define   EN8811H_POLARITY_RX_REVERSE		BIT(1)
 
+#define EN8811H_CLK_CGM     0xcf958
+#define EN8811H_CLK_CGM_CKO     BIT(26)
+#define EN8811H_HWTRAP1     0xcf914
+#define EN8811H_HWTRAP1_CKO     BIT(12)
+
 #define EN8811H_GPIO_OUTPUT		0xcf8b8
 #define   EN8811H_GPIO_OUTPUT_345		(BIT(3) | BIT(4) | BIT(5))
 
@@ -142,10 +148,15 @@ struct led {
 	unsigned long state;
 };
 
+#define to_en8811h_priv(_hw)			\
+	container_of(_hw, struct en8811h_priv, hw)
+
 struct en8811h_priv {
 	u32		firmware_version;
 	bool		mcu_needs_restart;
 	struct led	led[EN8811H_LED_COUNT];
+	struct clk_hw        hw;
+	struct phy_device *phydev;
 };
 
 enum {
@@ -806,6 +817,84 @@ static int en8811h_led_hw_is_supported(struct phy_device *phydev, u8 index,
 	return 0;
 };
 
+static unsigned long en8811h_recalc_rate(struct clk_hw *hw, unsigned long parent)
+{
+	struct en8811h_priv *priv = to_en8811h_priv(hw);
+	struct phy_device *phydev = priv->phydev;
+	u32 pbus_value;
+	int ret;
+
+	ret = air_buckpbus_reg_read(phydev, EN8811H_HWTRAP1, &pbus_value);
+	if (ret < 0)
+		return ret;
+
+	return (pbus_value & EN8811H_HWTRAP1_CKO) ? 50000000 : 25000000;
+}
+
+static int en8811h_enable(struct clk_hw *hw)
+{
+	struct en8811h_priv *priv = to_en8811h_priv(hw);
+	struct phy_device *phydev = priv->phydev;
+
+	return air_buckpbus_reg_modify(phydev, EN8811H_CLK_CGM,
+				EN8811H_CLK_CGM_CKO, EN8811H_CLK_CGM_CKO);
+}
+
+static void en8811h_disable(struct clk_hw *hw)
+{
+	struct en8811h_priv *priv = to_en8811h_priv(hw);
+	struct phy_device *phydev = priv->phydev;
+
+	air_buckpbus_reg_modify(phydev, EN8811H_CLK_CGM,
+				EN8811H_CLK_CGM_CKO, 0);
+}
+
+static int en8811h_is_enabled(struct clk_hw *hw)
+{
+	struct en8811h_priv *priv = to_en8811h_priv(hw);
+	struct phy_device *phydev = priv->phydev;
+	int ret = 0;
+	u32 pbus_value;
+
+	ret = air_buckpbus_reg_read(phydev, EN8811H_CLK_CGM, &pbus_value);
+	if (ret < 0)
+		return ret;
+
+	return (pbus_value & EN8811H_CLK_CGM_CKO);
+}
+
+static const struct clk_ops en8811h_clk_ops = {
+	.recalc_rate = en8811h_recalc_rate,
+	.enable = en8811h_enable,
+	.disable = en8811h_disable,
+	.is_enabled	= en8811h_is_enabled,
+};
+
+static int en8811h_clk_provider_setup(struct device *dev, struct clk_hw *hw)
+{
+	struct clk_init_data init;
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_COMMON_CLK))
+		return 0;
+
+	init.name =  devm_kasprintf(dev, GFP_KERNEL, "%s-clk",
+				    fwnode_get_name(dev_fwnode(dev)));
+	if (!init.name)
+		return -ENOMEM;
+
+	init.ops = &en8811h_clk_ops;
+	init.flags = CLK_GET_RATE_NOCACHE;
+	init.num_parents = 0;
+	hw->init = &init;
+
+	ret = devm_clk_hw_register(dev, hw);
+	if (ret)
+		return ret;
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
+}
+
 static int en8811h_probe(struct phy_device *phydev)
 {
 	struct en8811h_priv *priv;
@@ -838,6 +927,12 @@ static int en8811h_probe(struct phy_device *phydev)
 		return ret;
 	}
 
+	priv->phydev = phydev;
+	/* Co-Clock */
+	ret = en8811h_clk_provider_setup(&phydev->mdio.dev, &priv->hw);
+	if (ret)
+		return ret;
+
 	/* Configure led gpio pins as output */
 	ret = air_buckpbus_reg_modify(phydev, EN8811H_GPIO_OUTPUT,
 				      EN8811H_GPIO_OUTPUT_345,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 net-next PATCH 1/1] net: phy: air_en8811h: Add clk provider for CKO pin
  2025-03-16 14:19 ` [PATCH v3 net-next PATCH 1/1] " Lucien.Jheng
@ 2025-03-16 16:31   ` Daniel Golle
  2025-03-16 20:15   ` Russell King (Oracle)
  1 sibling, 0 replies; 4+ messages in thread
From: Daniel Golle @ 2025-03-16 16:31 UTC (permalink / raw)
  To: Lucien.Jheng
  Cc: andrew, hkallweit1, linux, kuba, davem, edumazet, pabeni,
	ericwouds, netdev, linux-kernel, joseph.lin, wenshin.chung

Hi Lucien,

nice work, this looks much better already.

As the PHY now becomes a clk provider, please also include
linux-clk@vger.kernel.org list among the receivers in Cc for future
iterations (but allow for at least 24h to pass before resending, so
others also have time to comment on this version).

On Sun, Mar 16, 2025 at 10:19:00PM +0800, Lucien.Jheng wrote:
> The EN8811H generates 25MHz or 50MHz clocks on its CKO pin, selected by GPIO3 hardware trap.
> Register 0xcf914, read via buckpbus API, shows the frequency with bit 12: 0 for 25MHz, 1 for 50MHz.
> CKO clock output is active from power-up through md32 firmware loading.

Nit: The lines of the patch description body are still too long.

> ...
> +static int en8811h_clk_provider_setup(struct device *dev, struct clk_hw *hw)
> +{
> +	struct clk_init_data init;
> +	int ret;
> +
> +	if (!IS_ENABLED(CONFIG_COMMON_CLK))
> +		return 0;
> +
> +	init.name =  devm_kasprintf(dev, GFP_KERNEL, "%s-clk",
> +				    fwnode_get_name(dev_fwnode(dev)));
> +	if (!init.name)
> +		return -ENOMEM;
> +
> +	init.ops = &en8811h_clk_ops;
> +	init.flags = CLK_GET_RATE_NOCACHE;

The rate is fixed by bootstrap pins, so there is reason for not allowing
to cache the rate (which is always going to be the same). Hence I
suggest to not set the CLK_GET_RATE_NOCACHE flag.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 net-next PATCH 1/1] net: phy: air_en8811h: Add clk provider for CKO pin
  2025-03-16 14:19 ` [PATCH v3 net-next PATCH 1/1] " Lucien.Jheng
  2025-03-16 16:31   ` Daniel Golle
@ 2025-03-16 20:15   ` Russell King (Oracle)
  1 sibling, 0 replies; 4+ messages in thread
From: Russell King (Oracle) @ 2025-03-16 20:15 UTC (permalink / raw)
  To: Lucien.Jheng
  Cc: andrew, hkallweit1, kuba, davem, edumazet, pabeni, daniel,
	ericwouds, netdev, linux-kernel, joseph.lin, wenshin.chung

On Sun, Mar 16, 2025 at 10:19:00PM +0800, Lucien.Jheng wrote:
> +#define to_en8811h_priv(_hw)			\
> +	container_of(_hw, struct en8811h_priv, hw)

Maybe better to call this "clk_hw_to_en8811h_priv()" ?

> +static int en8811h_clk_provider_setup(struct device *dev, struct clk_hw *hw)
> +{
> +	struct clk_init_data init;
> +	int ret;
> +
> +	if (!IS_ENABLED(CONFIG_COMMON_CLK))
> +		return 0;
> +
> +	init.name =  devm_kasprintf(dev, GFP_KERNEL, "%s-clk",
> +				    fwnode_get_name(dev_fwnode(dev)));

Given that this is the clk API, naming a clock with a "-clk" suffix
is redundant. Instead, consider something more descriptive. You say
this is the "CKO" output, so maybe "%s-cko" so that hardware reference
is included in the name.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-03-16 20:16 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-16 14:18 [PATCH v3 net-next 0/1 ] net: phy: air_en8811h: Add clk provider for CKO pin Lucien.Jheng
2025-03-16 14:19 ` [PATCH v3 net-next PATCH 1/1] " Lucien.Jheng
2025-03-16 16:31   ` Daniel Golle
2025-03-16 20:15   ` Russell King (Oracle)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.