mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-30 18:47:06 +00:00
161 lines
4.8 KiB
Diff
161 lines
4.8 KiB
Diff
|
From f849bcb746abeaafa63b4f02f1d8bb22703fc645 Mon Sep 17 00:00:00 2001
|
||
|
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||
|
Date: Tue, 3 Sep 2024 23:39:48 +0200
|
||
|
Subject: [PATCH 3/6] clk: en7523: introduce chip_scu regmap
|
||
|
|
||
|
Introduce chip_scu regmap pointer since EN7581 SoC will access chip-scu
|
||
|
memory area via a syscon node. Remove first memory region mapping
|
||
|
for EN7581 SoC. This patch does not introduce any backward incompatibility
|
||
|
since the dts for EN7581 SoC is not upstream yet.
|
||
|
|
||
|
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||
|
---
|
||
|
drivers/clk/clk-en7523.c | 81 ++++++++++++++++++++++++++++++----------
|
||
|
1 file changed, 61 insertions(+), 20 deletions(-)
|
||
|
|
||
|
--- a/drivers/clk/clk-en7523.c
|
||
|
+++ b/drivers/clk/clk-en7523.c
|
||
|
@@ -3,8 +3,10 @@
|
||
|
#include <linux/delay.h>
|
||
|
#include <linux/clk-provider.h>
|
||
|
#include <linux/io.h>
|
||
|
+#include <linux/mfd/syscon.h>
|
||
|
#include <linux/platform_device.h>
|
||
|
#include <linux/property.h>
|
||
|
+#include <linux/regmap.h>
|
||
|
#include <linux/reset-controller.h>
|
||
|
#include <dt-bindings/clock/en7523-clk.h>
|
||
|
#include <dt-bindings/reset/airoha,en7581-reset.h>
|
||
|
@@ -247,15 +249,11 @@ static const u16 en7581_rst_map[] = {
|
||
|
[EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
|
||
|
};
|
||
|
|
||
|
-static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i)
|
||
|
+static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val)
|
||
|
{
|
||
|
- const struct en_clk_desc *desc = &en7523_base_clks[i];
|
||
|
- u32 val;
|
||
|
-
|
||
|
if (!desc->base_bits)
|
||
|
return desc->base_value;
|
||
|
|
||
|
- val = readl(base + desc->base_reg);
|
||
|
val >>= desc->base_shift;
|
||
|
val &= (1 << desc->base_bits) - 1;
|
||
|
|
||
|
@@ -265,16 +263,11 @@ static unsigned int en7523_get_base_rate
|
||
|
return desc->base_values[val];
|
||
|
}
|
||
|
|
||
|
-static u32 en7523_get_div(void __iomem *base, int i)
|
||
|
+static u32 en7523_get_div(const struct en_clk_desc *desc, u32 val)
|
||
|
{
|
||
|
- const struct en_clk_desc *desc = &en7523_base_clks[i];
|
||
|
- u32 reg, val;
|
||
|
-
|
||
|
if (!desc->div_bits)
|
||
|
return 1;
|
||
|
|
||
|
- reg = desc->div_reg ? desc->div_reg : desc->base_reg;
|
||
|
- val = readl(base + reg);
|
||
|
val >>= desc->div_shift;
|
||
|
val &= (1 << desc->div_bits) - 1;
|
||
|
|
||
|
@@ -416,9 +409,12 @@ static void en7523_register_clocks(struc
|
||
|
|
||
|
for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
|
||
|
const struct en_clk_desc *desc = &en7523_base_clks[i];
|
||
|
+ u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg;
|
||
|
+ u32 val = readl(base + desc->base_reg);
|
||
|
|
||
|
- rate = en7523_get_base_rate(base, i);
|
||
|
- rate /= en7523_get_div(base, i);
|
||
|
+ rate = en7523_get_base_rate(desc, val);
|
||
|
+ val = readl(base + reg);
|
||
|
+ rate /= en7523_get_div(desc, val);
|
||
|
|
||
|
hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
|
||
|
if (IS_ERR(hw)) {
|
||
|
@@ -454,21 +450,66 @@ static int en7523_clk_hw_init(struct pla
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
|
||
|
+ struct regmap *map, void __iomem *base)
|
||
|
+{
|
||
|
+ struct clk_hw *hw;
|
||
|
+ u32 rate;
|
||
|
+ int i;
|
||
|
+
|
||
|
+ for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
|
||
|
+ const struct en_clk_desc *desc = &en7523_base_clks[i];
|
||
|
+ u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg;
|
||
|
+ 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);
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ rate = en7523_get_base_rate(desc, val);
|
||
|
+
|
||
|
+ err = regmap_read(map, reg, &val);
|
||
|
+ if (err) {
|
||
|
+ pr_err("Failed reading fixed clk div %s: %d\n",
|
||
|
+ desc->name, err);
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ 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));
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+
|
||
|
+ clk_data->hws[desc->id] = hw;
|
||
|
+ }
|
||
|
+
|
||
|
+ hw = en7523_register_pcie_clk(dev, base);
|
||
|
+ clk_data->hws[EN7523_CLK_PCIE] = hw;
|
||
|
+
|
||
|
+ clk_data->num = EN7523_NUM_CLOCKS;
|
||
|
+}
|
||
|
+
|
||
|
static int en7581_clk_hw_init(struct platform_device *pdev,
|
||
|
struct clk_hw_onecell_data *clk_data)
|
||
|
{
|
||
|
- void __iomem *base, *np_base;
|
||
|
+ void __iomem *np_base;
|
||
|
+ struct regmap *map;
|
||
|
u32 val;
|
||
|
|
||
|
- base = devm_platform_ioremap_resource(pdev, 0);
|
||
|
- if (IS_ERR(base))
|
||
|
- return PTR_ERR(base);
|
||
|
+ map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
|
||
|
+ if (IS_ERR(map))
|
||
|
+ return PTR_ERR(map);
|
||
|
|
||
|
- np_base = devm_platform_ioremap_resource(pdev, 1);
|
||
|
+ np_base = devm_platform_ioremap_resource(pdev, 0);
|
||
|
if (IS_ERR(np_base))
|
||
|
return PTR_ERR(np_base);
|
||
|
|
||
|
- en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
|
||
|
+ en7581_register_clocks(&pdev->dev, clk_data, map, np_base);
|
||
|
|
||
|
val = readl(np_base + REG_NP_SCU_SSTR);
|
||
|
val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
|
||
|
@@ -545,7 +586,7 @@ static int en7523_reset_register(struct
|
||
|
if (!soc_data->reset.idx_map_nr)
|
||
|
return 0;
|
||
|
|
||
|
- base = devm_platform_ioremap_resource(pdev, 2);
|
||
|
+ base = devm_platform_ioremap_resource(pdev, 1);
|
||
|
if (IS_ERR(base))
|
||
|
return PTR_ERR(base);
|
||
|
|