1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2018-2019 SiFive, Inc. 4 * Wesley Terpstra 5 * Paul Walmsley 6 */ 7 8 #ifndef __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H 9 #define __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H 10 11 #include <linux/types.h> 12 13 /* DIVQ_VALUES: number of valid DIVQ values */ 14 #define DIVQ_VALUES 6 15 16 /* 17 * Bit definitions for struct wrpll_cfg.flags 18 * 19 * WRPLL_FLAGS_BYPASS_FLAG: if set, the PLL is either in bypass, or should be 20 * programmed to enter bypass 21 * WRPLL_FLAGS_RESET_FLAG: if set, the PLL is in reset 22 * WRPLL_FLAGS_INT_FEEDBACK_FLAG: if set, the PLL is configured for internal 23 * feedback mode 24 * WRPLL_FLAGS_EXT_FEEDBACK_FLAG: if set, the PLL is configured for external 25 * feedback mode (not yet supported by this driver) 26 */ 27 #define WRPLL_FLAGS_BYPASS_SHIFT 0 28 #define WRPLL_FLAGS_BYPASS_MASK BIT(WRPLL_FLAGS_BYPASS_SHIFT) 29 #define WRPLL_FLAGS_RESET_SHIFT 1 30 #define WRPLL_FLAGS_RESET_MASK BIT(WRPLL_FLAGS_RESET_SHIFT) 31 #define WRPLL_FLAGS_INT_FEEDBACK_SHIFT 2 32 #define WRPLL_FLAGS_INT_FEEDBACK_MASK BIT(WRPLL_FLAGS_INT_FEEDBACK_SHIFT) 33 #define WRPLL_FLAGS_EXT_FEEDBACK_SHIFT 3 34 #define WRPLL_FLAGS_EXT_FEEDBACK_MASK BIT(WRPLL_FLAGS_EXT_FEEDBACK_SHIFT) 35 36 /** 37 * struct wrpll_cfg - WRPLL configuration values 38 * @divr: reference divider value (6 bits), as presented to the PLL signals 39 * @divf: feedback divider value (9 bits), as presented to the PLL signals 40 * @divq: output divider value (3 bits), as presented to the PLL signals 41 * @flags: PLL configuration flags. See above for more information 42 * @range: PLL loop filter range. See below for more information 43 * @output_rate_cache: cached output rates, swept across DIVQ 44 * @parent_rate: PLL refclk rate for which values are valid 45 * @max_r: maximum possible R divider value, given @parent_rate 46 * @init_r: initial R divider value to start the search from 47 * 48 * @divr, @divq, @divq, @range represent what the PLL expects to see 49 * on its input signals. Thus @divr and @divf are the actual divisors 50 * minus one. @divq is a power-of-two divider; for example, 1 = 51 * divide-by-2 and 6 = divide-by-64. 0 is an invalid @divq value. 52 * 53 * When initially passing a struct wrpll_cfg record, the 54 * record should be zero-initialized with the exception of the @flags 55 * field. The only flag bits that need to be set are either 56 * WRPLL_FLAGS_INT_FEEDBACK or WRPLL_FLAGS_EXT_FEEDBACK. 57 */ 58 struct wrpll_cfg { 59 u8 divr; 60 u8 divq; 61 u8 range; 62 u8 flags; 63 u16 divf; 64 /* private: */ 65 u32 output_rate_cache[DIVQ_VALUES]; 66 unsigned long parent_rate; 67 u8 max_r; 68 u8 init_r; 69 }; 70 71 int wrpll_configure_for_rate(struct wrpll_cfg *c, u32 target_rate, 72 unsigned long parent_rate); 73 74 unsigned int wrpll_calc_max_lock_us(const struct wrpll_cfg *c); 75 76 unsigned long wrpll_calc_output_rate(const struct wrpll_cfg *c, 77 unsigned long parent_rate); 78 79 #endif /* __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H */ 80