215 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/* Copyright (C) 2014 Broadcom Corporation */3 4#ifndef _CLK_IPROC_H5#define _CLK_IPROC_H6 7#include <linux/kernel.h>8#include <linux/list.h>9#include <linux/spinlock.h>10#include <linux/slab.h>11#include <linux/device.h>12#include <linux/of.h>13#include <linux/clk-provider.h>14 15#define IPROC_CLK_NAME_LEN 2516#define IPROC_CLK_INVALID_OFFSET 0xffffffff17#define bit_mask(width) ((1 << (width)) - 1)18 19/* clocks that should not be disabled at runtime */20#define IPROC_CLK_AON BIT(0)21 22/* PLL that requires gating through ASIU */23#define IPROC_CLK_PLL_ASIU BIT(1)24 25/* PLL that has fractional part of the NDIV */26#define IPROC_CLK_PLL_HAS_NDIV_FRAC BIT(2)27 28/*29 * Some of the iProc PLL/clocks may have an ASIC bug that requires read back30 * of the same register following the write to flush the write transaction into31 * the intended register32 */33#define IPROC_CLK_NEEDS_READ_BACK BIT(3)34 35/*36 * Some PLLs require the PLL SW override bit to be set before changes can be37 * applied to the PLL38 */39#define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4)40 41/*42 * Some PLLs use a different way to control clock power, via the PWRDWN bit in43 * the PLL control register44 */45#define IPROC_CLK_EMBED_PWRCTRL BIT(5)46 47/*48 * Some PLLs have separate registers for Status and Control. Identify this to49 * let the driver know if additional registers need to be used50 */51#define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6)52 53/*54 * Some PLLs have an additional divide by 2 in master clock calculation;55 * MCLK = VCO_freq / (Mdiv * 2). Identify this to let the driver know56 * of modified calculations57 */58#define IPROC_CLK_MCLK_DIV_BY_2 BIT(7)59 60/*61 * Some PLLs provide a look up table for the leaf clock frequencies and62 * auto calculates VCO frequency parameters based on the provided leaf63 * clock frequencies. They have a user mode that allows the divider64 * controls to be determined by the user65 */66#define IPROC_CLK_PLL_USER_MODE_ON BIT(8)67 68/*69 * Some PLLs have an active low reset70 */71#define IPROC_CLK_PLL_RESET_ACTIVE_LOW BIT(9)72 73/*74 * Calculate the PLL parameters are runtime, instead of using table75 */76#define IPROC_CLK_PLL_CALC_PARAM BIT(10)77 78/*79 * Parameters for VCO frequency configuration80 *81 * VCO frequency =82 * ((ndiv_int + ndiv_frac / 2^20) * (ref frequency / pdiv)83 */84struct iproc_pll_vco_param {85 unsigned long rate;86 unsigned int ndiv_int;87 unsigned int ndiv_frac;88 unsigned int pdiv;89};90 91struct iproc_clk_reg_op {92 unsigned int offset;93 unsigned int shift;94 unsigned int width;95};96 97/*98 * Clock gating control at the top ASIU level99 */100struct iproc_asiu_gate {101 unsigned int offset;102 unsigned int en_shift;103};104 105/*106 * Control of powering on/off of a PLL107 *108 * Before powering off a PLL, input isolation (ISO) needs to be enabled109 */110struct iproc_pll_aon_pwr_ctrl {111 unsigned int offset;112 unsigned int pwr_width;113 unsigned int pwr_shift;114 unsigned int iso_shift;115};116 117/*118 * Control of the PLL reset119 */120struct iproc_pll_reset_ctrl {121 unsigned int offset;122 unsigned int reset_shift;123 unsigned int p_reset_shift;124};125 126/*127 * Control of the Ki, Kp, and Ka parameters128 */129struct iproc_pll_dig_filter_ctrl {130 unsigned int offset;131 unsigned int ki_shift;132 unsigned int ki_width;133 unsigned int kp_shift;134 unsigned int kp_width;135 unsigned int ka_shift;136 unsigned int ka_width;137};138 139/*140 * To enable SW control of the PLL141 */142struct iproc_pll_sw_ctrl {143 unsigned int offset;144 unsigned int shift;145};146 147struct iproc_pll_vco_ctrl {148 unsigned int u_offset;149 unsigned int l_offset;150};151 152/*153 * Main PLL control parameters154 */155struct iproc_pll_ctrl {156 unsigned long flags;157 struct iproc_pll_aon_pwr_ctrl aon;158 struct iproc_asiu_gate asiu;159 struct iproc_pll_reset_ctrl reset;160 struct iproc_pll_dig_filter_ctrl dig_filter;161 struct iproc_pll_sw_ctrl sw_ctrl;162 struct iproc_clk_reg_op ndiv_int;163 struct iproc_clk_reg_op ndiv_frac;164 struct iproc_clk_reg_op pdiv;165 struct iproc_pll_vco_ctrl vco_ctrl;166 struct iproc_clk_reg_op status;167 struct iproc_clk_reg_op macro_mode;168};169 170/*171 * Controls enabling/disabling a PLL derived clock172 */173struct iproc_clk_enable_ctrl {174 unsigned int offset;175 unsigned int enable_shift;176 unsigned int hold_shift;177 unsigned int bypass_shift;178};179 180/*181 * Main clock control parameters for clocks derived from the PLLs182 */183struct iproc_clk_ctrl {184 unsigned int channel;185 unsigned long flags;186 struct iproc_clk_enable_ctrl enable;187 struct iproc_clk_reg_op mdiv;188};189 190/*191 * Divisor of the ASIU clocks192 */193struct iproc_asiu_div {194 unsigned int offset;195 unsigned int en_shift;196 unsigned int high_shift;197 unsigned int high_width;198 unsigned int low_shift;199 unsigned int low_width;200};201 202void iproc_armpll_setup(struct device_node *node);203void iproc_pll_clk_setup(struct device_node *node,204 const struct iproc_pll_ctrl *pll_ctrl,205 const struct iproc_pll_vco_param *vco,206 unsigned int num_vco_entries,207 const struct iproc_clk_ctrl *clk_ctrl,208 unsigned int num_clks);209void iproc_asiu_setup(struct device_node *node,210 const struct iproc_asiu_div *div,211 const struct iproc_asiu_gate *gate,212 unsigned int num_clks);213 214#endif /* _CLK_IPROC_H */215