Commit 21170e3b authored by Stephen Boyd's avatar Stephen Boyd

Merge branches 'clk-spreadtrum', 'clk-mvebu-dvfs', 'clk-qoriq', 'clk-imx' and...

Merge branches 'clk-spreadtrum', 'clk-mvebu-dvfs', 'clk-qoriq', 'clk-imx' and 'clk-qcom-ipq8074' into clk-next

* clk-spreadtrum:
  clk: sprd: add clocks support for SC9860
  clk: sprd: Add dt-bindings include file for SC9860
  dt-bindings: Add Spreadtrum clock binding documentation
  clk: sprd: add adjustable pll support
  clk: sprd: add composite clock support
  clk: sprd: add divider clock support
  clk: sprd: add mux clock support
  clk: sprd: add gate clock support
  clk: sprd: Add common infrastructure
  clk: move clock common macros out from vendor directories

* clk-mvebu-dvfs:
  clk: mvebu: armada-37xx-periph: add DVFS support for cpu clocks
  clk: mvebu: armada-37xx-periph: prepare cpu clk to be used with DVFS
  clk: mvebu: armada-37xx-periph: cosmetic changes

* clk-qoriq:
  clk: qoriq: add more divider clocks support

* clk-imx:
  clk: imx51: uart4, uart5 gates only exist on imx50, imx53

* clk-qcom-ipq8074:
  clk: qcom: ipq8074: add misc resets for PCIE and NSS
  dt-bindings: clock: qcom: add misc resets for PCIE and NSS
  clk: qcom: ipq8074: add GP and Crypto clocks
  clk: qcom: ipq8074: add NSS ethernet port clocks
  clk: qcom: ipq8074: add NSS clocks
  clk: qcom: ipq8074: add PCIE, USB and SDCC clocks
  clk: qcom: ipq8074: add remaining PLL’s
  dt-bindings: clock: qcom: add remaining clocks for IPQ8074
  clk: qcom: ipq8074: fix missing GPLL0 divider width
  clk: qcom: add parent map for regmap mux
  clk: qcom: add read-only divider operations
