linux/drivers/clk/clk-versaclock7.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Common clock framework driver for the Versaclock7 family of timing devices.
 *
 * Copyright (c) 2022 Renesas Electronics Corporation
 */

#define pr_fmt(fmt)

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/i2c.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/swab.h>

/*
 * 16-bit register address: the lower 8 bits of the register address come
 * from the offset addr byte and the upper 8 bits come from the page register.
 */
#define VC7_PAGE_ADDR
#define VC7_PAGE_WINDOW
#define VC7_MAX_REG

/* Maximum number of banks supported by VC7 */
#define VC7_NUM_BANKS

/* Maximum number of FODs supported by VC7 */
#define VC7_NUM_FOD

/* Maximum number of IODs supported by VC7 */
#define VC7_NUM_IOD

/* Maximum number of outputs supported by VC7 */
#define VC7_NUM_OUT

/* VCO valid range is 9.5 GHz to 10.7 GHz */
#define VC7_APLL_VCO_MIN
#define VC7_APLL_VCO_MAX

/* APLL denominator is fixed at 2^27 */
#define VC7_APLL_DENOMINATOR_BITS

/* FOD 1st stage denominator is fixed 2^34 */
#define VC7_FOD_DENOMINATOR_BITS

/* IOD can operate between 1kHz and 650MHz */
#define VC7_IOD_RATE_MIN
#define VC7_IOD_RATE_MAX
#define VC7_IOD_MIN_DIVISOR
#define VC7_IOD_MAX_DIVISOR

#define VC7_FOD_RATE_MIN
#define VC7_FOD_RATE_MAX
#define VC7_FOD_1ST_STAGE_RATE_MIN
#define VC7_FOD_1ST_STAGE_RATE_MAX
#define VC7_FOD_1ST_INT_MAX
#define VC7_FOD_2ND_INT_MIN
#define VC7_FOD_2ND_INT_MAX

/* VC7 Registers */

#define VC7_REG_XO_CNFG
#define VC7_REG_XO_CNFG_COUNT
#define VC7_REG_XO_IB_H_DIV_SHIFT
#define VC7_REG_XO_IB_H_DIV_MASK

#define VC7_REG_APLL_FB_DIV_FRAC
#define VC7_REG_APLL_FB_DIV_FRAC_COUNT
#define VC7_REG_APLL_FB_DIV_FRAC_MASK

#define VC7_REG_APLL_FB_DIV_INT
#define VC7_REG_APLL_FB_DIV_INT_COUNT
#define VC7_REG_APLL_FB_DIV_INT_MASK

#define VC7_REG_APLL_CNFG
#define VC7_REG_APLL_EN_DOUBLER

#define VC7_REG_OUT_BANK_CNFG(idx)
#define VC7_REG_OUTPUT_BANK_SRC_MASK

#define VC7_REG_FOD_INT_CNFG(idx)
#define VC7_REG_FOD_INT_CNFG_COUNT
#define VC7_REG_FOD_1ST_INT_MASK
#define VC7_REG_FOD_2ND_INT_SHIFT
#define VC7_REG_FOD_2ND_INT_MASK
#define VC7_REG_FOD_FRAC_SHIFT
#define VC7_REG_FOD_FRAC_MASK

#define VC7_REG_IOD_INT_CNFG(idx)
#define VC7_REG_IOD_INT_CNFG_COUNT
#define VC7_REG_IOD_INT_MASK

#define VC7_REG_ODRV_EN(idx)
#define VC7_REG_OUT_DIS

struct vc7_driver_data;
static const struct regmap_config vc7_regmap_config;

/* Supported Renesas VC7 models */
enum vc7_model {};

struct vc7_chip_info {};

/*
 * Changing the APLL frequency is currently not supported.
 * The APLL will consist of an opaque block between the XO and FOD/IODs and
 * its frequency will be computed based on the current state of the device.
 */
struct vc7_apll_data {};

struct vc7_fod_data {};

struct vc7_iod_data {};

struct vc7_out_data {};

struct vc7_driver_data {};

struct vc7_bank_src_map {};

static struct clk_hw *vc7_of_clk_get(struct of_phandle_args *clkspec,
				     void *data)
{}

static const unsigned int RC21008A_index_to_output_mapping[] =;

static int vc7_map_index_to_output(const enum vc7_model model, const unsigned int i)
{}

