80 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Copyright (C) 2018-2019 SiFive, Inc.4 * Wesley Terpstra5 * Paul Walmsley6 */7 8#ifndef __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H9#define __LINUX_CLK_ANALOGBITS_WRPLL_CLN28HPC_H10 11#include <linux/types.h>12 13/* DIVQ_VALUES: number of valid DIVQ values */14#define DIVQ_VALUES 615 16/*17 * Bit definitions for struct wrpll_cfg.flags18 *19 * WRPLL_FLAGS_BYPASS_FLAG: if set, the PLL is either in bypass, or should be20 * programmed to enter bypass21 * WRPLL_FLAGS_RESET_FLAG: if set, the PLL is in reset22 * WRPLL_FLAGS_INT_FEEDBACK_FLAG: if set, the PLL is configured for internal23 * feedback mode24 * WRPLL_FLAGS_EXT_FEEDBACK_FLAG: if set, the PLL is configured for external25 * feedback mode (not yet supported by this driver)26 */27#define WRPLL_FLAGS_BYPASS_SHIFT 028#define WRPLL_FLAGS_BYPASS_MASK BIT(WRPLL_FLAGS_BYPASS_SHIFT)29#define WRPLL_FLAGS_RESET_SHIFT 130#define WRPLL_FLAGS_RESET_MASK BIT(WRPLL_FLAGS_RESET_SHIFT)31#define WRPLL_FLAGS_INT_FEEDBACK_SHIFT 232#define WRPLL_FLAGS_INT_FEEDBACK_MASK BIT(WRPLL_FLAGS_INT_FEEDBACK_SHIFT)33#define WRPLL_FLAGS_EXT_FEEDBACK_SHIFT 334#define WRPLL_FLAGS_EXT_FEEDBACK_MASK BIT(WRPLL_FLAGS_EXT_FEEDBACK_SHIFT)35 36/**37 * struct wrpll_cfg - WRPLL configuration values38 * @divr: reference divider value (6 bits), as presented to the PLL signals39 * @divf: feedback divider value (9 bits), as presented to the PLL signals40 * @divq: output divider value (3 bits), as presented to the PLL signals41 * @flags: PLL configuration flags. See above for more information42 * @range: PLL loop filter range. See below for more information43 * @output_rate_cache: cached output rates, swept across DIVQ44 * @parent_rate: PLL refclk rate for which values are valid45 * @max_r: maximum possible R divider value, given @parent_rate46 * @init_r: initial R divider value to start the search from47 *48 * @divr, @divq, @divq, @range represent what the PLL expects to see49 * on its input signals. Thus @divr and @divf are the actual divisors50 * 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, the54 * record should be zero-initialized with the exception of the @flags55 * field. The only flag bits that need to be set are either56 * WRPLL_FLAGS_INT_FEEDBACK or WRPLL_FLAGS_EXT_FEEDBACK.57 */58struct 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 71int wrpll_configure_for_rate(struct wrpll_cfg *c, u32 target_rate,72 unsigned long parent_rate);73 74unsigned int wrpll_calc_max_lock_us(const struct wrpll_cfg *c);75 76unsigned 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