linux/arch/arm/mach-w90x900/clksel.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-w90x900/clksel.c
   3 *
   4 * Copyright (c) 2008 Nuvoton technology corporation
   5 *
   6 * Wan ZongShun <mcuos.com@gmail.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation;version 2 of the License.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/kernel.h>
  15#include <linux/device.h>
  16#include <linux/list.h>
  17#include <linux/errno.h>
  18#include <linux/err.h>
  19#include <linux/string.h>
  20#include <linux/clk.h>
  21#include <linux/mutex.h>
  22#include <linux/io.h>
  23
  24#include <mach/hardware.h>
  25#include <mach/regs-clock.h>
  26
  27#define PLL0            0x00
  28#define PLL1            0x01
  29#define OTHER           0x02
  30#define EXT             0x03
  31#define MSOFFSET        0x0C
  32#define ATAOFFSET       0x0a
  33#define LCDOFFSET       0x06
  34#define AUDOFFSET       0x04
  35#define CPUOFFSET       0x00
  36
  37static DEFINE_MUTEX(clksel_sem);
  38
  39static void clock_source_select(const char *dev_id, unsigned int clkval)
  40{
  41        unsigned int clksel, offset;
  42
  43        clksel = __raw_readl(REG_CLKSEL);
  44
  45        if (strcmp(dev_id, "nuc900-ms") == 0)
  46                offset = MSOFFSET;
  47        else if (strcmp(dev_id, "nuc900-atapi") == 0)
  48                offset = ATAOFFSET;
  49        else if (strcmp(dev_id, "nuc900-lcd") == 0)
  50                offset = LCDOFFSET;
  51        else if (strcmp(dev_id, "nuc900-ac97") == 0)
  52                offset = AUDOFFSET;
  53        else
  54                offset = CPUOFFSET;
  55
  56        clksel &= ~(0x03 << offset);
  57        clksel |= (clkval << offset);
  58
  59        __raw_writel(clksel, REG_CLKSEL);
  60}
  61
  62void nuc900_clock_source(struct device *dev, unsigned char *src)
  63{
  64        unsigned int clkval;
  65        const char *dev_id;
  66
  67        BUG_ON(!src);
  68        clkval = 0;
  69
  70        mutex_lock(&clksel_sem);
  71
  72        if (dev)
  73                dev_id = dev_name(dev);
  74        else
  75                dev_id = "cpufreq";
  76
  77        if (strcmp(src, "pll0") == 0)
  78                clkval = PLL0;
  79        else if (strcmp(src, "pll1") == 0)
  80                clkval = PLL1;
  81        else if (strcmp(src, "ext") == 0)
  82                clkval = EXT;
  83        else if (strcmp(src, "oth") == 0)
  84                clkval = OTHER;
  85
  86        clock_source_select(dev_id, clkval);
  87
  88        mutex_unlock(&clksel_sem);
  89}
  90EXPORT_SYMBOL(nuc900_clock_source);
  91
  92