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 * Calculate the PLL parameters are runtime, instead of using table
  85 */
  86#define IPROC_CLK_PLL_CALC_PARAM BIT(10)
  87
  88/*
  89 * Parameters for VCO frequency configuration
  90 *
  91 * VCO frequency =
  92 * ((ndiv_int + ndiv_frac / 2^20) * (ref freqeuncy  / pdiv)
  93 */
  94struct iproc_pll_vco_param {
  95        unsigned long rate;
  96        unsigned int ndiv_int;
  97        unsigned int ndiv_frac;
  98        unsigned int pdiv;
  99};
 100
 101struct iproc_clk_reg_op {
 102        unsigned int offset;
 103        unsigned int shift;
 104        unsigned int width;
 105};
 106
 107/*
 108 * Clock gating control at the top ASIU level
 109 */
 110struct iproc_asiu_gate {
 111        unsigned int offset;
 112        unsigned int en_shift;
 113};
 114
 115/*
 116 * Control of powering on/off of a PLL
 117 *
 118 * Before powering off a PLL, input isolation (ISO) needs to be enabled
 119 */
 120struct iproc_pll_aon_pwr_ctrl {
 121        unsigned int offset;
 122        unsigned int pwr_width;
 123        unsigned int pwr_shift;
 124        unsigned int iso_shift;
 125};
 126
 127/*
 128 * Control of the PLL reset
 129 */
 130struct iproc_pll_reset_ctrl {
 131        unsigned int offset;
 132        unsigned int reset_shift;
 133        unsigned int p_reset_shift;
 134};
 135
 136/*
 137 * Control of the Ki, Kp, and Ka parameters
 138 */
 139struct iproc_pll_dig_filter_ctrl {
 140        unsigned int offset;
 141        unsigned int ki_shift;
 142        unsigned int ki_width;
 143        unsigned int kp_shift;
 144        unsigned int kp_width;
 145        unsigned int ka_shift;
 146        unsigned int ka_width;
 147};
 148
 149/*
 150 * To enable SW control of the PLL
 151 */
 152struct iproc_pll_sw_ctrl {
 153        unsigned int offset;
 154        unsigned int shift;
 155};
 156
 157struct iproc_pll_vco_ctrl {
 158        unsigned int u_offset;
 159        unsigned int l_offset;
 160};
 161
 162/*
 163 * Main PLL control parameters
 164 */
 165struct iproc_pll_ctrl {
 166        unsigned long flags;
 167        struct iproc_pll_aon_pwr_ctrl aon;
 168        struct iproc_asiu_gate asiu;
 169        struct iproc_pll_reset_ctrl reset;
 170        struct iproc_pll_dig_filter_ctrl dig_filter;
 171        struct iproc_pll_sw_ctrl sw_ctrl;
 172        struct iproc_clk_reg_op ndiv_int;
 173        struct iproc_clk_reg_op ndiv_frac;
 174        struct iproc_clk_reg_op pdiv;
 175        struct iproc_pll_vco_ctrl vco_ctrl;
 176        struct iproc_clk_reg_op status;
 177        struct iproc_clk_reg_op macro_mode;
 178};
 179
 180/*
 181 * Controls enabling/disabling a PLL derived clock
 182 */
 183struct iproc_clk_enable_ctrl {
 184        unsigned int offset;
 185        unsigned int enable_shift;
 186        unsigned int hold_shift;
 187        unsigned int bypass_shift;
 188};
 189
 190/*
 191 * Main clock control parameters for clocks derived from the PLLs
 192 */
 193struct iproc_clk_ctrl {
 194        unsigned int channel;
 195        unsigned long flags;
 196        struct iproc_clk_enable_ctrl enable;
 197        struct iproc_clk_reg_op mdiv;
 198};
 199
 200/*
 201 * Divisor of the ASIU clocks
 202 */
 203struct iproc_asiu_div {
 204        unsigned int offset;
 205        unsigned int en_shift;
 206        unsigned int high_shift;
 207        unsigned int high_width;
 208        unsigned int low_shift;
 209        unsigned int low_width;
 210};
 211
 212void iproc_armpll_setup(struct device_node *node);
 213void iproc_pll_clk_setup(struct device_node *node,
 214                         const struct iproc_pll_ctrl *pll_ctrl,
 215                         const struct iproc_pll_vco_param *vco,
 216                         unsigned int num_vco_entries,
 217                         const struct iproc_clk_ctrl *clk_ctrl,
 218                         unsigned int num_clks);
 219void iproc_asiu_setup(struct device_node *node,
 220                      const struct iproc_asiu_div *div,
 221                      const struct iproc_asiu_gate *gate,
 222                      unsigned int num_clks);
 223
 224#endif /* _CLK_IPROC_H */
 225