diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 17:48:14 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-14 17:48:14 -0700 |
commit | 2ca7d674d7ab2220707b2ada0b690c0e7c95e7ac (patch) | |
tree | 9c0927ed1d540e5fd704c1f82689870786514655 /arch/arm/mach-s3c2410 | |
parent | 2195d2818c37bdf263865f1e9effccdd9fc5f9d4 (diff) | |
parent | 87d721ad7a37b7650dd710c88dd5c6a5bf9fe996 (diff) |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (257 commits)
[ARM] Update mach-types
ARM: 5636/1: Move vendor enum to AMBA include
ARM: Fix pfn_valid() for sparse memory
[ARM] orion5x: Add LaCie NAS 2Big Network support
[ARM] pxa/sharpsl_pm: zaurus c3000 aka spitz: fix resume
ARM: 5686/1: at91: Correct AC97 reset line in at91sam9263ek board
ARM: 5640/1: This patch modifies the support of AC97 on the at91sam9263 ek board
ARM: 5689/1: Update default config of HP Jornada 700-series machines
ARM: 5691/1: fix cache aliasing issues between kmap() and kmap_atomic() with highmem
ARM: 5688/1: ks8695_serial: disable_irq() lockup
ARM: 5687/1: fix an oops with highmem
ARM: 5684/1: Add nuc960 platform to w90x900
ARM: 5683/1: Add nuc950 platform to w90x900
ARM: 5682/1: Add cpu.c and dev.c and modify some files of w90p910 platform
ARM: 5626/1: add suspend/resume functions to amba-pl011 serial driver
ARM: 5625/1: fix hard coded 4K resource size in amba bus detection
MMC: MMCI: convert realview MMC to use gpiolib
ARM: 5685/1: Make MMCI driver compile without gpiolib
ARM: implement highpte
ARM: Show FIQ in /proc/interrupts on CONFIG_FIQ
...
Fix up trivial conflict in arch/arm/kernel/signal.c.
It was due to the TIF_NOTIFY_RESUME addition in commit d0420c83f ("KEYS:
Extend TIF_NOTIFY_RESUME to (almost) all architectures") and follow-ups.
Diffstat (limited to 'arch/arm/mach-s3c2410')
-rw-r--r-- | arch/arm/mach-s3c2410/Kconfig | 18 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/cpu-freq.c | 159 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/dma.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/include/mach/irqs.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/include/mach/map.h | 8 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/include/mach/regs-gpio.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/include/mach/regs-mem.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h | 23 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/include/mach/spi.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/irq.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/mach-bast.c | 41 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/pll.c | 95 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/pm.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/s3c2410.c | 29 |
15 files changed, 432 insertions, 4 deletions
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 41bb65d5b91..d8c023d4df3 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -12,6 +12,7 @@ config CPU_S3C2410 select S3C2410_GPIO select CPU_LLSERIAL_S3C2410 select S3C2410_PM if PM + select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX help Support for S3C2410 and S3C2410A family from the S3C24XX line of Samsung Mobile CPUs. @@ -45,6 +46,22 @@ config MACH_BAST_IDE Internal node for machines with an BAST style IDE interface +# cpu frequency scaling support + +config S3C2410_CPUFREQ + bool + depends on CPU_FREQ_S3C24XX && CPU_S3C2410 + select S3C2410_CPUFREQ_UTILS + help + CPU Frequency scaling support for S3C2410 + +config S3C2410_PLLTABLE + bool + depends on S3C2410_CPUFREQ && CPU_FREQ_S3C24XX_PLL + default y + help + Select the PLL table for the S3C2410 + menu "S3C2410 Machines" config ARCH_SMDK2410 @@ -79,6 +96,7 @@ config MACH_N30 config ARCH_BAST bool "Simtec Electronics BAST (EB2410ITX)" select CPU_S3C2410 + select S3C2410_IOTIMING if S3C2410_CPUFREQ select PM_SIMTEC if PM select SIMTEC_NOR select MACH_BAST_IDE diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index fca02f82711..2ab5ba4b266 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -15,6 +15,8 @@ obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o obj-$(CONFIG_S3C2410_GPIO) += gpio.o +obj-$(CONFIG_S3C2410_CPUFREQ) += cpu-freq.o +obj-$(CONFIG_S3C2410_PLLTABLE) += pll.o # Machine support diff --git a/arch/arm/mach-s3c2410/cpu-freq.c b/arch/arm/mach-s3c2410/cpu-freq.c new file mode 100644 index 00000000000..9d1186877d0 --- /dev/null +++ b/arch/arm/mach-s3c2410/cpu-freq.c @@ -0,0 +1,159 @@ +/* linux/arch/arm/mach-s3c2410/cpu-freq.c + * + * Copyright (c) 2006,2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2410 CPU Frequency scaling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/cpufreq.h> +#include <linux/sysdev.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/io.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include <mach/regs-clock.h> + +#include <plat/cpu.h> +#include <plat/clock.h> +#include <plat/cpu-freq-core.h> + +/* Note, 2410A has an extra mode for 1:4:4 ratio, bit 2 of CLKDIV */ + +static void s3c2410_cpufreq_setdivs(struct s3c_cpufreq_config *cfg) +{ + u32 clkdiv = 0; + + if (cfg->divs.h_divisor == 2) + clkdiv |= S3C2410_CLKDIVN_HDIVN; + + if (cfg->divs.p_divisor != cfg->divs.h_divisor) + clkdiv |= S3C2410_CLKDIVN_PDIVN; + + __raw_writel(clkdiv, S3C2410_CLKDIVN); +} + +static int s3c2410_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) +{ + unsigned long hclk, fclk, pclk; + unsigned int hdiv, pdiv; + unsigned long hclk_max; + + fclk = cfg->freq.fclk; + hclk_max = cfg->max.hclk; + + cfg->freq.armclk = fclk; + + s3c_freq_dbg("%s: fclk is %lu, max hclk %lu\n", + __func__, fclk, hclk_max); + + hdiv = (fclk > cfg->max.hclk) ? 2 : 1; + hclk = fclk / hdiv; + + if (hclk > cfg->max.hclk) { + s3c_freq_dbg("%s: hclk too big\n", __func__); + return -EINVAL; + } + + pdiv = (hclk > cfg->max.pclk) ? 2 : 1; + pclk = hclk / pdiv; + + if (pclk > cfg->max.pclk) { + s3c_freq_dbg("%s: pclk too big\n", __func__); + return -EINVAL; + } + + pdiv *= hdiv; + + /* record the result */ + cfg->divs.p_divisor = pdiv; + cfg->divs.h_divisor = hdiv; + + return 0 ; +} + +static struct s3c_cpufreq_info s3c2410_cpufreq_info = { + .max = { + .fclk = 200000000, + .hclk = 100000000, + .pclk = 50000000, + }, + + /* transition latency is about 5ms worst-case, so + * set 10ms to be sure */ + .latency = 10000000, + + .locktime_m = 150, + .locktime_u = 150, + .locktime_bits = 12, + + .need_pll = 1, + + .name = "s3c2410", + .calc_iotiming = s3c2410_iotiming_calc, + .set_iotiming = s3c2410_iotiming_set, + .get_iotiming = s3c2410_iotiming_get, + .resume_clocks = s3c2410_setup_clocks, + + .set_fvco = s3c2410_set_fvco, + .set_refresh = s3c2410_cpufreq_setrefresh, + .set_divs = s3c2410_cpufreq_setdivs, + .calc_divs = s3c2410_cpufreq_calcdivs, + + .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs), +}; + +static int s3c2410_cpufreq_add(struct sys_device *sysdev) +{ + return s3c_cpufreq_register(&s3c2410_cpufreq_info); +} + +static struct sysdev_driver s3c2410_cpufreq_driver = { + .add = s3c2410_cpufreq_add, +}; + +static int __init s3c2410_cpufreq_init(void) +{ + return sysdev_driver_register(&s3c2410_sysclass, + &s3c2410_cpufreq_driver); +} + +arch_initcall(s3c2410_cpufreq_init); + +static int s3c2410a_cpufreq_add(struct sys_device *sysdev) +{ + /* alter the maximum freq settings for S3C2410A. If a board knows + * it only has a maximum of 200, then it should register its own + * limits. */ + + s3c2410_cpufreq_info.max.fclk = 266000000; + s3c2410_cpufreq_info.max.hclk = 133000000; + s3c2410_cpufreq_info.max.pclk = 66500000; + s3c2410_cpufreq_info.name = "s3c2410a"; + + return s3c2410_cpufreq_add(sysdev); +} + +static struct sysdev_driver s3c2410a_cpufreq_driver = { + .add = s3c2410a_cpufreq_add, +}; + +static int __init s3c2410a_cpufreq_init(void) +{ + return sysdev_driver_register(&s3c2410a_sysclass, + &s3c2410a_cpufreq_driver); +} + +arch_initcall(s3c2410a_cpufreq_init); diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index dbf96e60d99..63b753f56c6 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c @@ -164,6 +164,17 @@ static int __init s3c2410_dma_drvinit(void) } arch_initcall(s3c2410_dma_drvinit); + +static struct sysdev_driver s3c2410a_dma_driver = { + .add = s3c2410_dma_add, +}; + +static int __init s3c2410a_dma_drvinit(void) +{ + return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_dma_driver); +} + +arch_initcall(s3c2410a_dma_drvinit); #endif #if defined(CONFIG_CPU_S3C2442) diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h index 2a2384ffa7b..6c12c6312ad 100644 --- a/arch/arm/mach-s3c2410/include/mach/irqs.h +++ b/arch/arm/mach-s3c2410/include/mach/irqs.h @@ -164,6 +164,12 @@ #define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3 #define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3 +#ifdef CONFIG_CPU_S3C2440 +#define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97 +#else +#define IRQ_S3C244x_AC97 IRQ_S3C2443_AC97 +#endif + /* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */ #define FIQ_START IRQ_EINT0 diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h index e99b212cb1c..b049e61460b 100644 --- a/arch/arm/mach-s3c2410/include/mach/map.h +++ b/arch/arm/mach-s3c2410/include/mach/map.h @@ -67,6 +67,13 @@ #define S3C2443_PA_HSMMC (0x4A800000) #define S3C2443_SZ_HSMMC (256) +/* S3C2412 memory and IO controls */ +#define S3C2412_PA_SSMC (0x4F000000) +#define S3C2412_VA_SSMC S3C_ADDR_CPU(0x00000000) + +#define S3C2412_PA_EBI (0x48800000) +#define S3C2412_VA_EBI S3C_ADDR_CPU(0x00010000) + /* physical addresses of all the chip-select areas */ #define S3C2410_CS0 (0x00000000) @@ -103,5 +110,6 @@ #define S3C_PA_UART S3C24XX_PA_UART #define S3C_PA_USBHOST S3C2410_PA_USBHOST #define S3C_PA_HSMMC0 S3C2443_PA_HSMMC +#define S3C_PA_NAND S3C24XX_PA_NAND #endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h index b278d0c45cc..f6e8eec879c 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h @@ -328,13 +328,15 @@ #define S3C2410_GPD8_VD16 (0x02 << 16) #define S3C2400_GPD8_TOUT3 (0x02 << 16) +#define S3C2440_GPD8_SPIMISO1 (0x03 << 16) #define S3C2410_GPD9_VD17 (0x02 << 18) #define S3C2400_GPD9_TCLK0 (0x02 << 18) -#define S3C2410_GPD9_MASK (0x03 << 18) +#define S3C2440_GPD9_SPIMOSI1 (0x03 << 18) #define S3C2410_GPD10_VD18 (0x02 << 20) #define S3C2400_GPD10_nWAIT (0x02 << 20) +#define S3C2440_GPD10_SPICLK1 (0x03 << 20) #define S3C2410_GPD11_VD19 (0x02 << 22) diff --git a/arch/arm/mach-s3c2410/include/mach/regs-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-mem.h index 57759804e2f..7f7c5294796 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-mem.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-mem.h @@ -73,6 +73,16 @@ #define S3C2410_BWSCON_WS7 (1<<30) #define S3C2410_BWSCON_ST7 (1<<31) +/* accesor functions for getting BANK(n) configuration. (n != 0) */ + +#define S3C2410_BWSCON_GET(_bwscon, _bank) (((_bwscon) >> ((_bank) * 4)) & 0xf) + +#define S3C2410_BWSCON_DW8 (0) +#define S3C2410_BWSCON_DW16 (1) +#define S3C2410_BWSCON_DW32 (2) +#define S3C2410_BWSCON_WS (1 << 2) +#define S3C2410_BWSCON_ST (1 << 3) + /* memory set (rom, ram) */ #define S3C2410_BANKCON0 S3C2410_MEMREG(0x0004) #define S3C2410_BANKCON1 S3C2410_MEMREG(0x0008) diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h index a4bf2712317..fb635251509 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h @@ -14,9 +14,11 @@ #ifndef __ASM_ARM_REGS_S3C2412_MEM #define __ASM_ARM_REGS_S3C2412_MEM -#ifndef S3C2412_MEMREG #define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x)) -#endif +#define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x)) + +#define S3C2412_SSMCREG(x) (S3C2412_VA_SSMC + (x)) +#define S3C2412_SSMC(x, o) (S3C2412_SSMCREG((x * 0x20) + (o))) #define S3C2412_BANKCFG S3C2412_MEMREG(0x00) #define S3C2412_BANKCON1 S3C2412_MEMREG(0x04) @@ -26,4 +28,21 @@ #define S3C2412_REFRESH S3C2412_MEMREG(0x10) #define S3C2412_TIMEOUT S3C2412_MEMREG(0x14) +/* EBI control registers */ + +#define S3C2412_EBI_PR S3C2412_EBIREG(0x00) +#define S3C2412_EBI_BANKCFG S3C2412_EBIREG(0x04) + +/* SSMC control registers */ + +#define S3C2412_SSMC_BANK(x) S3C2412_SSMC(x, 0x00) +#define S3C2412_SMIDCYR(x) S3C2412_SSMC(x, 0x00) +#define S3C2412_SMBWSTRD(x) S3C2412_SSMC(x, 0x04) +#define S3C2412_SMBWSTWRR(x) S3C2412_SSMC(x, 0x08) +#define S3C2412_SMBWSTOENR(x) S3C2412_SSMC(x, 0x0C) +#define S3C2412_SMBWSTWENR(x) S3C2412_SSMC(x, 0x10) +#define S3C2412_SMBCR(x) S3C2412_SSMC(x, 0x14) +#define S3C2412_SMBSR(x) S3C2412_SSMC(x, 0x18) +#define S3C2412_SMBWSTBRDR(x) S3C2412_SSMC(x, 0x1C) + #endif /* __ASM_ARM_REGS_S3C2412_MEM */ diff --git a/arch/arm/mach-s3c2410/include/mach/spi.h b/arch/arm/mach-s3c2410/include/mach/spi.h index 1d300fb112b..193b39d654e 100644 --- a/arch/arm/mach-s3c2410/include/mach/spi.h +++ b/arch/arm/mach-s3c2410/include/mach/spi.h @@ -30,4 +30,7 @@ extern void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi, extern void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi, int enable); +extern void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi, + int enable); + #endif /* __ASM_ARCH_SPI_H */ diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index 92150399563..5e2f3533205 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -39,9 +39,22 @@ static struct sysdev_driver s3c2410_irq_driver = { .resume = s3c24xx_irq_resume, }; -static int s3c2410_irq_init(void) +static int __init s3c2410_irq_init(void) { return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver); } arch_initcall(s3c2410_irq_init); + +static struct sysdev_driver s3c2410a_irq_driver = { + .add = s3c2410_irq_add, + .suspend = s3c24xx_irq_suspend, + .resume = s3c24xx_irq_resume, +}; + +static int __init s3c2410a_irq_init(void) +{ + return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_irq_driver); +} + +arch_initcall(s3c2410a_irq_init); diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index ce3baba2cd7..647c9adb018 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -45,6 +45,7 @@ #include <mach/regs-mem.h> #include <mach/regs-lcd.h> +#include <plat/hwmon.h> #include <plat/nand.h> #include <plat/iic.h> #include <mach/fb.h> @@ -59,6 +60,7 @@ #include <plat/clock.h> #include <plat/devs.h> #include <plat/cpu.h> +#include <plat/cpu-freq.h> #include "usb-simtec.h" #include "nor-simtec.h" @@ -547,7 +549,35 @@ static struct i2c_board_info bast_i2c_devs[] __initdata = { }, }; +static struct s3c_hwmon_pdata bast_hwmon_info = { + /* LCD contrast (0-6.6V) */ + .in[0] = &(struct s3c_hwmon_chcfg) { + .name = "lcd-contrast", + .mult = 3300, + .div = 512, + }, + /* LED current feedback */ + .in[1] = &(struct s3c_hwmon_chcfg) { + .name = "led-feedback", + .mult = 3300, + .div = 1024, + }, + /* LCD feedback (0-6.6V) */ + .in[2] = &(struct s3c_hwmon_chcfg) { + .name = "lcd-feedback", + .mult = 3300, + .div = 512, + }, + /* Vcore (1.8-2.0V), Vref 3.3V */ + .in[3] = &(struct s3c_hwmon_chcfg) { + .name = "vcore", + .mult = 3300, + .div = 1024, + }, +}; + /* Standard BAST devices */ +// cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0 static struct platform_device *bast_devices[] __initdata = { &s3c_device_usb, @@ -556,6 +586,8 @@ static struct platform_device *bast_devices[] __initdata = { &s3c_device_i2c0, &s3c_device_rtc, &s3c_device_nand, + &s3c_device_adc, + &s3c_device_hwmon, &bast_device_dm9k, &bast_device_asix, &bast_device_axpp, @@ -570,6 +602,12 @@ static struct clk *bast_clocks[] __initdata = { &s3c24xx_uclk, }; +static struct s3c_cpufreq_board __initdata bast_cpufreq = { + .refresh = 7800, /* 7.8usec */ + .auto_io = 1, + .need_io = 1, +}; + static void __init bast_map_io(void) { /* initialise the clocks */ @@ -588,6 +626,7 @@ static void __init bast_map_io(void) s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); s3c_device_nand.dev.platform_data = &bast_nand_info; + s3c_device_hwmon.dev.platform_data = &bast_hwmon_info; s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); s3c24xx_init_clocks(0); @@ -608,6 +647,8 @@ static void __init bast_init(void) usb_simtec_init(); nor_simtec_init(); + + s3c_cpufreq_setboard(&bast_cpufreq); } MACHINE_START(BAST, "Simtec-BAST") diff --git a/arch/arm/mach-s3c2410/pll.c b/arch/arm/mach-s3c2410/pll.c new file mode 100644 index 00000000000..f178c2fd9d8 --- /dev/null +++ b/arch/arm/mach-s3c2410/pll.c @@ -0,0 +1,95 @@ +/* arch/arm/mach-s3c2410/pll.c + * + * Copyright (c) 2006,2007 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks <ben@simtec.co.uk> + * Vincent Sanders <vince@arm.linux.org.uk> + * + * S3C2410 CPU PLL tables + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sysdev.h> +#include <linux/list.h> +#include <linux/clk.h> +#include <linux/err.h> + +#include <plat/cpu.h> +#include <plat/cpu-freq-core.h> + +static struct cpufreq_frequency_table pll_vals_12MHz[] = { + { .frequency = 34000000, .index = PLLVAL(82, 2, 3), }, + { .frequency = 45000000, .index = PLLVAL(82, 1, 3), }, + { .frequency = 51000000, .index = PLLVAL(161, 3, 3), }, + { .frequency = 48000000, .index = PLLVAL(120, 2, 3), }, + { .frequency = 56000000, .index = PLLVAL(142, 2, 3), }, + { .frequency = 68000000, .index = PLLVAL(82, 2, 2), }, + { .frequency = 79000000, .index = PLLVAL(71, 1, 2), }, + { .frequency = 85000000, .index = PLLVAL(105, 2, 2), }, + { .frequency = 90000000, .index = PLLVAL(112, 2, 2), }, + { .frequency = 101000000, .index = PLLVAL(127, 2, 2), }, + { .frequency = 113000000, .index = PLLVAL(105, 1, 2), }, + { .frequency = 118000000, .index = PLLVAL(150, 2, 2), }, + { .frequency = 124000000, .index = PLLVAL(116, 1, 2), }, + { .frequency = 135000000, .index = PLLVAL(82, 2, 1), }, + { .frequency = 147000000, .index = PLLVAL(90, 2, 1), }, + { .frequency = 152000000, .index = PLLVAL(68, 1, 1), }, + { .frequency = 158000000, .index = PLLVAL(71, 1, 1), }, + { .frequency = 170000000, .index = PLLVAL(77, 1, 1), }, + { .frequency = 180000000, .index = PLLVAL(82, 1, 1), }, + { .frequency = 186000000, .index = PLLVAL(85, 1, 1), }, + { .frequency = 192000000, .index = PLLVAL(88, 1, 1), }, + { .frequency = 203000000, .index = PLLVAL(161, 3, 1), }, + + /* 2410A extras */ + + { .frequency = 210000000, .index = PLLVAL(132, 2, 1), }, + { .frequency = 226000000, .index = PLLVAL(105, 1, 1), }, + { .frequency = 266000000, .index = PLLVAL(125, 1, 1), }, + { .frequency = 268000000, .index = PLLVAL(126, 1, 1), }, + { .frequency = 270000000, .index = PLLVAL(127, 1, 1), }, +}; + +static int s3c2410_plls_add(struct sys_device *dev) +{ + return s3c_plltab_register(pll_vals_12MHz, ARRAY_SIZE(pll_vals_12MHz)); +} + +static struct sysdev_driver s3c2410_plls_drv = { + .add = s3c2410_plls_add, +}; + +static int __init s3c2410_pll_init(void) +{ + return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_plls_drv); + +} + +arch_initcall(s3c2410_pll_init); + +static struct sysdev_driver s3c2410a_plls_drv = { + .add = s3c2410_plls_add, +}; + +static int __init s3c2410a_pll_init(void) +{ + return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_plls_drv); +} + +arch_initcall(s3c2410a_pll_init); diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c index 143e08a599d..966119c8efe 100644 --- a/arch/arm/mach-s3c2410/pm.c +++ b/arch/arm/mach-s3c2410/pm.c @@ -119,6 +119,18 @@ static int __init s3c2410_pm_drvinit(void) } arch_initcall(s3c2410_pm_drvinit); + +static struct sysdev_driver s3c2410a_pm_driver = { + .add = s3c2410_pm_add, + .resume = s3c2410_pm_resume, +}; + +static int __init s3c2410a_pm_drvinit(void) +{ + return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_pm_driver); +} + +arch_initcall(s3c2410a_pm_drvinit); #endif #if defined(CONFIG_CPU_S3C2440) diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c index feb141b1f91..91ba42f688a 100644 --- a/arch/arm/mach-s3c2410/s3c2410.c +++ b/arch/arm/mach-s3c2410/s3c2410.c @@ -105,17 +105,33 @@ void __init_or_cpufreq s3c2410_setup_clocks(void) s3c24xx_setup_clocks(fclk, hclk, pclk); } +/* fake ARMCLK for use with cpufreq, etc. */ + +static struct clk s3c2410_armclk = { + .name = "armclk", + .parent = &clk_f, + .id = -1, +}; + void __init s3c2410_init_clocks(int xtal) { s3c24xx_register_baseclocks(xtal); s3c2410_setup_clocks(); s3c2410_baseclk_add(); + s3c24xx_register_clock(&s3c2410_armclk); } struct sysdev_class s3c2410_sysclass = { .name = "s3c2410-core", }; +/* Note, we would have liked to name this s3c2410-core, but we cannot + * register two sysdev_class with the same name. + */ +struct sysdev_class s3c2410a_sysclass = { + .name = "s3c2410a-core", +}; + static struct sys_device s3c2410_sysdev = { .cls = &s3c2410_sysclass, }; @@ -133,9 +149,22 @@ static int __init s3c2410_core_init(void) core_initcall(s3c2410_core_init); +static int __init s3c2410a_core_init(void) +{ + return sysdev_class_register(&s3c2410a_sysclass); +} + +core_initcall(s3c2410a_core_init); + int __init s3c2410_init(void) { printk("S3C2410: Initialising architecture\n"); return sysdev_register(&s3c2410_sysdev); } + +int __init s3c2410a_init(void) +{ + s3c2410_sysdev.cls = &s3c2410a_sysclass; + return s3c2410_init(); +} |