Logo Search packages:      
Sourcecode: linux version File versions  Download package

clock.h

/*
 *  Copyright (C) 2010 ST-Ericsson
 *  Copyright (C) 2009 STMicroelectronics
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

/**
 * struct clkops - ux500 clock operations
 * @enable: function to enable the clock
 * @disable:      function to disable the clock
 * @get_rate:     function to get the current clock rate
 *
 * This structure contains function pointers to functions that will be used to
 * control the clock.  All of these functions are optional.  If get_rate is
 * NULL, the rate in the struct clk will be used.
 */
struct clkops {
      void (*enable) (struct clk *);
      void (*disable) (struct clk *);
      unsigned long (*get_rate) (struct clk *);
};

/**
 * struct clk - ux500 clock structure
 * @ops:          pointer to clkops struct used to control this clock
 * @name:         name, for debugging
 * @enabled:            refcount. positive if enabled, zero if disabled
 * @get_rate:           custom callback for getting the clock rate
 * @data:         custom per-clock data for example for the get_rate
 *                callback
 * @rate:         fixed rate for clocks which don't implement
 *                ops->getrate
 * @prcmu_cg_off: address offset of the combined enable/disable register
 *                (used on u8500v1)
 * @prcmu_cg_bit: bit in the combined enable/disable register (used on
 *                u8500v1)
 * @prcmu_cg_mgt: address of the enable/disable register (used on
 *                u8500ed)
 * @cluster:            peripheral cluster number
 * @prcc_bus:           bit for the bus clock in the peripheral's CLKRST
 * @prcc_kernel:  bit for the kernel clock in the peripheral's CLKRST.
 *                -1 if no kernel clock exists.
 * @parent_cluster:     pointer to parent's cluster clk struct
 * @parent_periph:      pointer to parent's peripheral clk struct
 *
 * Peripherals are organised into clusters, and each cluster has an associated
 * bus clock.  Some peripherals also have a parent peripheral clock.
 *
 * In order to enable a clock for a peripheral, we need to enable:
 *    (1) the parent cluster (bus) clock at the PRCMU level
 *    (2) the parent peripheral clock (if any) at the PRCMU level
 *    (3) the peripheral's bus & kernel clock at the PRCC level
 *
 * (1) and (2) are handled by defining clk structs (DEFINE_PRCMU_CLK) for each
 * of the cluster and peripheral clocks, and hooking these as the parents of
 * the individual peripheral clocks.
 *
 * (3) is handled by specifying the bits in the PRCC control registers required
 * to enable these clocks and modifying them in the ->enable and
 * ->disable callbacks of the peripheral clocks (DEFINE_PRCC_CLK).
 *
 * This structure describes both the PRCMU-level clocks and PRCC-level clocks.
 * The prcmu_* fields are only used for the PRCMU clocks, and the cluster,
 * prcc, and parent pointers are only used for the PRCC-level clocks.
 */
struct clk {
      const struct clkops     *ops;
      const char        *name;
      unsigned int            enabled;
      unsigned long           (*get_rate)(struct clk *);
      void              *data;

      unsigned long           rate;
      struct list_head  list;

      /* These three are only for PRCMU clks */

      unsigned int            prcmu_cg_off;
      unsigned int            prcmu_cg_bit;
      unsigned int            prcmu_cg_mgt;

      /* The rest are only for PRCC clks */

      int               cluster;
      unsigned int            prcc_bus;
      unsigned int            prcc_kernel;

      struct clk        *parent_cluster;
      struct clk        *parent_periph;
#if defined(CONFIG_DEBUG_FS)
      struct dentry           *dent;            /* For visible tree hierarchy */
      struct dentry           *dent_bus;  /* For visible tree hierarchy */
#endif
};

#define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg)           \
struct clk clk_##_name = {                            \
            .name       = #_name,               \
            .ops        = &clk_prcmu_ops,             \
            .prcmu_cg_off     = _cg_off,              \
            .prcmu_cg_bit     = _cg_bit,              \
            .prcmu_cg_mgt     = PRCM_##_reg##_MGT           \
      }

#define DEFINE_PRCMU_CLK_RATE(_name, _cg_off, _cg_bit, _reg, _rate)     \
struct clk clk_##_name = {                                  \
            .name       = #_name,                     \
            .ops        = &clk_prcmu_ops,                   \
            .prcmu_cg_off     = _cg_off,                    \
            .prcmu_cg_bit     = _cg_bit,                    \
            .rate       = _rate,                      \
            .prcmu_cg_mgt     = PRCM_##_reg##_MGT                 \
      }

#define DEFINE_PRCC_CLK(_pclust, _name, _bus_en, _kernel_en, _kernclk)  \
struct clk clk_##_name = {                                  \
            .name       = #_name,                     \
            .ops        = &clk_prcc_ops,              \
            .cluster    = _pclust,                    \
            .prcc_bus   = _bus_en,                    \
            .prcc_kernel      = _kernel_en,                       \
            .parent_cluster = &clk_per##_pclust##clk,       \
            .parent_periph    = _kernclk                    \
      }

#define DEFINE_PRCC_CLK_CUSTOM(_pclust, _name, _bus_en, _kernel_en, _kernclk, _callback, _data) \
struct clk clk_##_name = {                                  \
            .name       = #_name,                     \
            .ops        = &clk_prcc_ops,              \
            .cluster    = _pclust,                    \
            .prcc_bus   = _bus_en,                    \
            .prcc_kernel      = _kernel_en,                       \
            .parent_cluster = &clk_per##_pclust##clk,       \
            .parent_periph    = _kernclk,                   \
            .get_rate   = _callback,                        \
            .data       = (void *) _data              \
      }


#define CLK(_clk, _devname, _conname)                 \
      {                                   \
            .clk  = &clk_##_clk,                \
            .dev_id     = _devname,             \
            .con_id = _conname,                 \
      }

int __init clk_db8500_ed_fixup(void);
int __init clk_init(void);

Generated by  Doxygen 1.6.0   Back to index