1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
6 #include <linux/clk-provider.h>
11 static inline struct tegra_clk_periph_fixed
*
12 to_tegra_clk_periph_fixed(struct clk_hw
*hw
)
14 return container_of(hw
, struct tegra_clk_periph_fixed
, hw
);
17 static int tegra_clk_periph_fixed_is_enabled(struct clk_hw
*hw
)
19 struct tegra_clk_periph_fixed
*fixed
= to_tegra_clk_periph_fixed(hw
);
20 u32 mask
= 1 << (fixed
->num
% 32), value
;
22 value
= readl(fixed
->base
+ fixed
->regs
->enb_reg
);
24 value
= readl(fixed
->base
+ fixed
->regs
->rst_reg
);
25 if ((value
& mask
) == 0)
32 static int tegra_clk_periph_fixed_enable(struct clk_hw
*hw
)
34 struct tegra_clk_periph_fixed
*fixed
= to_tegra_clk_periph_fixed(hw
);
35 u32 mask
= 1 << (fixed
->num
% 32);
37 writel(mask
, fixed
->base
+ fixed
->regs
->enb_set_reg
);
42 static void tegra_clk_periph_fixed_disable(struct clk_hw
*hw
)
44 struct tegra_clk_periph_fixed
*fixed
= to_tegra_clk_periph_fixed(hw
);
45 u32 mask
= 1 << (fixed
->num
% 32);
47 writel(mask
, fixed
->base
+ fixed
->regs
->enb_clr_reg
);
51 tegra_clk_periph_fixed_recalc_rate(struct clk_hw
*hw
,
52 unsigned long parent_rate
)
54 struct tegra_clk_periph_fixed
*fixed
= to_tegra_clk_periph_fixed(hw
);
55 unsigned long long rate
;
57 rate
= (unsigned long long)parent_rate
* fixed
->mul
;
58 do_div(rate
, fixed
->div
);
60 return (unsigned long)rate
;
63 static const struct clk_ops tegra_clk_periph_fixed_ops
= {
64 .is_enabled
= tegra_clk_periph_fixed_is_enabled
,
65 .enable
= tegra_clk_periph_fixed_enable
,
66 .disable
= tegra_clk_periph_fixed_disable
,
67 .recalc_rate
= tegra_clk_periph_fixed_recalc_rate
,
70 struct clk
*tegra_clk_register_periph_fixed(const char *name
,
78 const struct tegra_clk_periph_regs
*regs
;
79 struct tegra_clk_periph_fixed
*fixed
;
80 struct clk_init_data init
;
83 regs
= get_reg_bank(num
);
85 return ERR_PTR(-EINVAL
);
87 fixed
= kzalloc(sizeof(*fixed
), GFP_KERNEL
);
89 return ERR_PTR(-ENOMEM
);
93 init
.parent_names
= parent
? &parent
: NULL
;
94 init
.num_parents
= parent
? 1 : 0;
95 init
.ops
= &tegra_clk_periph_fixed_ops
;
103 fixed
->hw
.init
= &init
;
105 clk
= clk_register(NULL
, &fixed
->hw
);