mirror of
https://github.com/openwrt/openwrt.git
synced 2026-05-05 22:25:44 +04:00
c5b12fc02a
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>
148 lines
4.0 KiB
Diff
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);
|