brintos

brintos / linux-shallow public Read only

0
0
Text · 2.2 KiB · 431cf6f Raw
110 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*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 clock15 * @hw: clk_hw for the pll16 * @base: base address of the pll17 * @power: the shift of power bit18 * @rate: the clock rate of the pll19 *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}110