diff options
| author | wanzongshun <mcuos.com@gmail.com> | 2009-07-30 21:30:32 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-08-01 11:23:57 -0400 |
| commit | ae45b1c618d9e645a5e1decff31b710f739745fa (patch) | |
| tree | de581101750f9b1a040fbb131740424649995281 /arch | |
| parent | 897bd6a363770ced6b78f6ae8882325c7590ed8b (diff) | |
ARM: 5634/1: Add static setting cpu frequence for w90p910 platform
Add static setting cpu frequence for w90p910 platform.
Signed-off-by: Wan ZongShun <mcuos.com@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/arm/mach-w90x900/Makefile | 2 | ||||
| -rw-r--r-- | arch/arm/mach-w90x900/clksel.c | 91 | ||||
| -rw-r--r-- | arch/arm/mach-w90x900/cpu.h | 1 | ||||
| -rw-r--r-- | arch/arm/mach-w90x900/include/mach/regs-clock.h | 22 | ||||
| -rw-r--r-- | arch/arm/mach-w90x900/include/mach/regs-ebi.h | 33 | ||||
| -rw-r--r-- | arch/arm/mach-w90x900/w90p910.c | 80 |
6 files changed, 228 insertions, 1 deletions
diff --git a/arch/arm/mach-w90x900/Makefile b/arch/arm/mach-w90x900/Makefile index d50c94f4dbdf..3ccd625455cf 100644 --- a/arch/arm/mach-w90x900/Makefile +++ b/arch/arm/mach-w90x900/Makefile | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | # Object file lists. | 5 | # Object file lists. |
| 6 | 6 | ||
| 7 | obj-y := irq.o time.o mfp-w90p910.o gpio.o clock.o | 7 | obj-y := irq.o time.o mfp-w90p910.o gpio.o clock.o |
| 8 | 8 | obj-y += clksel.o | |
| 9 | # W90X900 CPU support files | 9 | # W90X900 CPU support files |
| 10 | 10 | ||
| 11 | obj-$(CONFIG_CPU_W90P910) += w90p910.o | 11 | obj-$(CONFIG_CPU_W90P910) += w90p910.o |
diff --git a/arch/arm/mach-w90x900/clksel.c b/arch/arm/mach-w90x900/clksel.c new file mode 100644 index 000000000000..5a77eb91cb16 --- /dev/null +++ b/arch/arm/mach-w90x900/clksel.c | |||
| @@ -0,0 +1,91 @@ | |||
| 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 | |||
| 37 | static DEFINE_MUTEX(clksel_sem); | ||
| 38 | |||
| 39 | static 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, "w90p910-ms") == 0) | ||
| 46 | offset = MSOFFSET; | ||
| 47 | else if (strcmp(dev_id, "w90p910-atapi") == 0) | ||
| 48 | offset = ATAOFFSET; | ||
| 49 | else if (strcmp(dev_id, "w90p910-lcd") == 0) | ||
| 50 | offset = LCDOFFSET; | ||
| 51 | else if (strcmp(dev_id, "w90p910-audio") == 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 | |||
| 62 | void w90p910_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 | } | ||
| 90 | EXPORT_SYMBOL(w90p910_clock_source); | ||
| 91 | |||
diff --git a/arch/arm/mach-w90x900/cpu.h b/arch/arm/mach-w90x900/cpu.h index 57b5dbabeb41..ddde959d8987 100644 --- a/arch/arm/mach-w90x900/cpu.h +++ b/arch/arm/mach-w90x900/cpu.h | |||
| @@ -45,6 +45,7 @@ extern void w90p910_init_clocks(void); | |||
| 45 | extern void w90p910_map_io(struct map_desc *mach_desc, int size); | 45 | extern void w90p910_map_io(struct map_desc *mach_desc, int size); |
| 46 | extern struct platform_device w90p910_serial_device; | 46 | extern struct platform_device w90p910_serial_device; |
| 47 | extern struct sys_timer w90x900_timer; | 47 | extern struct sys_timer w90x900_timer; |
| 48 | extern void w90p910_clock_source(struct device *dev, unsigned char *src); | ||
| 48 | 49 | ||
| 49 | #define W90X900_8250PORT(name) \ | 50 | #define W90X900_8250PORT(name) \ |
| 50 | { \ | 51 | { \ |
diff --git a/arch/arm/mach-w90x900/include/mach/regs-clock.h b/arch/arm/mach-w90x900/include/mach/regs-clock.h index f10b6a8dc069..516d6b477b61 100644 --- a/arch/arm/mach-w90x900/include/mach/regs-clock.h +++ b/arch/arm/mach-w90x900/include/mach/regs-clock.h | |||
| @@ -28,4 +28,26 @@ | |||
| 28 | #define REG_CLKEN1 (CLK_BA + 0x24) | 28 | #define REG_CLKEN1 (CLK_BA + 0x24) |
| 29 | #define REG_CLKDIV1 (CLK_BA + 0x28) | 29 | #define REG_CLKDIV1 (CLK_BA + 0x28) |
| 30 | 30 | ||
| 31 | /* Define PLL freq setting */ | ||
| 32 | #define PLL_DISABLE 0x12B63 | ||
| 33 | #define PLL_66MHZ 0x2B63 | ||
| 34 | #define PLL_100MHZ 0x4F64 | ||
| 35 | #define PLL_120MHZ 0x4F63 | ||
| 36 | #define PLL_166MHZ 0x4124 | ||
| 37 | #define PLL_200MHZ 0x4F24 | ||
| 38 | |||
| 39 | /* Define AHB:CPUFREQ ratio */ | ||
| 40 | #define AHB_CPUCLK_1_1 0x00 | ||
| 41 | #define AHB_CPUCLK_1_2 0x01 | ||
| 42 | #define AHB_CPUCLK_1_4 0x02 | ||
| 43 | #define AHB_CPUCLK_1_8 0x03 | ||
| 44 | |||
| 45 | /* Define APB:AHB ratio */ | ||
| 46 | #define APB_AHB_1_2 0x01 | ||
| 47 | #define APB_AHB_1_4 0x02 | ||
| 48 | #define APB_AHB_1_8 0x03 | ||
| 49 | |||
| 50 | /* Define clock skew */ | ||
| 51 | #define DEFAULTSKEW 0x48 | ||
| 52 | |||
| 31 | #endif /* __ASM_ARCH_REGS_CLOCK_H */ | 53 | #endif /* __ASM_ARCH_REGS_CLOCK_H */ |
diff --git a/arch/arm/mach-w90x900/include/mach/regs-ebi.h b/arch/arm/mach-w90x900/include/mach/regs-ebi.h new file mode 100644 index 000000000000..b68455e7f88b --- /dev/null +++ b/arch/arm/mach-w90x900/include/mach/regs-ebi.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/mach-w90x900/include/mach/regs-ebi.h | ||
| 3 | * | ||
| 4 | * Copyright (c) 2009 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 | |||
| 14 | #ifndef __ASM_ARCH_REGS_EBI_H | ||
| 15 | #define __ASM_ARCH_REGS_EBI_H | ||
| 16 | |||
| 17 | /* EBI Control Registers */ | ||
| 18 | |||
| 19 | #define EBI_BA W90X900_VA_EBI | ||
| 20 | #define REG_EBICON (EBI_BA + 0x00) | ||
| 21 | #define REG_ROMCON (EBI_BA + 0x04) | ||
| 22 | #define REG_SDCONF0 (EBI_BA + 0x08) | ||
| 23 | #define REG_SDCONF1 (EBI_BA + 0x0C) | ||
| 24 | #define REG_SDTIME0 (EBI_BA + 0x10) | ||
| 25 | #define REG_SDTIME1 (EBI_BA + 0x14) | ||
| 26 | #define REG_EXT0CON (EBI_BA + 0x18) | ||
| 27 | #define REG_EXT1CON (EBI_BA + 0x1C) | ||
| 28 | #define REG_EXT2CON (EBI_BA + 0x20) | ||
| 29 | #define REG_EXT3CON (EBI_BA + 0x24) | ||
| 30 | #define REG_EXT4CON (EBI_BA + 0x28) | ||
| 31 | #define REG_CKSKEW (EBI_BA + 0x2C) | ||
| 32 | |||
| 33 | #endif /* __ASM_ARCH_REGS_EBI_H */ | ||
diff --git a/arch/arm/mach-w90x900/w90p910.c b/arch/arm/mach-w90x900/w90p910.c index 6ebf5cfc78da..8444eababaab 100644 --- a/arch/arm/mach-w90x900/w90p910.c +++ b/arch/arm/mach-w90x900/w90p910.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
| 25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
| 26 | #include <linux/serial_8250.h> | 26 | #include <linux/serial_8250.h> |
| 27 | #include <linux/delay.h> | ||
| 27 | 28 | ||
| 28 | #include <asm/mach/arch.h> | 29 | #include <asm/mach/arch.h> |
| 29 | #include <asm/mach/map.h> | 30 | #include <asm/mach/map.h> |
| @@ -32,6 +33,8 @@ | |||
| 32 | 33 | ||
| 33 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
| 34 | #include <mach/regs-serial.h> | 35 | #include <mach/regs-serial.h> |
| 36 | #include <mach/regs-clock.h> | ||
| 37 | #include <mach/regs-ebi.h> | ||
| 35 | 38 | ||
| 36 | #include "cpu.h" | 39 | #include "cpu.h" |
| 37 | #include "clock.h" | 40 | #include "clock.h" |
| @@ -123,6 +126,83 @@ void __init w90p910_map_io(struct map_desc *mach_desc, int mach_size) | |||
| 123 | printk(KERN_ERR "CPU type 0x%08lx is not W90P910\n", idcode); | 126 | printk(KERN_ERR "CPU type 0x%08lx is not W90P910\n", idcode); |
| 124 | } | 127 | } |
| 125 | 128 | ||
| 129 | /*Set W90P910 cpu frequence*/ | ||
| 130 | static int __init w90p910_set_clkval(unsigned int cpufreq) | ||
| 131 | { | ||
| 132 | unsigned int pllclk, ahbclk, apbclk, val; | ||
| 133 | |||
| 134 | pllclk = 0; | ||
| 135 | ahbclk = 0; | ||
| 136 | apbclk = 0; | ||
| 137 | |||
| 138 | switch (cpufreq) { | ||
| 139 | case 66: | ||
| 140 | pllclk = PLL_66MHZ; | ||
| 141 | ahbclk = AHB_CPUCLK_1_1; | ||
| 142 | apbclk = APB_AHB_1_2; | ||
| 143 | break; | ||
| 144 | |||
| 145 | case 100: | ||
| 146 | pllclk = PLL_100MHZ; | ||
| 147 | ahbclk = AHB_CPUCLK_1_1; | ||
| 148 | apbclk = APB_AHB_1_2; | ||
| 149 | break; | ||
| 150 | |||
| 151 | case 120: | ||
| 152 | pllclk = PLL_120MHZ; | ||
| 153 | ahbclk = AHB_CPUCLK_1_2; | ||
| 154 | apbclk = APB_AHB_1_2; | ||
| 155 | break; | ||
| 156 | |||
| 157 | case 166: | ||
| 158 | pllclk = PLL_166MHZ; | ||
| 159 | ahbclk = AHB_CPUCLK_1_2; | ||
| 160 | apbclk = APB_AHB_1_2; | ||
| 161 | break; | ||
| 162 | |||
| 163 | case 200: | ||
| 164 | pllclk = PLL_200MHZ; | ||
| 165 | ahbclk = AHB_CPUCLK_1_2; | ||
| 166 | apbclk = APB_AHB_1_2; | ||
| 167 | break; | ||
| 168 | } | ||
| 169 | |||
| 170 | __raw_writel(pllclk, REG_PLLCON0); | ||
| 171 | |||
| 172 | val = __raw_readl(REG_CLKDIV); | ||
| 173 | val &= ~(0x03 << 24 | 0x03 << 26); | ||
| 174 | val |= (ahbclk << 24 | apbclk << 26); | ||
| 175 | __raw_writel(val, REG_CLKDIV); | ||
| 176 | |||
| 177 | return 0; | ||
| 178 | } | ||
| 179 | static int __init w90p910_set_cpufreq(char *str) | ||
| 180 | { | ||
| 181 | unsigned long cpufreq, val; | ||
| 182 | |||
| 183 | if (!*str) | ||
| 184 | return 0; | ||
| 185 | |||
| 186 | strict_strtoul(str, 0, &cpufreq); | ||
| 187 | |||
| 188 | w90p910_clock_source(NULL, "ext"); | ||
| 189 | |||
| 190 | w90p910_set_clkval(cpufreq); | ||
| 191 | |||
| 192 | mdelay(1); | ||
| 193 | |||
| 194 | val = __raw_readl(REG_CKSKEW); | ||
| 195 | val &= ~0xff; | ||
| 196 | val |= DEFAULTSKEW; | ||
| 197 | __raw_writel(val, REG_CKSKEW); | ||
| 198 | |||
| 199 | w90p910_clock_source(NULL, "pll0"); | ||
| 200 | |||
| 201 | return 1; | ||
| 202 | } | ||
| 203 | |||
| 204 | __setup("cpufreq=", w90p910_set_cpufreq); | ||
| 205 | |||
| 126 | /*Init W90P910 clock*/ | 206 | /*Init W90P910 clock*/ |
| 127 | 207 | ||
| 128 | void __init w90p910_init_clocks(void) | 208 | void __init w90p910_init_clocks(void) |
