linux/drivers/clk/baikal-t1/ccu-pll.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
 *
 * Authors:
 *   Serge Semin <[email protected]>
 *   Dmitry Dunaev <[email protected]>
 *
 * Baikal-T1 CCU PLL interface driver
 */

#define pr_fmt(fmt)

#include <linux/kernel.h>
#include <linux/printk.h>
#include <linux/limits.h>
#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/slab.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/spinlock.h>
#include <linux/regmap.h>
#include <linux/iopoll.h>
#include <linux/time64.h>
#include <linux/rational.h>
#include <linux/debugfs.h>

#include "ccu-pll.h"

#define CCU_PLL_CTL
#define CCU_PLL_CTL_EN
#define CCU_PLL_CTL_RST
#define CCU_PLL_CTL_CLKR_FLD
#define CCU_PLL_CTL_CLKR_MASK
#define CCU_PLL_CTL_CLKF_FLD
#define CCU_PLL_CTL_CLKF_MASK
#define CCU_PLL_CTL_CLKOD_FLD
#define CCU_PLL_CTL_CLKOD_MASK
#define CCU_PLL_CTL_BYPASS
#define CCU_PLL_CTL_LOCK
#define CCU_PLL_CTL1
#define CCU_PLL_CTL1_BWADJ_FLD
#define CCU_PLL_CTL1_BWADJ_MASK

#define CCU_PLL_LOCK_CHECK_RETRIES

#define CCU_PLL_NR_MAX
#define CCU_PLL_NF_MAX
#define CCU_PLL_OD_MAX
#define CCU_PLL_NB_MAX
#define CCU_PLL_FDIV_MIN
#define CCU_PLL_FDIV_MAX
#define CCU_PLL_FOUT_MIN
#define CCU_PLL_FOUT_MAX
#define CCU_PLL_FVCO_MIN
#define CCU_PLL_FVCO_MAX
#define CCU_PLL_CLKOD_FACTOR

static inline unsigned long ccu_pll_lock_delay_us(unsigned long ref_clk,
						  unsigned long nr)
{}

static inline unsigned long ccu_pll_calc_freq(unsigned long ref_clk,
					      unsigned long nr,
					      unsigned long nf,
					      unsigned long od)
{}

static int ccu_pll_reset(struct ccu_pll *pll, unsigned long ref_clk,
			 unsigned long nr)
{}

static int ccu_pll_enable(struct clk_hw *hw)
{}

static void ccu_pll_disable(struct clk_hw *hw)
{}

static int ccu_pll_is_enabled(struct clk_hw *hw)
{}

static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
					 unsigned long parent_rate)
{}

static void ccu_pll_calc_factors(unsigned long rate, unsigned long parent_rate,
				 unsigned long *nr, unsigned long *nf,
				 unsigned long *od)
{}

static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate,
			       unsigned long *parent_rate)
{}

/*
 * This method is used for PLLs, which support the on-the-fly dividers
 * adjustment. So there is no need in gating such clocks.
 */
static int ccu_pll_set_rate_reset(struct clk_hw *hw, unsigned long rate,
				  unsigned long parent_rate)
{}

/*
 * This method is used for PLLs, which don't support the on-the-fly dividers
 * adjustment. So the corresponding clocks are supposed to be gated first.
 */
static int ccu_pll_set_rate_norst(struct clk_hw *hw, unsigned long rate,
				  unsigned long parent_rate)
{}

#ifdef CONFIG_DEBUG_FS

struct ccu_pll_dbgfs_bit {};

struct ccu_pll_dbgfs_fld {};

#define CCU_PLL_DBGFS_BIT_ATTR(_name, _reg, _mask)

#define CCU_PLL_DBGFS_FLD_ATTR(_name, _reg, _lsb, _mask, _min, _max)

static const struct ccu_pll_dbgfs_bit ccu_pll_bits[] =;

#define CCU_PLL_DBGFS_BIT_NUM

static const struct ccu_pll_dbgfs_fld ccu_pll_flds[] =;

#define CCU_PLL_DBGFS_FLD_NUM

/*
 * It can be dangerous to change the PLL settings behind clock framework back,
 * therefore we don't provide any kernel config based compile time option for
 * this feature to enable.
 */
#undef CCU_PLL_ALLOW_WRITE_DEBUGFS
#ifdef CCU_PLL_ALLOW_WRITE_DEBUGFS

static int ccu_pll_dbgfs_bit_set(void *priv, u64 val)
{
	const struct ccu_pll_dbgfs_bit *bit = priv;
	struct ccu_pll *pll = bit->pll;
	unsigned long flags;

	spin_lock_irqsave(&pll->lock, flags);
	regmap_update_bits(pll->sys_regs, pll->reg_ctl + bit->reg,
			   bit->mask, val ? bit->mask : 0);
	spin_unlock_irqrestore(&pll->lock, flags);

	return 0;
}

static int ccu_pll_dbgfs_fld_set(void *priv, u64 val)
{
	struct ccu_pll_dbgfs_fld *fld = priv;
	struct ccu_pll *pll = fld->pll;
	unsigned long flags;
	u32 data;

	val = clamp_t(u64, val, fld->min, fld->max);
	data = ((val - 1) << fld->lsb) & fld->mask;

	spin_lock_irqsave(&pll->lock, flags);
	regmap_update_bits(pll->sys_regs, pll->reg_ctl + fld->reg, fld->mask,
			   data);
	spin_unlock_irqrestore(&pll->lock, flags);

	return 0;
}

#define ccu_pll_dbgfs_mode

#else /* !CCU_PLL_ALLOW_WRITE_DEBUGFS */

#define ccu_pll_dbgfs_bit_set
#define ccu_pll_dbgfs_fld_set
#define ccu_pll_dbgfs_mode

#endif /* !CCU_PLL_ALLOW_WRITE_DEBUGFS */

static int ccu_pll_dbgfs_bit_get(void *priv, u64 *val)
{}
DEFINE_DEBUGFS_ATTRIBUTE();

static int ccu_pll_dbgfs_fld_get(void *priv, u64 *val)
{}
DEFINE_DEBUGFS_ATTRIBUTE();

static void ccu_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
{}

#else /* !CONFIG_DEBUG_FS */

#define ccu_pll_debug_init

#endif /* !CONFIG_DEBUG_FS */

static const struct clk_ops ccu_pll_gate_to_set_ops =;

static const struct clk_ops ccu_pll_straight_set_ops =;

struct ccu_pll *ccu_pll_hw_register(const struct ccu_pll_init_data *pll_init)
{}

void ccu_pll_hw_unregister(struct ccu_pll *pll)
{}