1*28c06333SKamlesh Gurudasani /* 2*28c06333SKamlesh Gurudasani * Copyright (c) 2025-2026 Texas Instruments Incorporated - https://www.ti.com 3*28c06333SKamlesh Gurudasani * 4*28c06333SKamlesh Gurudasani * SPDX-License-Identifier: BSD-3-Clause 5*28c06333SKamlesh Gurudasani */ 6*28c06333SKamlesh Gurudasani 7*28c06333SKamlesh Gurudasani /* 8*28c06333SKamlesh Gurudasani * TI Generic PLL API Header 9*28c06333SKamlesh Gurudasani * 10*28c06333SKamlesh Gurudasani * This header defines the common PLL data structures and interfaces shared 11*28c06333SKamlesh Gurudasani * across different PLL variants. It provides PLL table entries, PLL data 12*28c06333SKamlesh Gurudasani * structures for configuration parameters (VCO ranges, dividers, multipliers), 13*28c06333SKamlesh Gurudasani * and the common PLL frequency calculation functions. 14*28c06333SKamlesh Gurudasani */ 15*28c06333SKamlesh Gurudasani 16*28c06333SKamlesh Gurudasani #ifndef TI_CLK_PLL_H 17*28c06333SKamlesh Gurudasani #define TI_CLK_PLL_H 18*28c06333SKamlesh Gurudasani 19*28c06333SKamlesh Gurudasani #include <ti_clk.h> 20*28c06333SKamlesh Gurudasani #include <ti_devgrps.h> 21*28c06333SKamlesh Gurudasani 22*28c06333SKamlesh Gurudasani /* 23*28c06333SKamlesh Gurudasani * PLL table entry 24*28c06333SKamlesh Gurudasani * 25*28c06333SKamlesh Gurudasani * This describes a precomputed PLL setting. This should be preferred 26*28c06333SKamlesh Gurudasani * over brute force calculated settings. Additionally, PLL table entries 27*28c06333SKamlesh Gurudasani * can be outside spec'd PLL parameters such as minimum VCO frequency. 28*28c06333SKamlesh Gurudasani * 29*28c06333SKamlesh Gurudasani * Note that the input frequency is not specified but the input frequency 30*28c06333SKamlesh Gurudasani * range can be calculated from the given parameters. 31*28c06333SKamlesh Gurudasani * 32*28c06333SKamlesh Gurudasani * Current data type sizes are chosen based on currently supported PLLs. 33*28c06333SKamlesh Gurudasani * If support for an additional PLL with a larger range is added, then 34*28c06333SKamlesh Gurudasani * the data sizes will either need to increase or be selected at compile 35*28c06333SKamlesh Gurudasani * time. 36*28c06333SKamlesh Gurudasani */ 37*28c06333SKamlesh Gurudasani struct ti_pll_table_entry { 38*28c06333SKamlesh Gurudasani /* Minimum output frequency */ 39*28c06333SKamlesh Gurudasani uint32_t freq_min_hz; 40*28c06333SKamlesh Gurudasani 41*28c06333SKamlesh Gurudasani /* Maximum output frequency */ 42*28c06333SKamlesh Gurudasani uint32_t freq_max_hz; 43*28c06333SKamlesh Gurudasani 44*28c06333SKamlesh Gurudasani /* Multiplier setting */ 45*28c06333SKamlesh Gurudasani uint16_t pllm; 46*28c06333SKamlesh Gurudasani 47*28c06333SKamlesh Gurudasani /* Input divider setting */ 48*28c06333SKamlesh Gurudasani uint8_t plld; 49*28c06333SKamlesh Gurudasani 50*28c06333SKamlesh Gurudasani /* Output divider setting */ 51*28c06333SKamlesh Gurudasani uint8_t clkod; 52*28c06333SKamlesh Gurudasani 53*28c06333SKamlesh Gurudasani /* Fractional multiplier part */ 54*28c06333SKamlesh Gurudasani uint32_t pllfm; 55*28c06333SKamlesh Gurudasani }; 56*28c06333SKamlesh Gurudasani 57*28c06333SKamlesh Gurudasani /* The SoC specific table of precomputed PLL settings */ 58*28c06333SKamlesh Gurudasani extern const struct ti_pll_table_entry ti_soc_pll_table[]; 59*28c06333SKamlesh Gurudasani 60*28c06333SKamlesh Gurudasani /* PLL specific const clock data. */ 61*28c06333SKamlesh Gurudasani struct ti_clk_data_pll { 62*28c06333SKamlesh Gurudasani /* Common const clock data */ 63*28c06333SKamlesh Gurudasani struct ti_clk_drv_data data; 64*28c06333SKamlesh Gurudasani 65*28c06333SKamlesh Gurudasani /* 66*28c06333SKamlesh Gurudasani * Precomputed PLL entries 67*28c06333SKamlesh Gurudasani * 68*28c06333SKamlesh Gurudasani * Points to an array of indexes into the PLL table. NULL if there are no 69*28c06333SKamlesh Gurudasani * entries. 70*28c06333SKamlesh Gurudasani */ 71*28c06333SKamlesh Gurudasani const uint8_t *pll_entries; 72*28c06333SKamlesh Gurudasani 73*28c06333SKamlesh Gurudasani /* 74*28c06333SKamlesh Gurudasani * Number of PLL entries 75*28c06333SKamlesh Gurudasani * 76*28c06333SKamlesh Gurudasani * Number of valid entries in pll_entries array. 77*28c06333SKamlesh Gurudasani */ 78*28c06333SKamlesh Gurudasani size_t pll_entries_count; 79*28c06333SKamlesh Gurudasani 80*28c06333SKamlesh Gurudasani /* 81*28c06333SKamlesh Gurudasani * VCO range. 82*28c06333SKamlesh Gurudasani * 83*28c06333SKamlesh Gurudasani * This points to the valid VCO frequency range in the range table. 84*28c06333SKamlesh Gurudasani */ 85*28c06333SKamlesh Gurudasani uint8_t vco_range_idx; 86*28c06333SKamlesh Gurudasani 87*28c06333SKamlesh Gurudasani /* 88*28c06333SKamlesh Gurudasani * VCO input range. 89*28c06333SKamlesh Gurudasani * 90*28c06333SKamlesh Gurudasani * This points to the valid VCO input frequency range in the range 91*28c06333SKamlesh Gurudasani * table. 92*28c06333SKamlesh Gurudasani */ 93*28c06333SKamlesh Gurudasani uint8_t vco_in_range_idx; 94*28c06333SKamlesh Gurudasani 95*28c06333SKamlesh Gurudasani /* 96*28c06333SKamlesh Gurudasani * Default frequency. 97*28c06333SKamlesh Gurudasani * 98*28c06333SKamlesh Gurudasani * This points to an index in the default frequency table. This 99*28c06333SKamlesh Gurudasani * allows the PLL to be programmed to a specific frequency at boot 100*28c06333SKamlesh Gurudasani * time. A table entry of 0 indicates that the current state of 101*28c06333SKamlesh Gurudasani * the hardware should be used. 102*28c06333SKamlesh Gurudasani */ 103*28c06333SKamlesh Gurudasani uint8_t default_freq_idx; 104*28c06333SKamlesh Gurudasani 105*28c06333SKamlesh Gurudasani /* 106*28c06333SKamlesh Gurudasani * Device Group. 107*28c06333SKamlesh Gurudasani * 108*28c06333SKamlesh Gurudasani * Device group(s) this PLL is contained in or DEVGRP_ALL to 109*28c06333SKamlesh Gurudasani * indicate unspecified. 110*28c06333SKamlesh Gurudasani */ 111*28c06333SKamlesh Gurudasani devgrp_t devgrp; 112*28c06333SKamlesh Gurudasani 113*28c06333SKamlesh Gurudasani /* 114*28c06333SKamlesh Gurudasani * Enable fractional support. 115*28c06333SKamlesh Gurudasani * 116*28c06333SKamlesh Gurudasani * True to enable fractional support if supported by this PLL. If 117*28c06333SKamlesh Gurudasani * this is false, fractional frequencies can still be read, but 118*28c06333SKamlesh Gurudasani * new fractional frequencies cannot be programmed. 119*28c06333SKamlesh Gurudasani */ 120*28c06333SKamlesh Gurudasani bool fractional_support; 121*28c06333SKamlesh Gurudasani }; 122*28c06333SKamlesh Gurudasani 123*28c06333SKamlesh Gurudasani /* Const PLL data for use by the pll_calc function. */ 124*28c06333SKamlesh Gurudasani struct ti_pll_data { 125*28c06333SKamlesh Gurudasani /* Maximum PLL divider. */ 126*28c06333SKamlesh Gurudasani uint32_t plld_max; 127*28c06333SKamlesh Gurudasani 128*28c06333SKamlesh Gurudasani /* Maximum PLL multiplier. */ 129*28c06333SKamlesh Gurudasani uint32_t pllm_max; 130*28c06333SKamlesh Gurudasani 131*28c06333SKamlesh Gurudasani /* Bits of fractional PLL multiplier. */ 132*28c06333SKamlesh Gurudasani uint32_t pllfm_bits; 133*28c06333SKamlesh Gurudasani 134*28c06333SKamlesh Gurudasani /* Maximum PLL post-divider. */ 135*28c06333SKamlesh Gurudasani uint32_t clkod_max; 136*28c06333SKamlesh Gurudasani 137*28c06333SKamlesh Gurudasani /* 138*28c06333SKamlesh Gurudasani * Indicate if a divider is valid. 139*28c06333SKamlesh Gurudasani * 140*28c06333SKamlesh Gurudasani * Some PLLs cannot use all values in their range, such as odd or 141*28c06333SKamlesh Gurudasani * even values. This callback allows the pll_calc function to skip 142*28c06333SKamlesh Gurudasani * over invalid values. 143*28c06333SKamlesh Gurudasani */ 144*28c06333SKamlesh Gurudasani bool (*plld_valid)(struct ti_clk *clkp, uint32_t plld); 145*28c06333SKamlesh Gurudasani 146*28c06333SKamlesh Gurudasani /* 147*28c06333SKamlesh Gurudasani * Indicate if a multiplier is valid. 148*28c06333SKamlesh Gurudasani * 149*28c06333SKamlesh Gurudasani * Some PLLs cannot use all values in their range, such as odd or 150*28c06333SKamlesh Gurudasani * even values. This callback allows the pll_calc function to skip 151*28c06333SKamlesh Gurudasani * over invalid values. 152*28c06333SKamlesh Gurudasani */ 153*28c06333SKamlesh Gurudasani bool (*pllm_valid)(struct ti_clk *clkp, uint32_t pllm, bool is_frac); 154*28c06333SKamlesh Gurudasani 155*28c06333SKamlesh Gurudasani /* 156*28c06333SKamlesh Gurudasani * Stride value for a given pllm. 157*28c06333SKamlesh Gurudasani * 158*28c06333SKamlesh Gurudasani * Some PLLs have additional multipliers enabled to reach certain 159*28c06333SKamlesh Gurudasani * pllm values. Normally, these are handled by treating the values 160*28c06333SKamlesh Gurudasani * in between possible values as invalid. However, when dealing with 161*28c06333SKamlesh Gurudasani * fractional multipliers the pll_calc function must understand that 162*28c06333SKamlesh Gurudasani * the fractional multiplier will also be multiplied by this value. 163*28c06333SKamlesh Gurudasani * 164*28c06333SKamlesh Gurudasani * Provide the extra multiplier value that gets applied at a given 165*28c06333SKamlesh Gurudasani * pllm value. 166*28c06333SKamlesh Gurudasani */ 167*28c06333SKamlesh Gurudasani uint32_t (*pllm_stride)(struct ti_clk *clkp, uint32_t pllm); 168*28c06333SKamlesh Gurudasani 169*28c06333SKamlesh Gurudasani /* 170*28c06333SKamlesh Gurudasani * Indicate if a post-divider is valid. 171*28c06333SKamlesh Gurudasani * 172*28c06333SKamlesh Gurudasani * Some PLLs cannot use all values in their range, such as odd or 173*28c06333SKamlesh Gurudasani * even values. This callback allows the pll_calc function to skip 174*28c06333SKamlesh Gurudasani * over invalid values. 175*28c06333SKamlesh Gurudasani */ 176*28c06333SKamlesh Gurudasani bool (*clkod_valid)(struct ti_clk *clkp, uint32_t clkod); 177*28c06333SKamlesh Gurudasani 178*28c06333SKamlesh Gurudasani /* 179*28c06333SKamlesh Gurudasani * Indicate a bin for this setting combination. 180*28c06333SKamlesh Gurudasani * 181*28c06333SKamlesh Gurudasani * Some PLLs prefer certain combinations or ranges of settings over 182*28c06333SKamlesh Gurudasani * others, such as a multiplier below 512. Binning allows pll_calc 183*28c06333SKamlesh Gurudasani * to act on that preference. This function returns a bin number for 184*28c06333SKamlesh Gurudasani * each pllm/plld/clkod combination passed. pll_calc will always 185*28c06333SKamlesh Gurudasani * prefer a setting with a higher bin value over a lower bin value. 186*28c06333SKamlesh Gurudasani */ 187*28c06333SKamlesh Gurudasani int32_t (*bin)(struct ti_clk *clkp, uint32_t plld, uint32_t pllm, 188*28c06333SKamlesh Gurudasani bool is_frac, uint32_t clkod); 189*28c06333SKamlesh Gurudasani 190*28c06333SKamlesh Gurudasani /* 191*28c06333SKamlesh Gurudasani * Try to find a larger pllm value that exists in a better bin 192*28c06333SKamlesh Gurudasani * 193*28c06333SKamlesh Gurudasani * The pll calculation code functions by testing every allowable plld 194*28c06333SKamlesh Gurudasani * and clkod combination. For each combination, it tests a pllm value 195*28c06333SKamlesh Gurudasani * that produces a frequency at or below the target, and a pllm value 196*28c06333SKamlesh Gurudasani * that produces a frequency above the target. However, this may skip 197*28c06333SKamlesh Gurudasani * certain plld/pllm/clkod combinations that are in a better bin. 198*28c06333SKamlesh Gurudasani * This function allows the pll driver code to return a larger pllm 199*28c06333SKamlesh Gurudasani * value that is in a better bin than the current pllm value. It 200*28c06333SKamlesh Gurudasani * will be called by the pll calculation code until it returns 0. 201*28c06333SKamlesh Gurudasani * 202*28c06333SKamlesh Gurudasani * Note that the pll calculation function will assume the pllm value 203*28c06333SKamlesh Gurudasani * returned is valid and will not call pllm_valid to test it. 204*28c06333SKamlesh Gurudasani */ 205*28c06333SKamlesh Gurudasani uint32_t (*bin_next_pllm)(struct ti_clk *clkp, uint32_t plld, 206*28c06333SKamlesh Gurudasani uint32_t pllm, uint32_t clkod); 207*28c06333SKamlesh Gurudasani 208*28c06333SKamlesh Gurudasani /* 209*28c06333SKamlesh Gurudasani * Try to find a smaller pllm value that exists in a better bin 210*28c06333SKamlesh Gurudasani * 211*28c06333SKamlesh Gurudasani * The pll calculation code functions by testing every allowable plld 212*28c06333SKamlesh Gurudasani * and clkod combination. For each combination, it tests a pllm value 213*28c06333SKamlesh Gurudasani * that produces a frequency at or below the target, and a pllm value 214*28c06333SKamlesh Gurudasani * that produces a frequency above the target. However, this may skip 215*28c06333SKamlesh Gurudasani * certain plld/pllm/clkod combinations that are in a better bin. 216*28c06333SKamlesh Gurudasani * This function allows the pll driver code to return a smaller pllm 217*28c06333SKamlesh Gurudasani * value that is in a better bin than the current pllm value. It 218*28c06333SKamlesh Gurudasani * will be called by the pll calculation code until it returns 0. 219*28c06333SKamlesh Gurudasani * 220*28c06333SKamlesh Gurudasani * Note that the pll calculation function will assume the pllm value 221*28c06333SKamlesh Gurudasani * returned is valid and will not call pllm_valid to test it. 222*28c06333SKamlesh Gurudasani */ 223*28c06333SKamlesh Gurudasani uint32_t (*bin_prev_pllm)(struct ti_clk *clkp, uint32_t plld, 224*28c06333SKamlesh Gurudasani uint32_t pllm, uint32_t clkod); 225*28c06333SKamlesh Gurudasani 226*28c06333SKamlesh Gurudasani /* 227*28c06333SKamlesh Gurudasani * Return fitness value based on VCO frequency. 228*28c06333SKamlesh Gurudasani * 229*28c06333SKamlesh Gurudasani * While PLLs already have a maximum and minimum allowable VCO 230*28c06333SKamlesh Gurudasani * frequency, many prefer certain VCO frequencies over others. If the 231*28c06333SKamlesh Gurudasani * bin and frequency delta of a given pllm/plld/clkod combination are 232*28c06333SKamlesh Gurudasani * identical, the vco_fitness function is used to pick a preferred 233*28c06333SKamlesh Gurudasani * combination. 234*28c06333SKamlesh Gurudasani */ 235*28c06333SKamlesh Gurudasani uint32_t (*vco_fitness)(struct ti_clk *clkp, uint32_t vco, bool is_frac); 236*28c06333SKamlesh Gurudasani }; 237*28c06333SKamlesh Gurudasani 238*28c06333SKamlesh Gurudasani /** 239*28c06333SKamlesh Gurudasani * ti_pll_calc() - Calculate ideal PLL settings. 240*28c06333SKamlesh Gurudasani * @clk: The PLL to calculate settings for. 241*28c06333SKamlesh Gurudasani * @pll_data: The const parameters of the PLL that give allowable settings and preferences. 242*28c06333SKamlesh Gurudasani * @input: The input frequency in Hz. 243*28c06333SKamlesh Gurudasani * @output: The desired output frequency in Hz. 244*28c06333SKamlesh Gurudasani * @min: The minimum acceptable output frequency in Hz. 245*28c06333SKamlesh Gurudasani * @max: The maximum acceptable output frequency in Hz. 246*28c06333SKamlesh Gurudasani * @plld: Storage for generated divider value. 247*28c06333SKamlesh Gurudasani * @pllm: Storage for generated multiplier value. 248*28c06333SKamlesh Gurudasani * @pllfm: Storage for generated fractional multiplier value. 249*28c06333SKamlesh Gurudasani * @clkod: Storage for generated post-divider value. 250*28c06333SKamlesh Gurudasani * 251*28c06333SKamlesh Gurudasani * This calculates the ideal settings that can be used to generate an output 252*28c06333SKamlesh Gurudasani * frequenccy given an input frequency and PLL properties. It iterates through 253*28c06333SKamlesh Gurudasani * possible divider, multiplier, and post-divider values to find the best 254*28c06333SKamlesh Gurudasani * combination. Preferences are sorted by: 255*28c06333SKamlesh Gurudasani * - bin 256*28c06333SKamlesh Gurudasani * - frequency delta 257*28c06333SKamlesh Gurudasani * - VCO fitness 258*28c06333SKamlesh Gurudasani * Where bin is the bin value returned by the bin callback, frequency delta 259*28c06333SKamlesh Gurudasani * is the difference between the desired frequency and generated frequency, 260*28c06333SKamlesh Gurudasani * and VCO fitness is the fitness value returned by the vco_fitness callback. 261*28c06333SKamlesh Gurudasani * 262*28c06333SKamlesh Gurudasani * Return: Frequency produced with the calculated plld/pllm/clkod 263*28c06333SKamlesh Gurudasani * values. 0 if no combination could produce an output 264*28c06333SKamlesh Gurudasani * between min and max. 265*28c06333SKamlesh Gurudasani */ 266*28c06333SKamlesh Gurudasani uint32_t ti_pll_calc(struct ti_clk *clkp, const struct ti_pll_data *pll_d, 267*28c06333SKamlesh Gurudasani uint32_t input, uint32_t output, uint32_t min, uint32_t max, 268*28c06333SKamlesh Gurudasani uint32_t *plld, uint32_t *pllm, uint32_t *pllfm, 269*28c06333SKamlesh Gurudasani uint32_t *clkod); 270*28c06333SKamlesh Gurudasani 271*28c06333SKamlesh Gurudasani /** 272*28c06333SKamlesh Gurudasani * ti_pll_init() - Base PLL initialization function 273*28c06333SKamlesh Gurudasani * @clk: The PLL to calculate settings for. 274*28c06333SKamlesh Gurudasani * 275*28c06333SKamlesh Gurudasani * This contains the common PLL initialization code. This includes setting 276*28c06333SKamlesh Gurudasani * the default frequency if applicable. 277*28c06333SKamlesh Gurudasani * 278*28c06333SKamlesh Gurudasani * Return: 0 on success, error code on error. 279*28c06333SKamlesh Gurudasani */ 280*28c06333SKamlesh Gurudasani int32_t ti_pll_init(struct ti_clk *clkp); 281*28c06333SKamlesh Gurudasani 282*28c06333SKamlesh Gurudasani #endif /* TI_CLK_PLL_H */ 283