Skip to content

Commit 1199419

Browse files
MrVanabelvesa
authored andcommitted
clk: imx: add i.MX93 composite clk
i.MX93 CCM ROOT clock has a mux, gate and divider in one register, here is to combine all these into one composite clk and simplify clk tree. i.MX93 CCM is a new IP compared with i.MX8M, so introduce a new file. Reviewed-by: Abel Vesa <[email protected]> Reviewed-by: Stephen Boyd <[email protected]> Signed-off-by: Peng Fan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Abel Vesa <[email protected]>
1 parent 9a45081 commit 1199419

File tree

3 files changed

+103
-0
lines changed

3 files changed

+103
-0
lines changed

drivers/clk/imx/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mxc-clk-objs += clk.o
44
mxc-clk-objs += clk-busy.o
55
mxc-clk-objs += clk-composite-7ulp.o
66
mxc-clk-objs += clk-composite-8m.o
7+
mxc-clk-objs += clk-composite-93.o
78
mxc-clk-objs += clk-cpu.o
89
mxc-clk-objs += clk-divider-gate.o
910
mxc-clk-objs += clk-fixup-div.o

drivers/clk/imx/clk-composite-93.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/*
3+
* Copyright 2021 NXP
4+
*
5+
* Peng Fan <[email protected]>
6+
*/
7+
8+
#include <linux/clk-provider.h>
9+
#include <linux/errno.h>
10+
#include <linux/export.h>
11+
#include <linux/io.h>
12+
#include <linux/slab.h>
13+
14+
#include "clk.h"
15+
16+
#define CCM_DIV_SHIFT 0
17+
#define CCM_DIV_WIDTH 8
18+
#define CCM_MUX_SHIFT 8
19+
#define CCM_MUX_MASK 3
20+
#define CCM_OFF_SHIFT 24
21+
22+
#define AUTHEN_OFFSET 0x30
23+
#define TZ_NS_SHIFT 9
24+
#define TZ_NS_MASK BIT(9)
25+
26+
struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *parent_names,
27+
int num_parents, void __iomem *reg,
28+
unsigned long flags)
29+
{
30+
struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw;
31+
struct clk_hw *div_hw, *gate_hw;
32+
struct clk_divider *div = NULL;
33+
struct clk_gate *gate = NULL;
34+
struct clk_mux *mux = NULL;
35+
bool clk_ro = false;
36+
37+
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
38+
if (!mux)
39+
goto fail;
40+
41+
mux_hw = &mux->hw;
42+
mux->reg = reg;
43+
mux->shift = CCM_MUX_SHIFT;
44+
mux->mask = CCM_MUX_MASK;
45+
mux->lock = &imx_ccm_lock;
46+
47+
div = kzalloc(sizeof(*div), GFP_KERNEL);
48+
if (!div)
49+
goto fail;
50+
51+
div_hw = &div->hw;
52+
div->reg = reg;
53+
div->shift = CCM_DIV_SHIFT;
54+
div->width = CCM_DIV_WIDTH;
55+
div->lock = &imx_ccm_lock;
56+
div->flags = CLK_DIVIDER_ROUND_CLOSEST;
57+
58+
if (!(readl(reg + AUTHEN_OFFSET) & TZ_NS_MASK))
59+
clk_ro = true;
60+
61+
if (clk_ro) {
62+
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
63+
mux_hw, &clk_mux_ro_ops, div_hw,
64+
&clk_divider_ro_ops, NULL, NULL, flags);
65+
} else {
66+
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
67+
if (!gate)
68+
goto fail;
69+
70+
gate_hw = &gate->hw;
71+
gate->reg = reg;
72+
gate->bit_idx = CCM_OFF_SHIFT;
73+
gate->lock = &imx_ccm_lock;
74+
gate->flags = CLK_GATE_SET_TO_DISABLE;
75+
76+
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
77+
mux_hw, &clk_mux_ops, div_hw,
78+
&clk_divider_ops, gate_hw,
79+
&clk_gate_ops, flags | CLK_SET_RATE_NO_REPARENT);
80+
}
81+
82+
if (IS_ERR(hw))
83+
goto fail;
84+
85+
return hw;
86+
87+
fail:
88+
kfree(gate);
89+
kfree(div);
90+
kfree(mux);
91+
return ERR_CAST(hw);
92+
}
93+
EXPORT_SYMBOL_GPL(imx93_clk_composite_flags);

drivers/clk/imx/clk.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,15 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
419419
IMX_COMPOSITE_FW_MANAGED, \
420420
IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE)
421421

422+
struct clk_hw *imx93_clk_composite_flags(const char *name,
423+
const char * const *parent_names,
424+
int num_parents,
425+
void __iomem *reg,
426+
unsigned long flags);
427+
#define imx93_clk_composite(name, parent_names, num_parents, reg) \
428+
imx93_clk_composite_flags(name, parent_names, num_parents, reg, \
429+
CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
430+
422431
struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name,
423432
unsigned long flags, void __iomem *reg, u8 shift, u8 width,
424433
u8 clk_divider_flags, const struct clk_div_table *table,

0 commit comments

Comments
 (0)