Files
openwrt/target/linux/airoha/patches-6.12/600-03-clk-en7523-convert-to-full-clk_hw-implementation.patch
T
Christian Marangi c5b12fc02a airoha: Introduce support for Airoha AN7583 SoC
Introduce initial support for Airoha AN7583 SoC and add all the required
patch for basic functionality of the SoC.

Airoha AN7583 is based on Airoha EN7581 SoC with some major changes on
the PHY handling and Serdes. It can be see as a lower spec of EN7581
with modern and simplified implementations.

All the patch are sent upstream and are pending revision. Support for
PCIe and USB will come later as soon as DT structure is accepted
upstream.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
2025-09-26 05:00:07 +02:00

148 lines
4.0 KiB
Diff

From 933030fd268ac111eb9db13b5a90b7c66cd9df41 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Tue, 17 Jun 2025 11:38:21 +0200
Subject: [PATCH 03/10] clk: en7523: convert to full clk_hw implementation
In preparation for support of .set_rate, convert the clock register
logic from fixed clock implementation to full clk_hw implementation with
dedicated OPs.
This is just a rework and no behaviour change is expected.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/clk-en7523.c | 83 ++++++++++++++++++++++++++++------------
1 file changed, 59 insertions(+), 24 deletions(-)
--- a/drivers/clk/clk-en7523.c
+++ b/drivers/clk/clk-en7523.c
@@ -69,6 +69,12 @@ struct en_clk_gate {
struct clk_hw hw;
};
+struct en_clk {
+ struct regmap *map;
+ const struct en_clk_desc *desc;
+ struct clk_hw hw;
+};
+
struct en_rst_data {
const u16 *bank_ofs;
const u16 *idx_map;
@@ -471,44 +477,73 @@ static struct clk_hw *en7523_register_pc
return &cg->hw;
}
+static unsigned long en75xx_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct en_clk *c = container_of(hw, struct en_clk, hw);
+ const struct en_clk_desc *desc = c->desc;
+ struct regmap *map = c->map;
+ u32 val, reg;
+ u32 rate;
+ int err;
+
+ err = regmap_read(map, desc->base_reg, &val);
+ if (err) {
+ pr_err("Failed reading fixed clk rate %s: %d\n",
+ desc->name, err);
+ return err;
+ }
+ rate = en7523_get_base_rate(desc, val);
+
+ reg = desc->div_reg ? desc->div_reg : desc->base_reg;
+ err = regmap_read(map, reg, &val);
+ if (err) {
+ pr_err("Failed reading fixed clk div %s: %d\n",
+ desc->name, err);
+ return err;
+ }
+
+ return rate / en7523_get_div(desc, val);
+}
+
+static const struct clk_ops en75xx_clk_ops = {
+ .recalc_rate = en75xx_recalc_rate,
+};
+
static int en75xx_register_clocks(struct device *dev,
const struct en_clk_soc_data *soc_data,
struct clk_hw_onecell_data *clk_data,
struct regmap *map, struct regmap *clk_map)
{
struct clk_hw *hw;
- u32 rate;
int i;
for (i = 0; i < soc_data->num_clocks - 1; i++) {
const struct en_clk_desc *desc = &soc_data->base_clks[i];
- u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg;
+ struct clk_init_data init = {
+ .ops = &en75xx_clk_ops,
+ };
+ struct en_clk *en_clk;
int err;
- err = regmap_read(map, desc->base_reg, &val);
- if (err) {
- pr_err("Failed reading fixed clk rate %s: %d\n",
- desc->name, err);
- return err;
- }
- rate = en7523_get_base_rate(desc, val);
+ en_clk = devm_kzalloc(dev, sizeof(*en_clk), GFP_KERNEL);
+ if (!en_clk)
+ return -ENOMEM;
- err = regmap_read(map, reg, &val);
+ init.name = desc->name;
+
+ en_clk->map = map;
+ en_clk->desc = desc;
+ en_clk->hw.init = &init;
+
+ err = devm_clk_hw_register(dev, &en_clk->hw);
if (err) {
- pr_err("Failed reading fixed clk div %s: %d\n",
+ pr_err("Failed to register clk %s: %d\n",
desc->name, err);
return err;
}
- rate /= en7523_get_div(desc, val);
-
- hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
- if (IS_ERR(hw)) {
- pr_err("Failed to register clk %s: %ld\n",
- desc->name, PTR_ERR(hw));
- return PTR_ERR(hw);
- }
- clk_data->hws[desc->id] = hw;
+ clk_data->hws[desc->id] = &en_clk->hw;
}
hw = en7523_register_pcie_clk(dev, clk_map);
@@ -672,7 +707,7 @@ static int en7581_clk_hw_init(struct pla
{
struct regmap *map, *clk_map;
void __iomem *base;
- int ret;
+ int err;
map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
if (IS_ERR(map))
@@ -686,9 +721,9 @@ static int en7581_clk_hw_init(struct pla
if (IS_ERR(clk_map))
return PTR_ERR(clk_map);
- ret = en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map);
- if (ret)
- return ret;
+ err = en75xx_register_clocks(&pdev->dev, soc_data, clk_data, map, clk_map);
+ if (err)
+ return err;
regmap_clear_bits(clk_map, REG_NP_SCU_SSTR,
REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);