Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright (C) 2018-2019 SiFive, Inc.
0004  * Wesley Terpstra
0005  * Paul Walmsley
0006  */
0007 
0008 #ifndef __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H
0009 #define __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H
0010 
0011 #include <linux/types.h>
0012 
0013 /* DIVQ_VALUES: number of valid DIVQ values */
0014 #define DIVQ_VALUES             6
0015 
0016 /*
0017  * Bit definitions for struct wrpll_cfg.flags
0018  *
0019  * WRPLL_FLAGS_BYPASS_FLAG: if set, the PLL is either in bypass, or should be
0020  *  programmed to enter bypass
0021  * WRPLL_FLAGS_RESET_FLAG: if set, the PLL is in reset
0022  * WRPLL_FLAGS_INT_FEEDBACK_FLAG: if set, the PLL is configured for internal
0023  *  feedback mode
0024  * WRPLL_FLAGS_EXT_FEEDBACK_FLAG: if set, the PLL is configured for external
0025  *  feedback mode (not yet supported by this driver)
0026  */
0027 #define WRPLL_FLAGS_BYPASS_SHIFT        0
0028 #define WRPLL_FLAGS_BYPASS_MASK     BIT(WRPLL_FLAGS_BYPASS_SHIFT)
0029 #define WRPLL_FLAGS_RESET_SHIFT     1
0030 #define WRPLL_FLAGS_RESET_MASK      BIT(WRPLL_FLAGS_RESET_SHIFT)
0031 #define WRPLL_FLAGS_INT_FEEDBACK_SHIFT  2
0032 #define WRPLL_FLAGS_INT_FEEDBACK_MASK   BIT(WRPLL_FLAGS_INT_FEEDBACK_SHIFT)
0033 #define WRPLL_FLAGS_EXT_FEEDBACK_SHIFT  3
0034 #define WRPLL_FLAGS_EXT_FEEDBACK_MASK   BIT(WRPLL_FLAGS_EXT_FEEDBACK_SHIFT)
0035 
0036 /**
0037  * struct wrpll_cfg - WRPLL configuration values
0038  * @divr: reference divider value (6 bits), as presented to the PLL signals
0039  * @divf: feedback divider value (9 bits), as presented to the PLL signals
0040  * @divq: output divider value (3 bits), as presented to the PLL signals
0041  * @flags: PLL configuration flags.  See above for more information
0042  * @range: PLL loop filter range.  See below for more information
0043  * @output_rate_cache: cached output rates, swept across DIVQ
0044  * @parent_rate: PLL refclk rate for which values are valid
0045  * @max_r: maximum possible R divider value, given @parent_rate
0046  * @init_r: initial R divider value to start the search from
0047  *
0048  * @divr, @divq, @divq, @range represent what the PLL expects to see
0049  * on its input signals.  Thus @divr and @divf are the actual divisors
0050  * minus one.  @divq is a power-of-two divider; for example, 1 =
0051  * divide-by-2 and 6 = divide-by-64.  0 is an invalid @divq value.
0052  *
0053  * When initially passing a struct wrpll_cfg record, the
0054  * record should be zero-initialized with the exception of the @flags
0055  * field.  The only flag bits that need to be set are either
0056  * WRPLL_FLAGS_INT_FEEDBACK or WRPLL_FLAGS_EXT_FEEDBACK.
0057  */
0058 struct wrpll_cfg {
0059     u8 divr;
0060     u8 divq;
0061     u8 range;
0062     u8 flags;
0063     u16 divf;
0064 /* private: */
0065     u32 output_rate_cache[DIVQ_VALUES];
0066     unsigned long parent_rate;
0067     u8 max_r;
0068     u8 init_r;
0069 };
0070 
0071 int wrpll_configure_for_rate(struct wrpll_cfg *c, u32 target_rate,
0072                  unsigned long parent_rate);
0073 
0074 unsigned int wrpll_calc_max_lock_us(const struct wrpll_cfg *c);
0075 
0076 unsigned long wrpll_calc_output_rate(const struct wrpll_cfg *c,
0077                      unsigned long parent_rate);
0078 
0079 #endif /* __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H */