Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Copyright 2012 Freescale Semiconductor, Inc.
  4 */
  5
  6#include <linux/clk-provider.h>
  7#include <linux/delay.h>
  8#include <linux/err.h>
  9#include <linux/io.h>
 10#include <linux/slab.h>
 11#include "clk.h"
 12
 13/**
 14 * struct clk_pll - mxs pll clock
 15 * @hw: clk_hw for the pll
 16 * @base: base address of the pll
 17 * @power: the shift of power bit
 18 * @rate: the clock rate of the pll
 19 *
 20 * The mxs pll is a fixed rate clock with power and gate control,
 21 * and the shift of gate bit is always 31.
 22 */
 23struct clk_pll {
 24	struct clk_hw hw;
 25	void __iomem *base;
 26	u8 power;
 27	unsigned long rate;
 28};
 29
 30#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
 31
 32static int clk_pll_prepare(struct clk_hw *hw)
 33{
 34	struct clk_pll *pll = to_clk_pll(hw);
 35
 36	writel_relaxed(1 << pll->power, pll->base + SET);
 37
 38	udelay(10);
 39
 40	return 0;
 41}
 42
 43static void clk_pll_unprepare(struct clk_hw *hw)
 44{
 45	struct clk_pll *pll = to_clk_pll(hw);
 46
 47	writel_relaxed(1 << pll->power, pll->base + CLR);
 48}
 49
 50static int clk_pll_enable(struct clk_hw *hw)
 51{
 52	struct clk_pll *pll = to_clk_pll(hw);
 53
 54	writel_relaxed(1 << 31, pll->base + CLR);
 55
 56	return 0;
 57}
 58
 59static void clk_pll_disable(struct clk_hw *hw)
 60{
 61	struct clk_pll *pll = to_clk_pll(hw);
 62
 63	writel_relaxed(1 << 31, pll->base + SET);
 64}
 65
 66static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
 67					 unsigned long parent_rate)
 68{
 69	struct clk_pll *pll = to_clk_pll(hw);
 70
 71	return pll->rate;
 72}
 73
 74static const struct clk_ops clk_pll_ops = {
 75	.prepare = clk_pll_prepare,
 76	.unprepare = clk_pll_unprepare,
 77	.enable = clk_pll_enable,
 78	.disable = clk_pll_disable,
 79	.recalc_rate = clk_pll_recalc_rate,
 80};
 81
 82struct clk *mxs_clk_pll(const char *name, const char *parent_name,
 83			void __iomem *base, u8 power, unsigned long rate)
 84{
 85	struct clk_pll *pll;
 86	struct clk *clk;
 87	struct clk_init_data init;
 88
 89	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
 90	if (!pll)
 91		return ERR_PTR(-ENOMEM);
 92
 93	init.name = name;
 94	init.ops = &clk_pll_ops;
 95	init.flags = 0;
 96	init.parent_names = (parent_name ? &parent_name: NULL);
 97	init.num_parents = (parent_name ? 1 : 0);
 98
 99	pll->base = base;
100	pll->rate = rate;
101	pll->power = power;
102	pll->hw.init = &init;
103
104	clk = clk_register(NULL, &pll->hw);
105	if (IS_ERR(clk))
106		kfree(pll);
107
108	return clk;
109}