From: Christian Marangi <ansuelsmth@gmail.com>
To: Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@kernel.org>, Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Philipp Zabel <p.zabel@pengutronix.de>,
Felix Fietkau <nbd@nbd.name>,
linux-clk@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
Cc: Christian Marangi <ansuelsmth@gmail.com>
Subject: [PATCH 1/5] clk: en7523: convert driver to regmap API
Date: Wed, 28 May 2025 02:49:14 +0200 [thread overview]
Message-ID: <20250528004924.19970-2-ansuelsmth@gmail.com> (raw)
In-Reply-To: <20250528004924.19970-1-ansuelsmth@gmail.com>
Convert driver to regmap API, in preparation for support of Airoha
AN7523 as the SCU will be an MFD and the regmap will be provided in the
parent node.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/clk-en7523.c | 137 ++++++++++++++++++++++-----------------
1 file changed, 76 insertions(+), 61 deletions(-)
diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
index 15bbdeb60b8e..314e7450313f 100644
--- a/drivers/clk/clk-en7523.c
+++ b/drivers/clk/clk-en7523.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
@@ -34,6 +35,7 @@
#define REG_RESET_CONTROL_PCIE2 BIT(26)
/* EN7581 */
#define REG_NP_SCU_PCIC 0x88
+#define REG_PCIE_CTRL GENMASK(7, 0)
#define REG_NP_SCU_SSTR 0x9c
#define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13)
#define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11)
@@ -63,14 +65,14 @@ struct en_clk_desc {
};
struct en_clk_gate {
- void __iomem *base;
+ struct regmap *map;
struct clk_hw hw;
};
struct en_rst_data {
const u16 *bank_ofs;
const u16 *idx_map;
- void __iomem *base;
+ struct regmap *map;
struct reset_controller_dev rcdev;
};
@@ -388,44 +390,44 @@ static u32 en7523_get_div(const struct en_clk_desc *desc, u32 val)
static int en7523_pci_is_enabled(struct clk_hw *hw)
{
struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
+ u32 val;
- return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1);
+ regmap_read(cg->map, REG_PCI_CONTROL, &val);
+ return !!(val & REG_PCI_CONTROL_REFCLK_EN1);
}
static int en7523_pci_prepare(struct clk_hw *hw)
{
struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
- void __iomem *np_base = cg->base;
- u32 val, mask;
+ struct regmap *map = cg->map;
+ u32 mask;
/* Need to pull device low before reset */
- val = readl(np_base + REG_PCI_CONTROL);
- val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT);
- writel(val, np_base + REG_PCI_CONTROL);
+ regmap_clear_bits(map, REG_PCI_CONTROL,
+ REG_PCI_CONTROL_PERSTOUT1 |
+ REG_PCI_CONTROL_PERSTOUT);
usleep_range(1000, 2000);
/* Enable PCIe port 1 */
- val |= REG_PCI_CONTROL_REFCLK_EN1;
- writel(val, np_base + REG_PCI_CONTROL);
+ regmap_set_bits(map, REG_PCI_CONTROL,
+ REG_PCI_CONTROL_REFCLK_EN1);
usleep_range(1000, 2000);
/* Reset to default */
- val = readl(np_base + REG_RESET_CONTROL1);
mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
REG_RESET_CONTROL_PCIEHB;
- writel(val & ~mask, np_base + REG_RESET_CONTROL1);
+ regmap_clear_bits(map, REG_RESET_CONTROL1, mask);
usleep_range(1000, 2000);
- writel(val | mask, np_base + REG_RESET_CONTROL1);
+ regmap_set_bits(map, REG_RESET_CONTROL1, mask);
msleep(100);
- writel(val & ~mask, np_base + REG_RESET_CONTROL1);
+ regmap_clear_bits(map, REG_RESET_CONTROL1, mask);
usleep_range(5000, 10000);
/* Release device */
mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT;
- val = readl(np_base + REG_PCI_CONTROL);
- writel(val & ~mask, np_base + REG_PCI_CONTROL);
+ regmap_clear_bits(map, REG_PCI_CONTROL, mask);
usleep_range(1000, 2000);
- writel(val | mask, np_base + REG_PCI_CONTROL);
+ regmap_set_bits(map, REG_PCI_CONTROL, mask);
msleep(250);
return 0;
@@ -434,16 +436,13 @@ static int en7523_pci_prepare(struct clk_hw *hw)
static void en7523_pci_unprepare(struct clk_hw *hw)
{
struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
- void __iomem *np_base = cg->base;
- u32 val;
+ struct regmap *map = cg->map;
- val = readl(np_base + REG_PCI_CONTROL);
- val &= ~REG_PCI_CONTROL_REFCLK_EN1;
- writel(val, np_base + REG_PCI_CONTROL);
+ regmap_clear_bits(map, REG_PCI_CONTROL, REG_PCI_CONTROL_REFCLK_EN1);
}
static struct clk_hw *en7523_register_pcie_clk(struct device *dev,
- void __iomem *np_base)
+ struct regmap *clk_map)
{
const struct en_clk_soc_data *soc_data = device_get_match_data(dev);
struct clk_init_data init = {
@@ -456,7 +455,7 @@ static struct clk_hw *en7523_register_pcie_clk(struct device *dev,
if (!cg)
return NULL;
- cg->base = np_base;
+ cg->map = clk_map;
cg->hw.init = &init;
if (init.ops->unprepare)
@@ -474,21 +473,20 @@ static int en7581_pci_is_enabled(struct clk_hw *hw)
u32 val, mask;
mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1;
- val = readl(cg->base + REG_PCI_CONTROL);
+ regmap_read(cg->map, REG_PCI_CONTROL, &val);
return (val & mask) == mask;
}
static int en7581_pci_enable(struct clk_hw *hw)
{
struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
- void __iomem *np_base = cg->base;
- u32 val, mask;
+ struct regmap *map = cg->map;
+ u32 mask;
mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
REG_PCI_CONTROL_PERSTOUT;
- val = readl(np_base + REG_PCI_CONTROL);
- writel(val | mask, np_base + REG_PCI_CONTROL);
+ regmap_set_bits(map, REG_PCI_CONTROL, mask);
return 0;
}
@@ -496,19 +494,18 @@ static int en7581_pci_enable(struct clk_hw *hw)
static void en7581_pci_disable(struct clk_hw *hw)
{
struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
- void __iomem *np_base = cg->base;
- u32 val, mask;
+ struct regmap *map = cg->map;
+ u32 mask;
mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
REG_PCI_CONTROL_PERSTOUT;
- val = readl(np_base + REG_PCI_CONTROL);
- writel(val & ~mask, np_base + REG_PCI_CONTROL);
+ regmap_clear_bits(map, REG_PCI_CONTROL, mask);
usleep_range(1000, 2000);
}
static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
- void __iomem *base, void __iomem *np_base)
+ struct regmap *map, struct regmap *clk_map)
{
struct clk_hw *hw;
u32 rate;
@@ -517,10 +514,12 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat
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);
+ u32 val;
+
+ regmap_read(map, desc->base_reg, &val);
rate = en7523_get_base_rate(desc, val);
- val = readl(base + reg);
+ regmap_read(map, reg, &val);
rate /= en7523_get_div(desc, val);
hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
@@ -533,30 +532,47 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat
clk_data->hws[desc->id] = hw;
}
- hw = en7523_register_pcie_clk(dev, np_base);
+ hw = en7523_register_pcie_clk(dev, clk_map);
clk_data->hws[EN7523_CLK_PCIE] = hw;
}
+static const struct regmap_config en7523_clk_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
static int en7523_clk_hw_init(struct platform_device *pdev,
struct clk_hw_onecell_data *clk_data)
{
void __iomem *base, *np_base;
+ struct regmap *map, *clk_map;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
+ map = devm_regmap_init_mmio(&pdev->dev, base,
+ &en7523_clk_regmap_config);
+ if (IS_ERR(map))
+ return PTR_ERR(map);
+
np_base = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(np_base))
return PTR_ERR(np_base);
- en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
+ clk_map = devm_regmap_init_mmio(&pdev->dev, np_base,
+ &en7523_clk_regmap_config);
+ if (IS_ERR(clk_map))
+ return PTR_ERR(clk_map);
+
+ en7523_register_clocks(&pdev->dev, clk_data, map, clk_map);
return 0;
}
static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
- struct regmap *map, void __iomem *base)
+ struct regmap *map, struct regmap *clk_map)
{
struct clk_hw *hw;
u32 rate;
@@ -593,7 +609,7 @@ static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_dat
clk_data->hws[desc->id] = hw;
}
- hw = en7523_register_pcie_clk(dev, base);
+ hw = en7523_register_pcie_clk(dev, clk_map);
clk_data->hws[EN7523_CLK_PCIE] = hw;
}
@@ -601,15 +617,10 @@ static int en7523_reset_update(struct reset_controller_dev *rcdev,
unsigned long id, bool assert)
{
struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev);
- void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK];
- u32 val;
+ u32 addr = rst_data->bank_ofs[id / RST_NR_PER_BANK];
- val = readl(addr);
- if (assert)
- val |= BIT(id % RST_NR_PER_BANK);
- else
- val &= ~BIT(id % RST_NR_PER_BANK);
- writel(val, addr);
+ regmap_update_bits(rst_data->map, addr, BIT(id % RST_NR_PER_BANK),
+ assert ? BIT(id % RST_NR_PER_BANK) : 0);
return 0;
}
@@ -630,9 +641,11 @@ static int en7523_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev);
- void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK];
+ u32 addr = rst_data->bank_ofs[id / RST_NR_PER_BANK];
+ u32 val;
- return !!(readl(addr) & BIT(id % RST_NR_PER_BANK));
+ regmap_read(rst_data->map, addr, &val);
+ return !!(val & BIT(id % RST_NR_PER_BANK));
}
static int en7523_reset_xlate(struct reset_controller_dev *rcdev,
@@ -652,7 +665,7 @@ static const struct reset_control_ops en7581_reset_ops = {
.status = en7523_reset_status,
};
-static int en7581_reset_register(struct device *dev, void __iomem *base)
+static int en7581_reset_register(struct device *dev, struct regmap *map)
{
struct en_rst_data *rst_data;
@@ -662,7 +675,7 @@ static int en7581_reset_register(struct device *dev, void __iomem *base)
rst_data->bank_ofs = en7581_rst_ofs;
rst_data->idx_map = en7581_rst_map;
- rst_data->base = base;
+ rst_data->map = map;
rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map);
rst_data->rcdev.of_xlate = en7523_reset_xlate;
@@ -678,9 +691,8 @@ static int en7581_reset_register(struct device *dev, void __iomem *base)
static int en7581_clk_hw_init(struct platform_device *pdev,
struct clk_hw_onecell_data *clk_data)
{
- struct regmap *map;
+ struct regmap *map, *clk_map;
void __iomem *base;
- u32 val;
map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
if (IS_ERR(map))
@@ -690,15 +702,18 @@ static int en7581_clk_hw_init(struct platform_device *pdev,
if (IS_ERR(base))
return PTR_ERR(base);
- en7581_register_clocks(&pdev->dev, clk_data, map, base);
+ clk_map = devm_regmap_init_mmio(&pdev->dev, base, &en7523_clk_regmap_config);
+ if (IS_ERR(clk_map))
+ return PTR_ERR(clk_map);
+
+ en7581_register_clocks(&pdev->dev, clk_data, map, clk_map);
- val = readl(base + REG_NP_SCU_SSTR);
- val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
- writel(val, base + REG_NP_SCU_SSTR);
- val = readl(base + REG_NP_SCU_PCIC);
- writel(val | 3, base + REG_NP_SCU_PCIC);
+ regmap_clear_bits(clk_map, REG_NP_SCU_SSTR,
+ REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
+ regmap_update_bits(clk_map, REG_NP_SCU_PCIC, REG_PCIE_CTRL,
+ FIELD_PREP(REG_PCIE_CTRL, 3));
- return en7581_reset_register(&pdev->dev, base);
+ return en7581_reset_register(&pdev->dev, clk_map);
}
static int en7523_clk_probe(struct platform_device *pdev)
--
2.48.1
next prev parent reply other threads:[~2025-05-28 0:49 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-28 0:49 [PATCH 0/5] clk: add support for Airoha AN7583 clock Christian Marangi
2025-05-28 0:49 ` Christian Marangi [this message]
2025-05-28 0:49 ` [PATCH 2/5] clk: en7523: generalize register clocks function Christian Marangi
2025-05-28 0:49 ` [PATCH 3/5] dt-bindings: reset: add binding for Airoha AN7583 SoC reset Christian Marangi
2025-05-28 7:31 ` Krzysztof Kozlowski
2025-05-28 0:49 ` [PATCH 4/5] dt-bindings: clock: airoha: Document support for AN7583 clock Christian Marangi
2025-05-28 7:30 ` Krzysztof Kozlowski
2025-05-28 8:54 ` Christian Marangi
2025-05-28 11:56 ` Krzysztof Kozlowski
2025-05-28 12:57 ` Christian Marangi
2025-05-29 9:00 ` Krzysztof Kozlowski
2025-05-30 15:26 ` Christian Marangi
2025-06-02 8:13 ` Krzysztof Kozlowski
2025-05-28 0:49 ` [PATCH 5/5] clk: en7523: add support for Airoha " Christian Marangi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250528004924.19970-2-ansuelsmth@gmail.com \
--to=ansuelsmth@gmail.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mturquette@baylibre.com \
--cc=nbd@nbd.name \
--cc=p.zabel@pengutronix.de \
--cc=robh@kernel.org \
--cc=sboyd@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).