linux/drivers/clk/bcm/clk-iproc.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2014 Broadcom Corporation
   3 *
   4 * This program is free software; you can redistribute it and/or
   5 * modify it under the terms of the GNU General Public License as
   6 * published by the Free Software Foundation version 2.
   7 *
   8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
   9 * kind, whether express or implied; without even the implied warranty
  10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11 * GNU General Public License for more details.
  12 */
  13
  14#ifndef _CLK_IPROC_H
  15#define _CLK_IPROC_H
  16
  17#include <linux/kernel.h>
  18#include <linux/list.h>
  19#include <linux/spinlock.h>
  20#include <linux/slab.h>
  21#include <linux/device.h>
  22#include <linux/of.h>
  23#include <linux/clk-provider.h>
  24
  25#define IPROC_CLK_NAME_LEN 25
  26#define IPROC_CLK_INVALID_OFFSET 0xffffffff
  27#define bit_mask(width) ((1 << (width)) - 1)
  28
  29/* clocks that should not be disabled at runtime */
  30#define IPROC_CLK_AON BIT(0)
  31
  32/* PLL that requires gating through ASIU */
  33#define IPROC_CLK_PLL_ASIU BIT(1)
  34
  35/* PLL that has fractional part of the NDIV */
  36#define IPROC_CLK_PLL_HAS_NDIV_FRAC BIT(2)
  37
  38/*
  39 * Some of the iProc PLL/clocks may have an ASIC bug that requires read back
  40 * of the same register following the write to flush the write transaction into
  41 * the intended register
  42 */
  43#define IPROC_CLK_NEEDS_READ_BACK BIT(3)
  44
  45/*
  46 * Some PLLs require the PLL SW override bit to be set before changes can be
  47 * applied to the PLL
  48 */
  49#define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4)
  50
  51/*
  52 * Some PLLs use a different way to control clock power, via the PWRDWN bit in
  53 * the PLL control register
  54 */
  55#define IPROC_CLK_EMBED_PWRCTRL BIT(5)
  56
  57/*
  58 * Some PLLs have separate registers for Status and Control.  Identify this to
  59 * let the driver know if additional registers need to be used
  60 */
  61#define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6)
  62
  63/*
  64 * Some PLLs have an additional divide by 2 in master clock calculation;
  65 * MCLK = VCO_freq / (Mdiv * 2). Identify this to let the driver know
  66 * of modified calculations
  67 */
  68#define IPROC_CLK_MCLK_DIV_BY_2 BIT(7)
  69
  70/*
  71 * Some PLLs provide a look up table for the leaf clock frequencies and
  72 * auto calculates VCO frequency parameters based on the provided leaf
  73 * clock frequencies. They have a user mode that allows the divider
  74 * controls to be determined by the user
  75 */
  76#define IPROC_CLK_PLL_USER_MODE_ON BIT(8)
  77
  78/*
  79 * Some PLLs have an active low reset
  80 */
  81#define IPROC_CLK_PLL_RESET_ACTIVE_LOW BIT(9)
  82
  83/*
  84 * Parameters for VCO frequency configuration
  85 *
  86 * VCO frequency =
  87 * ((ndiv_int + ndiv_frac / 2^20) * (ref freqeuncy  / pdiv)
  88 */
  89struct iproc_pll_vco_param {
  90        unsigned long rate;
  91        unsigned int ndiv_int;
  92        unsigned int ndiv_frac;
  93        unsigned int pdiv;
  94};
  95
  96struct iproc_clk_reg_op {
  97        unsigned int offset;
  98        unsigned int shift;
  99        unsigned int width;
 100};
 101
 102/*
 103 * Clock gating control at the top ASIU level
 104 */
 105struct iproc_asiu_gate {
 106        unsigned int offset;
 107        unsigned int en_shift;
 108};
 109
 110/*
 111 * Control of powering on/off of a PLL
 112 *
 113 * Before powering off a PLL, input isolation (ISO) needs to be enabled
 114 */
 115struct iproc_pll_aon_pwr_ctrl {
 116        unsigned int offset;
 117        unsigned int pwr_width;
 118        unsigned int pwr_shift;
 119        unsigned int iso_shift;
 120};
 121
 122/*
 123 * Control of the PLL reset
 124 */
 125struct iproc_pll_reset_ctrl {
 126        unsigned int offset;
 127        unsigned int reset_shift;
 128        unsigned int p_reset_shift;
 129};
 130
 131/*
 132 * Control of the Ki, Kp, and Ka parameters
 133 */
 134struct iproc_pll_dig_filter_ctrl {
 135        unsigned int offset;
 136        unsigned int ki_shift;
 137        unsigned int ki_width;
 138        unsigned int kp_shift;
 139        unsigned int kp_width;
 140        unsigned int ka_shift;
 141        unsigned int ka_width;
 142};
 143
 144/*
 145 * To enable SW control of the PLL
 146 */
 147struct iproc_pll_sw_ctrl {
 148        unsigned int offset;
 149        unsigned int shift;
 150};
 151
 152struct iproc_pll_vco_ctrl {
 153        unsigned int u_offset;
 154        unsigned int l_offset;
 155};
 156
 157/*
 158 * Main PLL control parameters
 159 */
 160struct iproc_pll_ctrl {
 161        unsigned long flags;
 162        struct iproc_pll_aon_pwr_ctrl aon;
 163        struct iproc_asiu_gate asiu;
 164        struct iproc_pll_reset_ctrl reset;
 165        struct iproc_pll_dig_filter_ctrl dig_filter;
 166        struct iproc_pll_sw_ctrl sw_ctrl;
 167        struct iproc_clk_reg_op ndiv_int;
 168        struct iproc_clk_reg_op ndiv_frac;
 169        struct iproc_clk_reg_op pdiv;
 170        struct iproc_pll_vco_ctrl vco_ctrl;
 171        struct iproc_clk_reg_op status;
 172        struct iproc_clk_reg_op macro_mode;
 173};
 174
 175/*
 176 * Controls enabling/disabling a PLL derived clock
 177 */
 178struct iproc_clk_enable_ctrl {
 179        unsigned int offset;
 180        unsigned int enable_shift;
 181        unsigned int hold_shift;
 182        unsigned int bypass_shift;
 183};
 184
 185/*
 186 * Main clock control parameters for clocks derived from the PLLs
 187 */
 188struct iproc_clk_ctrl {
 189        unsigned int channel;
 190        unsigned long flags;
 191        struct iproc_clk_enable_ctrl enable;
 192        struct iproc_clk_reg_op mdiv;
 193};
 194
 195/*
 196 * Divisor of the ASIU clocks
 197 */
 198struct iproc_asiu_div {
 199        unsigned int offset;
 200        unsigned int en_shift;
 201        unsigned int high_shift;
 202        unsigned int high_width;
 203        unsigned int low_shift;
 204        unsigned int low_width;
 205};
 206
 207void iproc_armpll_setup(struct device_node *node);
 208void iproc_pll_clk_setup(struct device_node *node,
 209                         const struct iproc_pll_ctrl *pll_ctrl,
 210                         const struct iproc_pll_vco_param *vco,
 211                         unsigned int num_vco_entries,
 212                         const struct iproc_clk_ctrl *clk_ctrl,
 213                         unsigned int num_clks);
 214void iproc_asiu_setup(struct device_node *node,
 215                      const struct iproc_asiu_div *div,
 216                      const struct iproc_asiu_gate *gate,
 217                      unsigned int num_clks);
 218
 219#endif /* _CLK_IPROC_H */
 220