Merge branch 'fix' of git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6
authorRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 8 Jun 2010 18:40:08 +0000 (19:40 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 8 Jun 2010 18:40:08 +0000 (19:40 +0100)
1  2 
arch/arm/mach-ux500/clock.c

@@@ -16,7 -16,6 +16,7 @@@
  
  #include <asm/clkdev.h>
  
 +#include <plat/mtu.h>
  #include <mach/hardware.h>
  #include "clock.h"
  
@@@ -60,9 -59,6 +60,9 @@@
  #define PRCM_DMACLK_MGT               0x074
  #define PRCM_B2R2CLK_MGT      0x078
  #define PRCM_TVCLK_MGT                0x07C
 +#define PRCM_TCR              0x1C8
 +#define PRCM_TCR_STOPPED      (1 << 16)
 +#define PRCM_TCR_DOZE_MODE    (1 << 17)
  #define PRCM_UNIPROCLK_MGT    0x278
  #define PRCM_SSPCLK_MGT               0x280
  #define PRCM_RNGCLK_MGT               0x284
@@@ -124,95 -120,10 +124,95 @@@ void clk_disable(struct clk *clk
  }
  EXPORT_SYMBOL(clk_disable);
  
 +/*
 + * The MTU has a separate, rather complex muxing setup
 + * with alternative parents (peripheral cluster or
 + * ULP or fixed 32768 Hz) depending on settings
 + */
 +static unsigned long clk_mtu_get_rate(struct clk *clk)
 +{
 +      void __iomem *addr = __io_address(U8500_PRCMU_BASE)
 +              + PRCM_TCR;
 +      u32 tcr = readl(addr);
 +      int mtu = (int) clk->data;
 +      /*
 +       * One of these is selected eventually
 +       * TODO: Replace the constant with a reference
 +       * to the ULP source once this is modeled.
 +       */
 +      unsigned long clk32k = 32768;
 +      unsigned long mturate;
 +      unsigned long retclk;
 +
 +      /* Get the rate from the parent as a default */
 +      if (clk->parent_periph)
 +              mturate = clk_get_rate(clk->parent_periph);
 +      else if (clk->parent_cluster)
 +              mturate = clk_get_rate(clk->parent_cluster);
 +      else
 +              /* We need to be connected SOMEWHERE */
 +              BUG();
 +
 +      /*
 +       * Are we in doze mode?
 +       * In this mode the parent peripheral or the fixed 32768 Hz
 +       * clock is fed into the block.
 +       */
 +      if (!(tcr & PRCM_TCR_DOZE_MODE)) {
 +              /*
 +               * Here we're using the clock input from the APE ULP
 +               * clock domain. But first: are the timers stopped?
 +               */
 +              if (tcr & PRCM_TCR_STOPPED) {
 +                      clk32k = 0;
 +                      mturate = 0;
 +              } else {
 +                      /* Else default mode: 0 and 2.4 MHz */
 +                      clk32k = 0;
 +                      if (cpu_is_u5500())
 +                              /* DB5500 divides by 8 */
 +                              mturate /= 8;
 +                      else if (cpu_is_u8500ed()) {
 +                              /*
 +                               * This clocking setting must not be used
 +                               * in the ED chip, it is simply not
 +                               * connected anywhere!
 +                               */
 +                              mturate = 0;
 +                              BUG();
 +                      } else
 +                              /*
 +                               * In this mode the ulp38m4 clock is divided
 +                               * by a factor 16, on the DB8500 typically
 +                               * 38400000 / 16 ~ 2.4 MHz.
 +                               * TODO: Replace the constant with a reference
 +                               * to the ULP source once this is modeled.
 +                               */
 +                              mturate = 38400000 / 16;
 +              }
 +      }
 +
 +      /* Return the clock selected for this MTU */
 +      if (tcr & (1 << mtu))
 +              retclk = clk32k;
 +      else
 +              retclk = mturate;
 +
 +      pr_info("MTU%d clock rate: %lu Hz\n", mtu, retclk);
 +      return retclk;
 +}
 +
  unsigned long clk_get_rate(struct clk *clk)
  {
        unsigned long rate;
  
 +      /*
 +       * If there is a custom getrate callback for this clock,
 +       * it will take precedence.
 +       */
 +      if (clk->get_rate)
 +              return clk->get_rate(clk);
 +
        if (clk->ops && clk->ops->get_rate)
                return clk->ops->get_rate(clk);
  
@@@ -430,9 -341,8 +430,9 @@@ static DEFINE_PRCC_CLK(5, usb_v1,  0,  
  
  /* Peripheral Cluster #6 */
  
 -static DEFINE_PRCC_CLK(6, mtu1_v1,    8, -1, NULL);
 -static DEFINE_PRCC_CLK(6, mtu0_v1,    7, -1, NULL);
 +/* MTU ID in data */
 +static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1);
 +static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0);
  static DEFINE_PRCC_CLK(6, cfgreg_v1,  6,  6, NULL);
  static DEFINE_PRCC_CLK(6, dmc_ed,     6,  6, NULL);
  static DEFINE_PRCC_CLK(6, hash1,      5, -1, NULL);
@@@ -447,9 -357,8 +447,9 @@@ static DEFINE_PRCC_CLK(6, rng_v1,  0,  
  /* Peripheral Cluster #7 */
  
  static DEFINE_PRCC_CLK(7, tzpc0_ed,   4, -1, NULL);
 -static DEFINE_PRCC_CLK(7, mtu1_ed,    3, -1, NULL);
 -static DEFINE_PRCC_CLK(7, mtu0_ed,    2, -1, NULL);
 +/* MTU ID in data */
 +static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1);
 +static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0);
  static DEFINE_PRCC_CLK(7, wdg_ed,     1, -1, NULL);
  static DEFINE_PRCC_CLK(7, cfgreg_ed,  0, -1, NULL);
  
@@@ -502,7 -411,7 +502,7 @@@ static struct clk_lookup u8500_common_c
        CLK(apetraceclk,        "apetrace",     NULL),
        CLK(mcdeclk,    "mcde",         NULL),
        CLK(ipi2clk,    "ipi2",         NULL),
-       CLK(dmaclk,     "dma40",        NULL),
+       CLK(dmaclk,     "dma40.0",      NULL),
        CLK(b2r2clk,    "b2r2",         NULL),
        CLK(tvclk,      "tv",           NULL),
  };
@@@ -594,17 -503,15 +594,17 @@@ static struct clk_lookup u8500_v1_clks[
        CLK(uiccclk,    "uicc",         NULL),
  };
  
 -static int __init clk_init(void)
 +int __init clk_init(void)
  {
        if (cpu_is_u8500ed()) {
                clk_prcmu_ops.enable = clk_prcmu_ed_enable;
                clk_prcmu_ops.disable = clk_prcmu_ed_disable;
 +              clk_per6clk.rate = 100000000;
        } else if (cpu_is_u5500()) {
                /* Clock tree for U5500 not implemented yet */
                clk_prcc_ops.enable = clk_prcc_ops.disable = NULL;
                clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL;
 +              clk_per6clk.rate = 26000000;
        }
  
        clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks));
  
        return 0;
  }
 -arch_initcall(clk_init);