......@@ -78,6 +78,7 @@ second cell is the clock index for the specified type.
2 hwaccel index (n in CLKCGnHWACSR)
3 fman 0 for fm1, 1 for fm2
4 platform pll 0=pll, 1=pll/2, 2=pll/3, 3=pll/4
4=pll/5, 5=pll/6, 6=pll/7, 7=pll/8
5 coreclk must be 0
3. Example
......
Spreadtrum Clock Binding
------------------------
Required properties:
- compatible: should contain the following compatible strings:
- "sprd,sc9860-pmu-gate"
- "sprd,sc9860-pll"
- "sprd,sc9860-ap-clk"
- "sprd,sc9860-aon-prediv"
- "sprd,sc9860-apahb-gate"
- "sprd,sc9860-aon-gate"
- "sprd,sc9860-aonsecure-clk"
- "sprd,sc9860-agcp-gate"
- "sprd,sc9860-gpu-clk"
- "sprd,sc9860-vsp-clk"
- "sprd,sc9860-vsp-gate"
- "sprd,sc9860-cam-clk"
- "sprd,sc9860-cam-gate"
- "sprd,sc9860-disp-clk"
- "sprd,sc9860-disp-gate"
- "sprd,sc9860-apapb-gate"
- #clock-cells: must be 1
- clocks : Should be the input parent clock(s) phandle for the clock, this
property here just simply shows which clock group the clocks'
parents are in, since each clk node would represent many clocks
which are defined in the driver. The detailed dependency
relationship (i.e. how many parents and which are the parents)
are implemented in driver code.
Optional properties:
- reg: Contain the registers base address and length. It must be configured
only if no 'sprd,syscon' under the node.
- sprd,syscon: phandle to the syscon which is in the same address area with
the clock, and so we can get regmap for the clocks from the
syscon device.
Example:
pmu_gate: pmu-gate {
compatible = "sprd,sc9860-pmu-gate";
sprd,syscon = <&pmu_regs>;
clocks = <&ext_26m>;
#clock-cells = <1>;
};
pll: pll {
compatible = "sprd,sc9860-pll";
sprd,syscon = <&ana_regs>;
clocks = <&pmu_gate 0>;
#clock-cells = <1>;
};
ap_clk: clock-controller@20000000 {
compatible = "sprd,sc9860-ap-clk";
reg = <0 0x20000000 0 0x400>;
clocks = <&ext_26m>, <&pll 0>,
<&pmu_gate 0>;
#clock-cells = <1>;
};
......@@ -236,6 +236,7 @@ source "drivers/clk/mvebu/Kconfig"
source "drivers/clk/qcom/Kconfig"
source "drivers/clk/renesas/Kconfig"
source "drivers/clk/samsung/Kconfig"
source "drivers/clk/sprd/Kconfig"
source "drivers/clk/sunxi-ng/Kconfig"
source "drivers/clk/tegra/Kconfig"
source "drivers/clk/ti/Kconfig"
......
......@@ -85,6 +85,7 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
obj-$(CONFIG_ARCH_SIRF) += sirf/
obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
obj-$(CONFIG_PLAT_SPEAR) += spear/
obj-$(CONFIG_ARCH_SPRD) += sprd/
obj-$(CONFIG_ARCH_STI) += st/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_ARCH_SUNXI) += sunxi-ng/
......
......@@ -41,7 +41,7 @@ struct clockgen_pll_div {
};
struct clockgen_pll {
struct clockgen_pll_div div[4];
struct clockgen_pll_div div[8];
};
#define CLKSEL_VALID 1
......@@ -1127,6 +1127,13 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
struct clk *clk;
int ret;
/*
* For platform PLL, there are 8 divider clocks.
* For core PLL, there are 4 divider clocks at most.
*/
if (idx != PLATFORM_PLL && i >= 4)
break;
snprintf(pll->div[i].name, sizeof(pll->div[i].name),
"cg-pll%d-div%d", idx, i + 1);
......
......@@ -257,10 +257,6 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base)
clk[IMX5_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
clk[IMX5_CLK_VPU_GATE] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
clk[IMX5_CLK_VPU_REFERENCE_GATE] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
clk[IMX5_CLK_UART4_IPG_GATE] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
clk[IMX5_CLK_UART4_PER_GATE] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
clk[IMX5_CLK_UART5_IPG_GATE] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
clk[IMX5_CLK_UART5_PER_GATE] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
clk[IMX5_CLK_GPC_DVFS] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24);
clk[IMX5_CLK_SSI_APM] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels));
......@@ -361,6 +357,10 @@ static void __init mx50_clocks_init(struct device_node *np)
clk[IMX5_CLK_USB_PHY1_GATE] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
clk[IMX5_CLK_USB_PHY2_GATE] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
clk[IMX5_CLK_UART4_IPG_GATE] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
clk[IMX5_CLK_UART4_PER_GATE] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
clk[IMX5_CLK_UART5_IPG_GATE] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
clk[IMX5_CLK_UART5_PER_GATE] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
......@@ -562,6 +562,10 @@ static void __init mx53_clocks_init(struct device_node *np)
clk[IMX5_CLK_IEEE1588_PRED] = imx_clk_divider("ieee1588_pred", "ieee1588_sel", MXC_CCM_CSCDR2, 6, 3);
clk[IMX5_CLK_IEEE1588_PODF] = imx_clk_divider("ieee1588_podf", "ieee1588_pred", MXC_CCM_CSCDR2, 0, 6);
clk[IMX5_CLK_IEEE1588_GATE] = imx_clk_gate2("ieee1588_serial_gate", "ieee1588_podf", MXC_CCM_CCGR7, 6);
clk[IMX5_CLK_UART4_IPG_GATE] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
clk[IMX5_CLK_UART4_PER_GATE] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
clk[IMX5_CLK_UART5_IPG_GATE] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
clk[IMX5_CLK_UART5_PER_GATE] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
......
This diff is collapsed.
......@@ -25,16 +25,6 @@ struct freq_tbl {
u16 n;
};
/**
* struct parent_map - map table for PLL source select configuration values
* @src: source PLL
* @cfg: configuration value
*/
struct parent_map {
u8 src;
u8 cfg;
};
/**
* struct mn - M/N:D counter
* @mnctr_en_bit: bit to enable mn counter
......
......@@ -23,6 +23,29 @@ static inline struct clk_regmap_div *to_clk_regmap_div(struct clk_hw *hw)
return container_of(to_clk_regmap(hw), struct clk_regmap_div, clkr);
}
static long div_round_ro_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct clk_regmap_div *divider = to_clk_regmap_div(hw);
struct clk_regmap *clkr = &divider->clkr;
u32 div;
struct clk_hw *hw_parent = clk_hw_get_parent(hw);
regmap_read(clkr->regmap, divider->reg, &div);
div >>= divider->shift;
div &= BIT(divider->width) - 1;
div += 1;
if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
if (!hw_parent)
return -EINVAL;
*prate = clk_hw_round_rate(hw_parent, rate * div);
}
return DIV_ROUND_UP_ULL((u64)*prate, div);
}
static long div_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
......@@ -68,3 +91,9 @@ const struct clk_ops clk_regmap_div_ops = {
.recalc_rate = div_recalc_rate,
};
EXPORT_SYMBOL_GPL(clk_regmap_div_ops);
const struct clk_ops clk_regmap_div_ro_ops = {
.round_rate = div_round_ro_rate,
.recalc_rate = div_recalc_rate,
};
EXPORT_SYMBOL_GPL(clk_regmap_div_ro_ops);
......@@ -25,5 +25,6 @@ struct clk_regmap_div {
};
extern const struct clk_ops clk_regmap_div_ops;
extern const struct clk_ops clk_regmap_div_ro_ops;
#endif
......@@ -35,6 +35,9 @@ static u8 mux_get_parent(struct clk_hw *hw)
val >>= mux->shift;
val &= mask;
if (mux->parent_map)
return qcom_find_src_index(hw, mux->parent_map, val);
return val;
}
......@@ -45,6 +48,9 @@ static int mux_set_parent(struct clk_hw *hw, u8 index)
unsigned int mask = GENMASK(mux->width + mux->shift - 1, mux->shift);
unsigned int val;
if (mux->parent_map)
index = mux->parent_map[index].cfg;
val = index;
val <<= mux->shift;
......
......@@ -16,11 +16,13 @@
#include <linux/clk-provider.h>
#include "clk-regmap.h"
#include "common.h"
struct clk_regmap_mux {
u32 reg;
u32 shift;
u32 width;
const struct parent_map *parent_map;
struct clk_regmap clkr;
};
......
......@@ -20,7 +20,6 @@ struct qcom_reset_map;
struct regmap;
struct freq_tbl;
struct clk_hw;
struct parent_map;
#define PLL_LOCK_COUNT_SHIFT 8
#define PLL_LOCK_COUNT_MASK 0x3f
......@@ -39,6 +38,16 @@ struct qcom_cc_desc {
size_t num_gdscs;
};
/**
* struct parent_map - map table for source select configuration values
* @src: source
* @cfg: configuration value
*/
struct parent_map {
u8 src;
u8 cfg;
};
extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
unsigned long rate);
extern const struct freq_tbl *qcom_find_freq_floor(const struct freq_tbl *f,
......
This diff is collapsed.
config SPRD_COMMON_CLK
tristate "Clock support for Spreadtrum SoCs"
depends on ARCH_SPRD || COMPILE_TEST
default ARCH_SPRD
if SPRD_COMMON_CLK
# SoC Drivers
config SPRD_SC9860_CLK
tristate "Support for the Spreadtrum SC9860 clocks"
depends on (ARM64 && ARCH_SPRD) || COMPILE_TEST
default ARM64 && ARCH_SPRD
endif
obj-$(CONFIG_SPRD_COMMON_CLK) += clk-sprd.o
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
clk-sprd-y += pll.o
## SoC support
obj-$(CONFIG_SPRD_SC9860_CLK) += sc9860-clk.o
// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum clock infrastructure
//
// Copyright (C) 2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/regmap.h>
#include "common.h"
static const struct regmap_config sprdclk_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.max_register = 0xffff,
.fast_io = true,
};
static void sprd_clk_set_regmap(const struct sprd_clk_desc *desc,
struct regmap *regmap)
{
int i;
struct sprd_clk_common *cclk;
for (i = 0; i < desc->num_clk_clks; i++) {
cclk = desc->clk_clks[i];
if (!cclk)
continue;
cclk->regmap = regmap;
}
}
int sprd_clk_regmap_init(struct platform_device *pdev,
const struct sprd_clk_desc *desc)
{
void __iomem *base;
struct device_node *node = pdev->dev.of_node;
struct regmap *regmap;
if (of_find_property(node, "sprd,syscon", NULL)) {
regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon");
if (IS_ERR_OR_NULL(regmap)) {
pr_err("%s: failed to get syscon regmap\n", __func__);
return PTR_ERR(regmap);
}
} else {
base = of_iomap(node, 0);
regmap = devm_regmap_init_mmio(&pdev->dev, base,
&sprdclk_regmap_config);
if (IS_ERR_OR_NULL(regmap)) {
pr_err("failed to init regmap\n");
return PTR_ERR(regmap);
}
}
sprd_clk_set_regmap(desc, regmap);
return 0;
}
EXPORT_SYMBOL_GPL(sprd_clk_regmap_init);
int sprd_clk_probe(struct device *dev, struct clk_hw_onecell_data *clkhw)
{
int i, ret;
struct clk_hw *hw;
for (i = 0; i < clkhw->num; i++) {
hw = clkhw->hws[i];
if (!hw)
continue;
ret = devm_clk_hw_register(dev, hw);
if (ret) {
dev_err(dev, "Couldn't register clock %d - %s\n",
i, hw->init->name);
return ret;
}
}
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clkhw);
if (ret)
dev_err(dev, "Failed to add clock provider\n");
return ret;
}
EXPORT_SYMBOL_GPL(sprd_clk_probe);
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum clock infrastructure
//
// Copyright (C) 2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
#ifndef _SPRD_CLK_COMMON_H_
#define _SPRD_CLK_COMMON_H_
#include <linux/clk-provider.h>
#include <linux/of_platform.h>
#include <linux/regmap.h>
struct device_node;
struct sprd_clk_common {
struct regmap *regmap;
u32 reg;
struct clk_hw hw;
};
struct sprd_clk_desc {
struct sprd_clk_common **clk_clks;
unsigned long num_clk_clks;
struct clk_hw_onecell_data *hw_clks;
};
static inline struct sprd_clk_common *
hw_to_sprd_clk_common(const struct clk_hw *hw)
{
return container_of(hw, struct sprd_clk_common, hw);
}
int sprd_clk_regmap_init(struct platform_device *pdev,
const struct sprd_clk_desc *desc);
int sprd_clk_probe(struct device *dev, struct clk_hw_onecell_data *clkhw);
#endif /* _SPRD_CLK_COMMON_H_ */
// 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);
// 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_ */
// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum divider clock driver
//
// Copyright (C) 2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
#include <linux/clk-provider.h>
#include "div.h"
long sprd_div_helper_round_rate(struct sprd_clk_common *common,
const struct sprd_div_internal *div,
unsigned long rate,
unsigned long *parent_rate)
{
return divider_round_rate(&common->hw, rate, parent_rate,
NULL, div->width, 0);
}
EXPORT_SYMBOL_GPL(sprd_div_helper_round_rate);
static long sprd_div_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
struct sprd_div *cd = hw_to_sprd_div(hw);
return sprd_div_helper_round_rate(&cd->common, &cd->div,
rate, parent_rate);
}
unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
const struct sprd_div_internal *div,
unsigned long parent_rate)
{
unsigned long val;
unsigned int reg;
regmap_read(common->regmap, common->reg, &reg);
val = reg >> div->shift;
val &= (1 << div->width) - 1;
return divider_recalc_rate(&common->hw, parent_rate, val, NULL, 0);
}
EXPORT_SYMBOL_GPL(sprd_div_helper_recalc_rate);
static unsigned long sprd_div_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct sprd_div *cd = hw_to_sprd_div(hw);
return sprd_div_helper_recalc_rate(&cd->common, &cd->div, parent_rate);
}
int sprd_div_helper_set_rate(const struct sprd_clk_common *common,
const struct sprd_div_internal *div,
unsigned long rate,
unsigned long parent_rate)
{
unsigned long val;
unsigned int reg;
val = divider_get_val(rate, parent_rate, NULL,
div->width, 0);
regmap_read(common->regmap, common->reg, &reg);
reg &= ~GENMASK(div->width + div->shift - 1, div->shift);
regmap_write(common->regmap, common->reg,
reg | (val << div->shift));
return 0;
}
EXPORT_SYMBOL_GPL(sprd_div_helper_set_rate);
static int sprd_div_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct sprd_div *cd = hw_to_sprd_div(hw);
return sprd_div_helper_set_rate(&cd->common, &cd->div,
rate, parent_rate);
}
const struct clk_ops sprd_div_ops = {
.recalc_rate = sprd_div_recalc_rate,
.round_rate = sprd_div_round_rate,
.set_rate = sprd_div_set_rate,
};
EXPORT_SYMBOL_GPL(sprd_div_ops);
// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum divider clock driver
//
// Copyright (C) 2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
#ifndef _SPRD_DIV_H_
#define _SPRD_DIV_H_
#include "common.h"
/**
* struct sprd_div_internal - Internal divider description
* @shift: Bit offset of the divider in its register
* @width: Width of the divider field in its register
*
* That structure represents a single divider, and is meant to be
* embedded in other structures representing the various clock
* classes.
*/
struct sprd_div_internal {
u8 shift;
u8 width;
};
#define _SPRD_DIV_CLK(_shift, _width) \
{ \
.shift = _shift, \
.width = _width, \
}
struct sprd_div {
struct sprd_div_internal div;
struct sprd_clk_common common;
};
#define SPRD_DIV_CLK(_struct, _name, _parent, _reg, \
_shift, _width, _flags) \
struct sprd_div _struct = { \
.div = _SPRD_DIV_CLK(_shift, _width), \
.common = { \
.regmap = NULL, \
.reg = _reg, \
.hw.init = CLK_HW_INIT(_name, \
_parent, \
&sprd_div_ops, \
_flags), \
} \
}
static inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw)
{
struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
return container_of(common, struct sprd_div, common);
}
long sprd_div_helper_round_rate(struct sprd_clk_common *common,
const struct sprd_div_internal *div,
unsigned long rate,
unsigned long *parent_rate);
unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
const struct sprd_div_internal *div,
unsigned long parent_rate);
int sprd_div_helper_set_rate(const struct sprd_clk_common *common,
const struct sprd_div_internal *div,
unsigned long rate,
unsigned long parent_rate);
extern const struct clk_ops sprd_div_ops;
#endif /* _SPRD_DIV_H_ */
// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum gate clock driver
//
// Copyright (C) 2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include "gate.h"
static void clk_gate_toggle(const struct sprd_gate *sg, bool en)
{
const struct sprd_clk_common *common = &sg->common;
unsigned int reg;
bool set = sg->flags & CLK_GATE_SET_TO_DISABLE ? true : false;
set ^= en;
regmap_read(common->regmap, common->reg, &reg);
if (set)
reg |= sg->enable_mask;
else
reg &= ~sg->enable_mask;
regmap_write(common->regmap, common->reg, reg);
}
static void clk_sc_gate_toggle(const struct sprd_gate *sg, bool en)
{
const struct sprd_clk_common *common = &sg->common;
bool set = sg->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
unsigned int offset;
set ^= en;
/*
* Each set/clear gate clock has three registers:
* common->reg - base register
* common->reg + offset - set register
* common->reg + 2 * offset - clear register
*/
offset = set ? sg->sc_offset : sg->sc_offset * 2;
regmap_write(common->regmap, common->reg + offset,
sg->enable_mask);
}
static void sprd_gate_disable(struct clk_hw *hw)
{
struct sprd_gate *sg = hw_to_sprd_gate(hw);
clk_gate_toggle(sg, false);
}
static int sprd_gate_enable(struct clk_hw *hw)
{
struct sprd_gate *sg = hw_to_sprd_gate(hw);
clk_gate_toggle(sg, true);
return 0;
}
static void sprd_sc_gate_disable(struct clk_hw *hw)
{
struct sprd_gate *sg = hw_to_sprd_gate(hw);
clk_sc_gate_toggle(sg, false);
}
static int sprd_sc_gate_enable(struct clk_hw *hw)
{
struct sprd_gate *sg = hw_to_sprd_gate(hw);
clk_sc_gate_toggle(sg, true);
return 0;
}
static int sprd_gate_is_enabled(struct clk_hw *hw)
{
struct sprd_gate *sg = hw_to_sprd_gate(hw);
struct sprd_clk_common *common = &sg->common;
unsigned int reg;
regmap_read(common->regmap, common->reg, &reg);
if (sg->flags & CLK_GATE_SET_TO_DISABLE)
reg ^= sg->enable_mask;
reg &= sg->enable_mask;
return reg ? 1 : 0;
}
const struct clk_ops sprd_gate_ops = {
.disable = sprd_gate_disable,
.enable = sprd_gate_enable,
.is_enabled = sprd_gate_is_enabled,
};
EXPORT_SYMBOL_GPL(sprd_gate_ops);
const struct clk_ops sprd_sc_gate_ops = {
.disable = sprd_sc_gate_disable,
.enable = sprd_sc_gate_enable,
.is_enabled = sprd_gate_is_enabled,
};
EXPORT_SYMBOL_GPL(sprd_sc_gate_ops);
// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum gate clock driver
//
// Copyright (C) 2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
#ifndef _SPRD_GATE_H_
#define _SPRD_GATE_H_
#include "common.h"
struct sprd_gate {
u32 enable_mask;
u16 flags;
u16 sc_offset;
struct sprd_clk_common common;
};
#define SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \
_enable_mask, _flags, _gate_flags, _ops) \
struct sprd_gate _struct = { \
.enable_mask = _enable_mask, \
.sc_offset = _sc_offset, \
.flags = _gate_flags, \
.common = { \
.regmap = NULL, \
.reg = _reg, \
.hw.init = CLK_HW_INIT(_name, \
_parent, \
_ops, \
_flags), \
} \
}
#define SPRD_GATE_CLK(_struct, _name, _parent, _reg, \
_enable_mask, _flags, _gate_flags) \
SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, 0, \
_enable_mask, _flags, _gate_flags, \
&sprd_gate_ops)
#define SPRD_SC_GATE_CLK(_struct, _name, _parent, _reg, _sc_offset, \
_enable_mask, _flags, _gate_flags) \
SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \
_enable_mask, _flags, _gate_flags, \
&sprd_sc_gate_ops)
static inline struct sprd_gate *hw_to_sprd_gate(const struct clk_hw *hw)
{
struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
return container_of(common, struct sprd_gate, common);
}
extern const struct clk_ops sprd_gate_ops;
extern const struct clk_ops sprd_sc_gate_ops;
#endif /* _SPRD_GATE_H_ */
// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum multiplexer clock driver
//
// Copyright (C) 2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include "mux.h"
u8 sprd_mux_helper_get_parent(const struct sprd_clk_common *common,
const struct sprd_mux_ssel *mux)
{
unsigned int reg;
u8 parent;
int num_parents;
int i;
regmap_read(common->regmap, common->reg, &reg);
parent = reg >> mux->shift;
parent &= (1 << mux->width) - 1;
if (!mux->table)
return parent;
num_parents = clk_hw_get_num_parents(&common->hw);
for (i = 0; i < num_parents - 1; i++)
if (parent >= mux->table[i] && parent < mux->table[i + 1])
return i;
return num_parents - 1;
}
EXPORT_SYMBOL_GPL(sprd_mux_helper_get_parent);
static u8 sprd_mux_get_parent(struct clk_hw *hw)
{
struct sprd_mux *cm = hw_to_sprd_mux(hw);
return sprd_mux_helper_get_parent(&cm->common, &cm->mux);
}
int sprd_mux_helper_set_parent(const struct sprd_clk_common *common,
const struct sprd_mux_ssel *mux,
u8 index)
{
unsigned int reg;
if (mux->table)
index = mux->table[index];
regmap_read(common->regmap, common->reg, &reg);
reg &= ~GENMASK(mux->width + mux->shift - 1, mux->shift);
regmap_write(common->regmap, common->reg,
reg | (index << mux->shift));
return 0;
}
EXPORT_SYMBOL_GPL(sprd_mux_helper_set_parent);
static int sprd_mux_set_parent(struct clk_hw *hw, u8 index)
{
struct sprd_mux *cm = hw_to_sprd_mux(hw);
return sprd_mux_helper_set_parent(&cm->common, &cm->mux, index);
}
const struct clk_ops sprd_mux_ops = {
.get_parent = sprd_mux_get_parent,
.set_parent = sprd_mux_set_parent,
.determine_rate = __clk_mux_determine_rate,
};
EXPORT_SYMBOL_GPL(sprd_mux_ops);
// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum multiplexer clock driver
//
// Copyright (C) 2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
#ifndef _SPRD_MUX_H_
#define _SPRD_MUX_H_
#include "common.h"
/**
* struct sprd_mux_ssel - Mux clock's source select bits in its register
* @shift: Bit offset of the divider in its register
* @width: Width of the divider field in its register
* @table: For some mux clocks, not all sources are used on some special
* chips, this matches the value of mux clock's register and the
* sources which are used for this mux clock
*/
struct sprd_mux_ssel {
u8 shift;
u8 width;
const u8 *table;
};
struct sprd_mux {
struct sprd_mux_ssel mux;
struct sprd_clk_common common;
};
#define _SPRD_MUX_CLK(_shift, _width, _table) \
{ \
.shift = _shift, \
.width = _width, \
.table = _table, \
}
#define SPRD_MUX_CLK_TABLE(_struct, _name, _parents, _table, \
_reg, _shift, _width, \
_flags) \
struct sprd_mux _struct = { \
.mux = _SPRD_MUX_CLK(_shift, _width, _table), \
.common = { \
.regmap = NULL, \
.reg = _reg, \
.hw.init = CLK_HW_INIT_PARENTS(_name, \
_parents, \
&sprd_mux_ops, \
_flags), \
} \
}
#define SPRD_MUX_CLK(_struct, _name, _parents, _reg, \
_shift, _width, _flags) \
SPRD_MUX_CLK_TABLE(_struct, _name, _parents, NULL, \
_reg, _shift, _width, _flags)
static inline struct sprd_mux *hw_to_sprd_mux(const struct clk_hw *hw)
{
struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
return container_of(common, struct sprd_mux, common);
}
extern const struct clk_ops sprd_mux_ops;
u8 sprd_mux_helper_get_parent(const struct sprd_clk_common *common,
const struct sprd_mux_ssel *mux);
int sprd_mux_helper_set_parent(const struct sprd_clk_common *common,
const struct sprd_mux_ssel *mux,
u8 index);
#endif /* _SPRD_MUX_H_ */
// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum pll clock driver
//
// Copyright (C) 2015~2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include "pll.h"
#define CLK_PLL_1M 1000000
#define CLK_PLL_10M (CLK_PLL_1M * 10)
#define pindex(pll, member) \
(pll->factors[member].shift / (8 * sizeof(pll->regs_num)))
#define pshift(pll, member) \
(pll->factors[member].shift % (8 * sizeof(pll->regs_num)))
#define pwidth(pll, member) \
pll->factors[member].width
#define pmask(pll, member) \
((pwidth(pll, member)) ? \
GENMASK(pwidth(pll, member) + pshift(pll, member) - 1, \
pshift(pll, member)) : 0)
#define pinternal(pll, cfg, member) \
(cfg[pindex(pll, member)] & pmask(pll, member))
#define pinternal_val(pll, cfg, member) \
(pinternal(pll, cfg, member) >> pshift(pll, member))
static inline unsigned int
sprd_pll_read(const struct sprd_pll *pll, u8 index)
{
const struct sprd_clk_common *common = &pll->common;
unsigned int val = 0;
if (WARN_ON(index >= pll->regs_num))
return 0;
regmap_read(common->regmap, common->reg + index * 4, &val);
return val;
}
static inline void
sprd_pll_write(const struct sprd_pll *pll, u8 index,
u32 msk, u32 val)
{
const struct sprd_clk_common *common = &pll->common;
unsigned int offset, reg;
int ret = 0;
if (WARN_ON(index >= pll->regs_num))
return;
offset = common->reg + index * 4;
ret = regmap_read(common->regmap, offset, &reg);
if (!ret)
regmap_write(common->regmap, offset, (reg & ~msk) | val);
}
static unsigned long pll_get_refin(const struct sprd_pll *pll)
{
u32 shift, mask, index, refin_id = 3;
const unsigned long refin[4] = { 2, 4, 13, 26 };
if (pwidth(pll, PLL_REFIN)) {
index = pindex(pll, PLL_REFIN);
shift = pshift(pll, PLL_REFIN);
mask = pmask(pll, PLL_REFIN);
refin_id = (sprd_pll_read(pll, index) & mask) >> shift;
if (refin_id > 3)
refin_id = 3;
}
return refin[refin_id];
}
static u32 pll_get_ibias(u64 rate, const u64 *table)
{
u32 i, num = table[0];
for (i = 1; i < num + 1; i++)
if (rate <= table[i])
break;
return (i == num + 1) ? num : i;
}
static unsigned long _sprd_pll_recalc_rate(const struct sprd_pll *pll,
unsigned long parent_rate)
{
u32 *cfg;
u32 i, mask, regs_num = pll->regs_num;
unsigned long rate, nint, kint = 0;
u64 refin;
u16 k1, k2;
cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL);
if (!cfg)
return -ENOMEM;
for (i = 0; i < regs_num; i++)
cfg[i] = sprd_pll_read(pll, i);
refin = pll_get_refin(pll);
if (pinternal(pll, cfg, PLL_PREDIV))
refin = refin * 2;
if (pwidth(pll, PLL_POSTDIV) &&
((pll->fflag == 1 && pinternal(pll, cfg, PLL_POSTDIV)) ||
(!pll->fflag && !pinternal(pll, cfg, PLL_POSTDIV))))
refin = refin / 2;
if (!pinternal(pll, cfg, PLL_DIV_S)) {
rate = refin * pinternal_val(pll, cfg, PLL_N) * CLK_PLL_10M;
} else {
nint = pinternal_val(pll, cfg, PLL_NINT);
if (pinternal(pll, cfg, PLL_SDM_EN))
kint = pinternal_val(pll, cfg, PLL_KINT);
mask = pmask(pll, PLL_KINT);
k1 = pll->k1;
k2 = pll->k2;
rate = DIV_ROUND_CLOSEST_ULL(refin * kint * k1,
((mask >> __ffs(mask)) + 1)) *
k2 + refin * nint * CLK_PLL_1M;
}
return rate;
}
#define SPRD_PLL_WRITE_CHECK(pll, i, mask, val) \
(((sprd_pll_read(pll, i) & mask) == val) ? 0 : (-EFAULT))
static int _sprd_pll_set_rate(const struct sprd_pll *pll,
unsigned long rate,
unsigned long parent_rate)
{
struct reg_cfg *cfg;
int ret = 0;
u32 mask, shift, width, ibias_val, index;
u32 regs_num = pll->regs_num, i = 0;
unsigned long kint, nint;
u64 tmp, refin, fvco = rate;
cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL);
if (!cfg)
return -ENOMEM;
refin = pll_get_refin(pll);
mask = pmask(pll, PLL_PREDIV);
index = pindex(pll, PLL_PREDIV);
width = pwidth(pll, PLL_PREDIV);
if (width && (sprd_pll_read(pll, index) & mask))
refin = refin * 2;
mask = pmask(pll, PLL_POSTDIV);
index = pindex(pll, PLL_POSTDIV);
width = pwidth(pll, PLL_POSTDIV);
cfg[index].msk = mask;
if (width && ((pll->fflag == 1 && fvco <= pll->fvco) ||
(pll->fflag == 0 && fvco > pll->fvco)))
cfg[index].val |= mask;
if (width && fvco <= pll->fvco)
fvco = fvco * 2;
mask = pmask(pll, PLL_DIV_S);
index = pindex(pll, PLL_DIV_S);
cfg[index].val |= mask;
cfg[index].msk |= mask;
mask = pmask(pll, PLL_SDM_EN);
index = pindex(pll, PLL_SDM_EN);
cfg[index].val |= mask;
cfg[index].msk |= mask;
nint = do_div(fvco, refin * CLK_PLL_1M);
mask = pmask(pll, PLL_NINT);
index = pindex(pll, PLL_NINT);
shift = pshift(pll, PLL_NINT);
cfg[index].val |= (nint << shift) & mask;
cfg[index].msk |= mask;
mask = pmask(pll, PLL_KINT);
index = pindex(pll, PLL_KINT);
width = pwidth(pll, PLL_KINT);
shift = pshift(pll, PLL_KINT);
tmp = fvco - refin * nint * CLK_PLL_1M;
tmp = do_div(tmp, 10000) * ((mask >> shift) + 1);
kint = DIV_ROUND_CLOSEST_ULL(tmp, refin * 100);
cfg[index].val |= (kint << shift) & mask;
cfg[index].msk |= mask;
ibias_val = pll_get_ibias(fvco, pll->itable);
mask = pmask(pll, PLL_IBIAS);
index = pindex(pll, PLL_IBIAS);
shift = pshift(pll, PLL_IBIAS);
cfg[index].val |= ibias_val << shift & mask;
cfg[index].msk |= mask;
for (i = 0; i < regs_num; i++) {
if (cfg[i].msk) {
sprd_pll_write(pll, i, cfg[i].msk, cfg[i].val);
ret |= SPRD_PLL_WRITE_CHECK(pll, i, cfg[i].msk,
cfg[i].val);
}
}
if (!ret)
udelay(pll->udelay);
return ret;
}
static unsigned long sprd_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct sprd_pll *pll = hw_to_sprd_pll(hw);
return _sprd_pll_recalc_rate(pll, parent_rate);
}
static int sprd_pll_set_rate(struct clk_hw *hw,
unsigned long rate,
unsigned long parent_rate)
{
struct sprd_pll *pll = hw_to_sprd_pll(hw);
return _sprd_pll_set_rate(pll, rate, parent_rate);
}
static int sprd_pll_clk_prepare(struct clk_hw *hw)
{
struct sprd_pll *pll = hw_to_sprd_pll(hw);
udelay(pll->udelay);
return 0;
}
static long sprd_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
return rate;
}
const struct clk_ops sprd_pll_ops = {
.prepare = sprd_pll_clk_prepare,
.recalc_rate = sprd_pll_recalc_rate,
.round_rate = sprd_pll_round_rate,
.set_rate = sprd_pll_set_rate,
};
EXPORT_SYMBOL_GPL(sprd_pll_ops);
// SPDX-License-Identifier: GPL-2.0
//
// Spreadtrum pll clock driver
//
// Copyright (C) 2015~2017 Spreadtrum, Inc.
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
#ifndef _SPRD_PLL_H_
#define _SPRD_PLL_H_
#include "common.h"
struct reg_cfg {
u32 val;
u32 msk;
};
struct clk_bit_field {
u8 shift;
u8 width;
};
enum {
PLL_LOCK_DONE,
PLL_DIV_S,
PLL_MOD_EN,
PLL_SDM_EN,
PLL_REFIN,
PLL_IBIAS,
PLL_N,
PLL_NINT,
PLL_KINT,
PLL_PREDIV,
PLL_POSTDIV,
PLL_FACT_MAX
};
/*
* struct sprd_pll - definition of adjustable pll clock
*
* @reg: registers used to set the configuration of pll clock,
* reg[0] shows how many registers this pll clock uses.
* @itable: pll ibias table, itable[0] means how many items this
* table includes
* @udelay delay time after setting rate
* @factors used to calculate the pll clock rate
* @fvco: fvco threshold rate
* @fflag: fvco flag
*/
struct sprd_pll {
u32 regs_num;
const u64 *itable;
const struct clk_bit_field *factors;
u16 udelay;
u16 k1;
u16 k2;
u16 fflag;
u64 fvco;
struct sprd_clk_common common;
};
#define SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \
_regs_num, _itable, _factors, \
_udelay, _k1, _k2, _fflag, _fvco) \
struct sprd_pll _struct = { \
.regs_num = _regs_num, \
.itable = _itable, \
.factors = _factors, \
.udelay = _udelay, \
.k1 = _k1, \
.k2 = _k2, \
.fflag = _fflag, \
.fvco = _fvco, \
.common = { \
.regmap = NULL, \
.reg = _reg, \
.hw.init = CLK_HW_INIT(_name, \
_parent, \
&sprd_pll_ops, \
0), \
}, \
}
#define SPRD_PLL_WITH_ITABLE_K(_struct, _name, _parent, _reg, \
_regs_num, _itable, _factors, \
_udelay, _k1, _k2) \
SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \
_regs_num, _itable, _factors, \
_udelay, _k1, _k2, 0, 0)
#define SPRD_PLL_WITH_ITABLE_1K(_struct, _name, _parent, _reg, \
_regs_num, _itable, _factors, _udelay) \
SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \
_regs_num, _itable, _factors, \
_udelay, 1000, 1000, 0, 0)
static inline struct sprd_pll *hw_to_sprd_pll(struct clk_hw *hw)
{
struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
return container_of(common, struct sprd_pll, common);
}
extern const struct clk_ops sprd_pll_ops;
#endif /* _SPRD_PLL_H_ */
This diff is collapsed.
......@@ -31,35 +31,6 @@
struct device_node;
#define CLK_HW_INIT(_name, _parent, _ops, _flags) \
&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_names = (const char *[]) { _parent }, \
.num_parents = 1, \
.ops = _ops, \
}
#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_names = _parents, \
.num_parents = ARRAY_SIZE(_parents), \
.ops = _ops, \
}
#define CLK_FIXED_FACTOR(_struct, _name, _parent, \
_div, _mult, _flags) \
struct clk_fixed_factor _struct = { \
.div = _div, \
.mult = _mult, \
.hw.init = CLK_HW_INIT(_name, \
_parent, \
&clk_fixed_factor_ops, \
_flags), \
}
struct ccu_common {
void __iomem *base;
u16 reg;
......
......@@ -14,24 +14,6 @@
#define PNAME(x) static const char *x[]
#define CLK_HW_INIT(_name, _parent, _ops, _flags) \
&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_names = (const char *[]) { _parent }, \
.num_parents = 1, \
.ops = _ops, \
}
#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_names = _parents, \
.num_parents = ARRAY_SIZE(_parents), \
.ops = _ops, \
}
struct zx_pll_config {
unsigned long rate;
u32 cfg0;
......
......@@ -58,6 +58,186 @@
#define GCC_QPIC_AHB_CLK 41
#define GCC_QPIC_CLK 42
#define PCNOC_BFDCD_CLK_SRC 43
#define GPLL2_MAIN 44
#define GPLL2 45
#define GPLL4_MAIN 46
#define GPLL4 47
#define GPLL6_MAIN 48
#define GPLL6 49
#define UBI32_PLL_MAIN 50
#define UBI32_PLL 51
#define NSS_CRYPTO_PLL_MAIN 52
#define NSS_CRYPTO_PLL 53
#define PCIE0_AXI_CLK_SRC 54
#define PCIE0_AUX_CLK_SRC 55
#define PCIE0_PIPE_CLK_SRC 56
#define PCIE1_AXI_CLK_SRC 57
#define PCIE1_AUX_CLK_SRC 58
#define PCIE1_PIPE_CLK_SRC 59
#define SDCC1_APPS_CLK_SRC 60
#define SDCC1_ICE_CORE_CLK_SRC 61
#define SDCC2_APPS_CLK_SRC 62
#define USB0_MASTER_CLK_SRC 63
#define USB0_AUX_CLK_SRC 64
#define USB0_MOCK_UTMI_CLK_SRC 65
#define USB0_PIPE_CLK_SRC 66
#define USB1_MASTER_CLK_SRC 67
#define USB1_AUX_CLK_SRC 68
#define USB1_MOCK_UTMI_CLK_SRC 69
#define USB1_PIPE_CLK_SRC 70
#define GCC_XO_CLK_SRC 71
#define SYSTEM_NOC_BFDCD_CLK_SRC 72
#define NSS_CE_CLK_SRC 73
#define NSS_NOC_BFDCD_CLK_SRC 74
#define NSS_CRYPTO_CLK_SRC 75
#define NSS_UBI0_CLK_SRC 76
#define NSS_UBI0_DIV_CLK_SRC 77
#define NSS_UBI1_CLK_SRC 78
#define NSS_UBI1_DIV_CLK_SRC 79
#define UBI_MPT_CLK_SRC 80
#define NSS_IMEM_CLK_SRC 81
#define NSS_PPE_CLK_SRC 82
#define NSS_PORT1_RX_CLK_SRC 83
#define NSS_PORT1_RX_DIV_CLK_SRC 84
#define NSS_PORT1_TX_CLK_SRC 85
#define NSS_PORT1_TX_DIV_CLK_SRC 86
#define NSS_PORT2_RX_CLK_SRC 87
#define NSS_PORT2_RX_DIV_CLK_SRC 88
#define NSS_PORT2_TX_CLK_SRC 89
#define NSS_PORT2_TX_DIV_CLK_SRC 90
#define NSS_PORT3_RX_CLK_SRC 91
#define NSS_PORT3_RX_DIV_CLK_SRC 92
#define NSS_PORT3_TX_CLK_SRC 93
#define NSS_PORT3_TX_DIV_CLK_SRC 94
#define NSS_PORT4_RX_CLK_SRC 95
#define NSS_PORT4_RX_DIV_CLK_SRC 96
#define NSS_PORT4_TX_CLK_SRC 97
#define NSS_PORT4_TX_DIV_CLK_SRC 98
#define NSS_PORT5_RX_CLK_SRC 99
#define NSS_PORT5_RX_DIV_CLK_SRC 100
#define NSS_PORT5_TX_CLK_SRC 101
#define NSS_PORT5_TX_DIV_CLK_SRC 102
#define NSS_PORT6_RX_CLK_SRC 103
#define NSS_PORT6_RX_DIV_CLK_SRC 104
#define NSS_PORT6_TX_CLK_SRC 105
#define NSS_PORT6_TX_DIV_CLK_SRC 106
#define CRYPTO_CLK_SRC 107
#define GP1_CLK_SRC 108
#define GP2_CLK_SRC 109
#define GP3_CLK_SRC 110
#define GCC_PCIE0_AHB_CLK 111
#define GCC_PCIE0_AUX_CLK 112
#define GCC_PCIE0_AXI_M_CLK 113
#define GCC_PCIE0_AXI_S_CLK 114
#define GCC_PCIE0_PIPE_CLK 115
#define GCC_SYS_NOC_PCIE0_AXI_CLK 116
#define GCC_PCIE1_AHB_CLK 117
#define GCC_PCIE1_AUX_CLK 118
#define GCC_PCIE1_AXI_M_CLK 119
#define GCC_PCIE1_AXI_S_CLK 120
#define GCC_PCIE1_PIPE_CLK 121
#define GCC_SYS_NOC_PCIE1_AXI_CLK 122
#define GCC_USB0_AUX_CLK 123
#define GCC_SYS_NOC_USB0_AXI_CLK 124
#define GCC_USB0_MASTER_CLK 125
#define GCC_USB0_MOCK_UTMI_CLK 126
#define GCC_USB0_PHY_CFG_AHB_CLK 127
#define GCC_USB0_PIPE_CLK 128
#define GCC_USB0_SLEEP_CLK 129
#define GCC_USB1_AUX_CLK 130
#define GCC_SYS_NOC_USB1_AXI_CLK 131
#define GCC_USB1_MASTER_CLK 132
#define GCC_USB1_MOCK_UTMI_CLK 133
#define GCC_USB1_PHY_CFG_AHB_CLK 134
#define GCC_USB1_PIPE_CLK 135
#define GCC_USB1_SLEEP_CLK 136
#define GCC_SDCC1_AHB_CLK 137
#define GCC_SDCC1_APPS_CLK 138
#define GCC_SDCC1_ICE_CORE_CLK 139
#define GCC_SDCC2_AHB_CLK 140
#define GCC_SDCC2_APPS_CLK 141
#define GCC_MEM_NOC_NSS_AXI_CLK 142
#define GCC_NSS_CE_APB_CLK 143
#define GCC_NSS_CE_AXI_CLK 144
#define GCC_NSS_CFG_CLK 145
#define GCC_NSS_CRYPTO_CLK 146
#define GCC_NSS_CSR_CLK 147
#define GCC_NSS_EDMA_CFG_CLK 148
#define GCC_NSS_EDMA_CLK 149
#define GCC_NSS_IMEM_CLK 150
#define GCC_NSS_NOC_CLK 151
#define GCC_NSS_PPE_BTQ_CLK 152
#define GCC_NSS_PPE_CFG_CLK 153
#define GCC_NSS_PPE_CLK 154
#define GCC_NSS_PPE_IPE_CLK 155
#define GCC_NSS_PTP_REF_CLK 156
#define GCC_NSSNOC_CE_APB_CLK 157
#define GCC_NSSNOC_CE_AXI_CLK 158
#define GCC_NSSNOC_CRYPTO_CLK 159
#define GCC_NSSNOC_PPE_CFG_CLK 160
#define GCC_NSSNOC_PPE_CLK 161
#define GCC_NSSNOC_QOSGEN_REF_CLK 162
#define GCC_NSSNOC_SNOC_CLK 163
#define GCC_NSSNOC_TIMEOUT_REF_CLK 164
#define GCC_NSSNOC_UBI0_AHB_CLK 165
#define GCC_NSSNOC_UBI1_AHB_CLK 166
#define GCC_UBI0_AHB_CLK 167
#define GCC_UBI0_AXI_CLK 168
#define GCC_UBI0_NC_AXI_CLK 169
#define GCC_UBI0_CORE_CLK 170
#define GCC_UBI0_MPT_CLK 171
#define GCC_UBI1_AHB_CLK 172
#define GCC_UBI1_AXI_CLK 173
#define GCC_UBI1_NC_AXI_CLK 174
#define GCC_UBI1_CORE_CLK 175
#define GCC_UBI1_MPT_CLK 176
#define GCC_CMN_12GPLL_AHB_CLK 177
#define GCC_CMN_12GPLL_SYS_CLK 178
#define GCC_MDIO_AHB_CLK 179
#define GCC_UNIPHY0_AHB_CLK 180
#define GCC_UNIPHY0_SYS_CLK 181
#define GCC_UNIPHY1_AHB_CLK 182
#define GCC_UNIPHY1_SYS_CLK 183
#define GCC_UNIPHY2_AHB_CLK 184
#define GCC_UNIPHY2_SYS_CLK 185
#define GCC_NSS_PORT1_RX_CLK 186
#define GCC_NSS_PORT1_TX_CLK 187
#define GCC_NSS_PORT2_RX_CLK 188
#define GCC_NSS_PORT2_TX_CLK 189
#define GCC_NSS_PORT3_RX_CLK 190
#define GCC_NSS_PORT3_TX_CLK 191
#define GCC_NSS_PORT4_RX_CLK 192
#define GCC_NSS_PORT4_TX_CLK 193
#define GCC_NSS_PORT5_RX_CLK 194
#define GCC_NSS_PORT5_TX_CLK 195
#define GCC_NSS_PORT6_RX_CLK 196
#define GCC_NSS_PORT6_TX_CLK 197
#define GCC_PORT1_MAC_CLK 198
#define GCC_PORT2_MAC_CLK 199
#define GCC_PORT3_MAC_CLK 200
#define GCC_PORT4_MAC_CLK 201
#define GCC_PORT5_MAC_CLK 202
#define GCC_PORT6_MAC_CLK 203
#define GCC_UNIPHY0_PORT1_RX_CLK 204
#define GCC_UNIPHY0_PORT1_TX_CLK 205
#define GCC_UNIPHY0_PORT2_RX_CLK 206
#define GCC_UNIPHY0_PORT2_TX_CLK 207
#define GCC_UNIPHY0_PORT3_RX_CLK 208
#define GCC_UNIPHY0_PORT3_TX_CLK 209
#define GCC_UNIPHY0_PORT4_RX_CLK 210
#define GCC_UNIPHY0_PORT4_TX_CLK 211
#define GCC_UNIPHY0_PORT5_RX_CLK 212
#define GCC_UNIPHY0_PORT5_TX_CLK 213
#define GCC_UNIPHY1_PORT5_RX_CLK 214
#define GCC_UNIPHY1_PORT5_TX_CLK 215
#define GCC_UNIPHY2_PORT6_RX_CLK 216
#define GCC_UNIPHY2_PORT6_TX_CLK 217
#define GCC_CRYPTO_AHB_CLK 218
#define GCC_CRYPTO_AXI_CLK 219
#define GCC_CRYPTO_CLK 220
#define GCC_GP1_CLK 221
#define GCC_GP2_CLK 222
#define GCC_GP3_CLK 223
#define GCC_BLSP1_BCR 0
#define GCC_BLSP1_QUP1_BCR 1
......@@ -148,5 +328,47 @@
#define GCC_APC0_VOLTAGE_DROOP_DETECTOR_BCR 86
#define GCC_APC1_VOLTAGE_DROOP_DETECTOR_BCR 87
#define GCC_SMMU_CATS_BCR 88
#define GCC_UBI0_AXI_ARES 89
#define GCC_UBI0_AHB_ARES 90
#define GCC_UBI0_NC_AXI_ARES 91
#define GCC_UBI0_DBG_ARES 92
#define GCC_UBI0_CORE_CLAMP_ENABLE 93
#define GCC_UBI0_CLKRST_CLAMP_ENABLE 94
#define GCC_UBI1_AXI_ARES 95
#define GCC_UBI1_AHB_ARES 96
#define GCC_UBI1_NC_AXI_ARES 97
#define GCC_UBI1_DBG_ARES 98
#define GCC_UBI1_CORE_CLAMP_ENABLE 99
#define GCC_UBI1_CLKRST_CLAMP_ENABLE 100
#define GCC_NSS_CFG_ARES 101
#define GCC_NSS_IMEM_ARES 102
#define GCC_NSS_NOC_ARES 103
#define GCC_NSS_CRYPTO_ARES 104
#define GCC_NSS_CSR_ARES 105
#define GCC_NSS_CE_APB_ARES 106
#define GCC_NSS_CE_AXI_ARES 107
#define GCC_NSSNOC_CE_APB_ARES 108
#define GCC_NSSNOC_CE_AXI_ARES 109
#define GCC_NSSNOC_UBI0_AHB_ARES 110
#define GCC_NSSNOC_UBI1_AHB_ARES 111
#define GCC_NSSNOC_SNOC_ARES 112
#define GCC_NSSNOC_CRYPTO_ARES 113
#define GCC_NSSNOC_ATB_ARES 114
#define GCC_NSSNOC_QOSGEN_REF_ARES 115
#define GCC_NSSNOC_TIMEOUT_REF_ARES 116
#define GCC_PCIE0_PIPE_ARES 117
#define GCC_PCIE0_SLEEP_ARES 118
#define GCC_PCIE0_CORE_STICKY_ARES 119
#define GCC_PCIE0_AXI_MASTER_ARES 120
#define GCC_PCIE0_AXI_SLAVE_ARES 121
#define GCC_PCIE0_AHB_ARES 122
#define GCC_PCIE0_AXI_MASTER_STICKY_ARES 123
#define GCC_PCIE1_PIPE_ARES 124
#define GCC_PCIE1_SLEEP_ARES 125
#define GCC_PCIE1_CORE_STICKY_ARES 126
#define GCC_PCIE1_AXI_MASTER_ARES 127
#define GCC_PCIE1_AXI_SLAVE_ARES 128
#define GCC_PCIE1_AHB_ARES 129
#define GCC_PCIE1_AXI_MASTER_STICKY_ARES 130
#endif
This diff is collapsed.
......@@ -807,6 +807,44 @@ extern struct of_device_id __clk_of_table;
} \
OF_DECLARE_1(clk, name, compat, name##_of_clk_init_driver)
#define CLK_HW_INIT(_name, _parent, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_names = (const char *[]) { _parent }, \
.num_parents = 1, \
.ops = _ops, \
})
#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_names = _parents, \
.num_parents = ARRAY_SIZE(_parents), \
.ops = _ops, \
})
#define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags) \
(&(struct clk_init_data) { \
.flags = _flags, \
.name = _name, \
.parent_names = NULL, \
.num_parents = 0, \
.ops = _ops, \
})
#define CLK_FIXED_FACTOR(_struct, _name, _parent, \
_div, _mult, _flags) \
struct clk_fixed_factor _struct = { \
.div = _div, \
.mult = _mult, \
.hw.init = CLK_HW_INIT(_name, \
_parent, \
&clk_fixed_factor_ops, \
_flags), \
}
#ifdef CONFIG_OF
int of_clk_add_provider(struct device_node *np,
struct clk *(*clk_src_get)(struct of_phandle_args *args,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment