brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · c088e7a Raw
111 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2015, NVIDIA CORPORATION.  All rights reserved.4 */5 6#include <linux/clk-provider.h>7#include <linux/io.h>8 9#include "clk.h"10 11static inline struct tegra_clk_periph_fixed *12to_tegra_clk_periph_fixed(struct clk_hw *hw)13{14	return container_of(hw, struct tegra_clk_periph_fixed, hw);15}16 17static int tegra_clk_periph_fixed_is_enabled(struct clk_hw *hw)18{19	struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);20	u32 mask = 1 << (fixed->num % 32), value;21 22	value = readl(fixed->base + fixed->regs->enb_reg);23	if (value & mask) {24		value = readl(fixed->base + fixed->regs->rst_reg);25		if ((value & mask) == 0)26			return 1;27	}28 29	return 0;30}31 32static int tegra_clk_periph_fixed_enable(struct clk_hw *hw)33{34	struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);35	u32 mask = 1 << (fixed->num % 32);36 37	writel(mask, fixed->base + fixed->regs->enb_set_reg);38 39	return 0;40}41 42static void tegra_clk_periph_fixed_disable(struct clk_hw *hw)43{44	struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);45	u32 mask = 1 << (fixed->num % 32);46 47	writel(mask, fixed->base + fixed->regs->enb_clr_reg);48}49 50static unsigned long51tegra_clk_periph_fixed_recalc_rate(struct clk_hw *hw,52				   unsigned long parent_rate)53{54	struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);55	unsigned long long rate;56 57	rate = (unsigned long long)parent_rate * fixed->mul;58	do_div(rate, fixed->div);59 60	return (unsigned long)rate;61}62 63static 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,68};69 70struct clk *tegra_clk_register_periph_fixed(const char *name,71					    const char *parent,72					    unsigned long flags,73					    void __iomem *base,74					    unsigned int mul,75					    unsigned int div,76					    unsigned int num)77{78	const struct tegra_clk_periph_regs *regs;79	struct tegra_clk_periph_fixed *fixed;80	struct clk_init_data init;81	struct clk *clk;82 83	regs = get_reg_bank(num);84	if (!regs)85		return ERR_PTR(-EINVAL);86 87	fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);88	if (!fixed)89		return ERR_PTR(-ENOMEM);90 91	init.name = name;92	init.flags = flags;93	init.parent_names = parent ? &parent : NULL;94	init.num_parents = parent ? 1 : 0;95	init.ops = &tegra_clk_periph_fixed_ops;96 97	fixed->base = base;98	fixed->regs = regs;99	fixed->mul = mul;100	fixed->div = div;101	fixed->num = num;102 103	fixed->hw.init = &init;104 105	clk = clk_register(NULL, &fixed->hw);106	if (IS_ERR(clk))107		kfree(fixed);108 109	return clk;110}111