Skip to content

Commit

Permalink
clk: sprd: add composite clock support
Browse files Browse the repository at this point in the history
This patch introduced composite driver for Spreadtrum's SoCs. The
functions of this composite clock simply consist of divider and
mux clocks.

Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
  • Loading branch information
Chunyan Zhang authored and Stephen Boyd committed Dec 21, 2017
1 parent e3f05d3 commit 4fcba55
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/clk/sprd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ clk-sprd-y += common.o
clk-sprd-y += gate.o
clk-sprd-y += mux.o
clk-sprd-y += div.o
clk-sprd-y += composite.o
60 changes: 60 additions & 0 deletions drivers/clk/sprd/composite.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum composite clock driver
//
// Copyright (C) 2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>

#include <linux/clk-provider.h>

#include "composite.h"

static long sprd_comp_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
struct sprd_comp *cc = hw_to_sprd_comp(hw);

return sprd_div_helper_round_rate(&cc->common, &cc->div,
rate, parent_rate);
}

static unsigned long sprd_comp_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct sprd_comp *cc = hw_to_sprd_comp(hw);

return sprd_div_helper_recalc_rate(&cc->common, &cc->div, parent_rate);
}

static int sprd_comp_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct sprd_comp *cc = hw_to_sprd_comp(hw);

return sprd_div_helper_set_rate(&cc->common, &cc->div,
rate, parent_rate);
}

static u8 sprd_comp_get_parent(struct clk_hw *hw)
{
struct sprd_comp *cc = hw_to_sprd_comp(hw);

return sprd_mux_helper_get_parent(&cc->common, &cc->mux);
}

static int sprd_comp_set_parent(struct clk_hw *hw, u8 index)
{
struct sprd_comp *cc = hw_to_sprd_comp(hw);

return sprd_mux_helper_set_parent(&cc->common, &cc->mux, index);
}

const struct clk_ops sprd_comp_ops = {
.get_parent = sprd_comp_get_parent,
.set_parent = sprd_comp_set_parent,

.round_rate = sprd_comp_round_rate,
.recalc_rate = sprd_comp_recalc_rate,
.set_rate = sprd_comp_set_rate,
};
EXPORT_SYMBOL_GPL(sprd_comp_ops);
51 changes: 51 additions & 0 deletions drivers/clk/sprd/composite.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum composite clock driver
//
// Copyright (C) 2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>

#ifndef _SPRD_COMPOSITE_H_
#define _SPRD_COMPOSITE_H_

#include "common.h"
#include "mux.h"
#include "div.h"

struct sprd_comp {
struct sprd_mux_ssel mux;
struct sprd_div_internal div;
struct sprd_clk_common common;
};

#define SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, _table, \
_mshift, _mwidth, _dshift, _dwidth, _flags) \
struct sprd_comp _struct = { \
.mux = _SPRD_MUX_CLK(_mshift, _mwidth, _table), \
.div = _SPRD_DIV_CLK(_dshift, _dwidth), \
.common = { \
.regmap = NULL, \
.reg = _reg, \
.hw.init = CLK_HW_INIT_PARENTS(_name, \
_parent, \
&sprd_comp_ops, \
_flags), \
} \
}

#define SPRD_COMP_CLK(_struct, _name, _parent, _reg, _mshift, \
_mwidth, _dshift, _dwidth, _flags) \
SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, \
NULL, _mshift, _mwidth, \
_dshift, _dwidth, _flags)

static inline struct sprd_comp *hw_to_sprd_comp(const struct clk_hw *hw)
{
struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);

return container_of(common, struct sprd_comp, common);
}

extern const struct clk_ops sprd_comp_ops;

#endif /* _SPRD_COMPOSITE_H_ */

0 comments on commit 4fcba55

Please sign in to comment.