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