/* bank to output mapping, same across all variants */
static const unsigned int output_bank_mapping[] =;

/**
 * vc7_64_mul_64_to_128() - Multiply two u64 and return an unsigned 128-bit integer
 * as an upper and lower part.
 *
 * @left: The left argument.
 * @right: The right argument.
 * @hi: The upper 64-bits of the 128-bit product.
 * @lo: The lower 64-bits of the 128-bit product.
 *
 * From mul_64_64 in crypto/ecc.c:350 in the linux kernel, accessed in v5.17.2.
 */
static void vc7_64_mul_64_to_128(u64 left, u64 right, u64 *hi, u64 *lo)
{}

/**
 * vc7_128_div_64_to_64() - Divides a 128-bit uint by a 64-bit divisor, return a 64-bit quotient.
 *
 * @numhi: The uppper 64-bits of the dividend.
 * @numlo: The lower 64-bits of the dividend.
 * @den: The denominator (divisor).
 * @r: The remainder, pass NULL if the remainder is not needed.
 *
 * Originally from libdivide, modified to use kernel u64/u32 types.
 *
 * See https://github.com/ridiculousfish/libdivide/blob/master/libdivide.h#L471.
 *
 * Return: The 64-bit quotient of the division.
 *
 * In case of overflow of division by zero, max(u64) is returned.
 */
static u64 vc7_128_div_64_to_64(u64 numhi, u64 numlo, u64 den, u64 *r)
{}

static int vc7_get_bank_clk(struct vc7_driver_data *vc7,
			    unsigned int bank_idx,
			    unsigned int output_bank_src,
			    struct vc7_bank_src_map *map)
{}

static int vc7_read_apll(struct vc7_driver_data *vc7)
{}

static int vc7_read_fod(struct vc7_driver_data *vc7, unsigned int idx)
{}

static int vc7_write_fod(struct vc7_driver_data *vc7, unsigned int idx)
{}

static int vc7_read_iod(struct vc7_driver_data *vc7, unsigned int idx)
{}

static int vc7_write_iod(struct vc7_driver_data *vc7, unsigned int idx)
{}

static int vc7_read_output(struct vc7_driver_data *vc7, unsigned int idx)
{}

static int vc7_write_output(struct vc7_driver_data *vc7, unsigned int idx)
{}

static unsigned long vc7_get_apll_rate(struct vc7_driver_data *vc7)
{}

static void vc7_calc_iod_divider(unsigned long rate, unsigned long parent_rate,
				 u32 *divider)
{}

static void vc7_calc_fod_1st_stage(unsigned long rate, unsigned long parent_rate,
				   u32 *div_int, u64 *div_frac)
{}

static unsigned long vc7_calc_fod_1st_stage_rate(unsigned long parent_rate,
						 u32 fod_1st_int, u64 fod_frac)
{}

static unsigned long vc7_calc_fod_2nd_stage_rate(unsigned long parent_rate,
						 u32 fod_1st_int, u32 fod_2nd_int, u64 fod_frac)
{}

static void vc7_calc_fod_divider(unsigned long rate, unsigned long parent_rate,
				 u32 *fod_1st_int, u32 *fod_2nd_int, u64 *fod_frac)
{}

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

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

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

static const struct clk_ops vc7_fod_ops =;

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

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

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

static const struct clk_ops vc7_iod_ops =;

static int vc7_clk_out_prepare(struct clk_hw *hw)
{}

static void vc7_clk_out_unprepare(struct clk_hw *hw)
{}

static int vc7_clk_out_is_enabled(struct clk_hw *hw)
{}

static const struct clk_ops vc7_clk_out_ops =;

static int vc7_probe(struct i2c_client *client)
{}

static void vc7_remove(struct i2c_client *client)
{}

static bool vc7_volatile_reg(struct device *dev, unsigned int reg)
{}

static const struct vc7_chip_info vc7_rc21008a_info =;

static struct regmap_range_cfg vc7_range_cfg[] =;

static const struct regmap_config vc7_regmap_config =;

static const struct i2c_device_id vc7_i2c_id[] =;
MODULE_DEVICE_TABLE(i2c, vc7_i2c_id);

static const struct of_device_id vc7_of_match[] =;
MODULE_DEVICE_TABLE(of, vc7_of_match);

static struct i2c_driver vc7_i2c_driver =;
module_i2c_driver();

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();