2 * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include <linux/clk-provider.h>
21 static inline struct tegra_clk_periph_fixed
*
22 to_tegra_clk_periph_fixed(struct clk_hw
*hw
)
24 return container_of(hw
, struct tegra_clk_periph_fixed
, hw
);
27 static int tegra_clk_periph_fixed_is_enabled(struct clk_hw
*hw
)
29 struct tegra_clk_periph_fixed
*fixed
= to_tegra_clk_periph_fixed(hw
);
30 u32 mask
= 1 << (fixed
->num
% 32), value
;
32 value
= readl(fixed
->base
+ fixed
->regs
->enb_reg
);
34 value
= readl(fixed
->base
+ fixed
->regs
->rst_reg
);
35 if ((value
& mask
) == 0)
42 static int tegra_clk_periph_fixed_enable(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_set_reg
);
52 static void tegra_clk_periph_fixed_disable(struct clk_hw
*hw
)
54 struct tegra_clk_periph_fixed
*fixed
= to_tegra_clk_periph_fixed(hw
);
55 u32 mask
= 1 << (fixed
->num
% 32);
57 writel(mask
, fixed
->base
+ fixed
->regs
->enb_clr_reg
);
61 tegra_clk_periph_fixed_recalc_rate(struct clk_hw
*hw
,
62 unsigned long parent_rate
)
64 struct tegra_clk_periph_fixed
*fixed
= to_tegra_clk_periph_fixed(hw
);
65 unsigned long long rate
;
67 rate
= (unsigned long long)parent_rate
* fixed
->mul
;
68 do_div(rate
, fixed
->div
);
70 return (unsigned long)rate
;
73 static const struct clk_ops tegra_clk_periph_fixed_ops
= {
74 .is_enabled
= tegra_clk_periph_fixed_is_enabled
,
75 .enable
= tegra_clk_periph_fixed_enable
,
76 .disable
= tegra_clk_periph_fixed_disable
,
77 .recalc_rate
= tegra_clk_periph_fixed_recalc_rate
,
80 struct clk
*tegra_clk_register_periph_fixed(const char *name
,
88 const struct tegra_clk_periph_regs
*regs
;
89 struct tegra_clk_periph_fixed
*fixed
;
90 struct clk_init_data init
;
93 regs
= get_reg_bank(num
);
95 return ERR_PTR(-EINVAL
);
97 fixed
= kzalloc(sizeof(*fixed
), GFP_KERNEL
);
99 return ERR_PTR(-ENOMEM
);
103 init
.parent_names
= parent
? &parent
: NULL
;
104 init
.num_parents
= parent
? 1 : 0;
105 init
.ops
= &tegra_clk_periph_fixed_ops
;
113 fixed
->hw
.init
= &init
;
115 clk
= clk_register(NULL
, &fixed
->hw
);