linux/drivers/clk/ti/clkt_iclk.c
<<
>>
Prefs
   1/*
   2 * OMAP2/3 interface clock control
   3 *
   4 * Copyright (C) 2011 Nokia Corporation
   5 * Paul Walmsley
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11#undef DEBUG
  12
  13#include <linux/kernel.h>
  14#include <linux/clk-provider.h>
  15#include <linux/io.h>
  16#include <linux/clk/ti.h>
  17
  18#include "clock.h"
  19
  20/* Register offsets */
  21#define OMAP24XX_CM_FCLKEN2             0x04
  22#define CM_AUTOIDLE                     0x30
  23#define CM_ICLKEN                       0x10
  24#define CM_IDLEST                       0x20
  25
  26#define OMAP24XX_CM_IDLEST_VAL          0
  27
  28/* Private functions */
  29
  30/* XXX */
  31void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk)
  32{
  33        u32 v;
  34        void __iomem *r;
  35
  36        r = (__force void __iomem *)
  37                ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
  38
  39        v = ti_clk_ll_ops->clk_readl(r);
  40        v |= (1 << clk->enable_bit);
  41        ti_clk_ll_ops->clk_writel(v, r);
  42}
  43
  44/* XXX */
  45void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk)
  46{
  47        u32 v;
  48        void __iomem *r;
  49
  50        r = (__force void __iomem *)
  51                ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
  52
  53        v = ti_clk_ll_ops->clk_readl(r);
  54        v &= ~(1 << clk->enable_bit);
  55        ti_clk_ll_ops->clk_writel(v, r);
  56}
  57
  58/**
  59 * omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
  60 * @clk: struct clk * being enabled
  61 * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
  62 * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
  63 * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
  64 *
  65 * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the
  66 * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE.  This custom function
  67 * passes back the correct CM_IDLEST register address for I2CHS
  68 * modules.  No return value.
  69 */
  70static void omap2430_clk_i2chs_find_idlest(struct clk_hw_omap *clk,
  71                                           void __iomem **idlest_reg,
  72                                           u8 *idlest_bit,
  73                                           u8 *idlest_val)
  74{
  75        u32 r;
  76
  77        r = ((__force u32)clk->enable_reg ^ (OMAP24XX_CM_FCLKEN2 ^ CM_IDLEST));
  78        *idlest_reg = (__force void __iomem *)r;
  79        *idlest_bit = clk->enable_bit;
  80        *idlest_val = OMAP24XX_CM_IDLEST_VAL;
  81}
  82
  83/* Public data */
  84
  85const struct clk_hw_omap_ops clkhwops_iclk = {
  86        .allow_idle     = omap2_clkt_iclk_allow_idle,
  87        .deny_idle      = omap2_clkt_iclk_deny_idle,
  88};
  89
  90const struct clk_hw_omap_ops clkhwops_iclk_wait = {
  91        .allow_idle     = omap2_clkt_iclk_allow_idle,
  92        .deny_idle      = omap2_clkt_iclk_deny_idle,
  93        .find_idlest    = omap2_clk_dflt_find_idlest,
  94        .find_companion = omap2_clk_dflt_find_companion,
  95};
  96
  97/* 2430 I2CHS has non-standard IDLEST register */
  98const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait = {
  99        .find_idlest    = omap2430_clk_i2chs_find_idlest,
 100        .find_companion = omap2_clk_dflt_find_companion,
 101};
 102