diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/arm/mach-s3c2410 |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/arm/mach-s3c2410')
34 files changed, 7722 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig new file mode 100644 index 00000000000..534df0c6c77 --- /dev/null +++ b/arch/arm/mach-s3c2410/Kconfig @@ -0,0 +1,169 @@ +if ARCH_S3C2410 + +menu "S3C24XX Implementations" + +config ARCH_BAST + bool "Simtec Electronics BAST (EB2410ITX)" + select CPU_S3C2410 + help + Say Y here if you are using the Simtec Electronics EB2410ITX + development board (also known as BAST) + + Product page: <http://www.simtec.co.uk/products/EB2410ITX/>. + +config ARCH_H1940 + bool "IPAQ H1940" + select CPU_S3C2410 + help + Say Y here if you are using the HP IPAQ H1940 + + <http://www.handhelds.org/projects/h1940.html>. + +config MACH_N30 + bool "Acer N30" + select CPU_S3C2410 + help + Say Y here if you are using the Acer N30 + + <http://zoo.weinigel.se/n30>. + +config ARCH_SMDK2410 + bool "SMDK2410/A9M2410" + select CPU_S3C2410 + help + Say Y here if you are using the SMDK2410 or the derived module A9M2410 + <http://www.fsforth.de> + +config ARCH_S3C2440 + bool "SMDK2440" + select CPU_S3C2440 + help + Say Y here if you are using the SMDK2440. + +config MACH_VR1000 + bool "Thorcom VR1000" + select CPU_S3C2410 + help + Say Y here if you are using the Thorcom VR1000 board. + + This linux port is currently being maintained by Simtec, on behalf + of Thorcom. Any queries, please contact Thorcom first. + +config MACH_RX3715 + bool "HP iPAQ rx3715" + select CPU_S3C2440 + help + Say Y here if you are using the HP iPAQ rx3715. + + See <http://www.handhelds.org/projects/rx3715.html> for more + information on this project + +config MACH_OTOM + bool "NexVision OTOM Board" + select CPU_S3C2410 + help + Say Y here if you are using the Nex Vision OTOM board + +config MACH_NEXCODER_2440 + bool "NexVision NEXCODER 2440 Light Board" + select CPU_S3C2440 + help + Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board + +endmenu + +config CPU_S3C2410 + bool + depends on ARCH_S3C2410 + help + Support for S3C2410 and S3C2410A family from the S3C24XX line + of Samsung Mobile CPUs. + +config CPU_S3C2440 + bool + depends on ARCH_S3C2410 + help + Support for S3C2440 Samsung Mobile CPU based systems. + +comment "S3C2410 Boot" + +config S3C2410_BOOT_WATCHDOG + bool "S3C2410 Initialisation watchdog" + depends on ARCH_S3C2410 && S3C2410_WATCHDOG + help + Say y to enable the watchdog during the kernel decompression + stage. If the kernel fails to uncompress, then the watchdog + will trigger a reset and the system should restart. + + Although this uses the same hardware unit as the kernel watchdog + driver, it is not a replacement for it. If you use this option, + you will have to use the watchdg driver to either stop the timeout + or restart it. If you do not, then your kernel will reboot after + startup. + + The driver uses a fixed timeout value, so the exact time till the + system resets depends on the value of PCLK. The timeout on an + 200MHz s3c2410 should be about 30 seconds. + +comment "S3C2410 Setup" + +config S3C2410_DMA + bool "S3C2410 DMA support" + depends on ARCH_S3C2410 + help + S3C2410 DMA support. This is needed for drivers like sound which + use the S3C2410's DMA system to move data to and from the + peripheral blocks. + +config S3C2410_DMA_DEBUG + bool "S3C2410 DMA support debug" + depends on ARCH_S3C2410 && S3C2410_DMA + help + Enable debugging output for the DMA code. This option sends info + to the kernel log, at priority KERN_DEBUG. + + Note, it is easy to create and fill the log buffer in a small + amount of time, as well as using an significant percentage of + the CPU time doing so. + + +config S3C2410_PM_DEBUG + bool "S3C2410 PM Suspend debug" + depends on ARCH_S3C2410 && PM + help + Say Y here if you want verbose debugging from the PM Suspend and + Resume code. See `Documentation/arm/Samsing-S3C24XX/Suspend.txt` + for more information. + +config S3C2410_PM_CHECK + bool "S3C2410 PM Suspend Memory CRC" + depends on ARCH_S3C2410 && PM && CRC32 + help + Enable the PM code's memory area checksum over sleep. This option + will generate CRCs of all blocks of memory, and store them before + going to sleep. The blocks are then checked on resume for any + errors. + +config S3C2410_PM_CHECK_CHUNKSIZE + int "S3C2410 PM Suspend CRC Chunksize (KiB)" + depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK + default 64 + help + Set the chunksize in Kilobytes of the CRC for checking memory + corruption over suspend and resume. A smaller value will mean that + the CRC data block will take more memory, but wil identify any + faults with better precision. + +config S3C2410_LOWLEVEL_UART_PORT + int "S3C2410 UART to use for low-level messages" + default 0 + help + Choice of which UART port to use for the low-level messages, + such as the `Uncompressing...` at start time. The value of + this configuration should be between zero and two. The port + must have been initialised by the boot-loader before use. + + Note, this does not affect the port used by the debug messages, + which is a separate configuration. + +endif diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile new file mode 100644 index 00000000000..7c379aad5d6 --- /dev/null +++ b/arch/arm/mach-s3c2410/Makefile @@ -0,0 +1,36 @@ + +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := cpu.o irq.o time.o gpio.o clock.o devs.o +obj-m := +obj-n := +obj- := + +# S3C2410 support files + +obj-$(CONFIG_CPU_S3C2410) += s3c2410.o +obj-$(CONFIG_S3C2410_DMA) += dma.o + +# Power Management support + +obj-$(CONFIG_PM) += pm.o sleep.o + +# S3C2440 support + +obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o + +# machine specific support + +obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o +obj-$(CONFIG_ARCH_H1940) += mach-h1940.o +obj-$(CONFIG_MACH_N30) += mach-n30.o +obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o +obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o +obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o +obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o +obj-$(CONFIG_MACH_OTOM) += mach-otom.o +obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o diff --git a/arch/arm/mach-s3c2410/Makefile.boot b/arch/arm/mach-s3c2410/Makefile.boot new file mode 100644 index 00000000000..7dab2a0325b --- /dev/null +++ b/arch/arm/mach-s3c2410/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x30008000 +params_phys-y := 0x30000100 + diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c new file mode 100644 index 00000000000..5e5bbe893cb --- /dev/null +++ b/arch/arm/mach-s3c2410/bast-irq.c @@ -0,0 +1,132 @@ +/* linux/arch/arm/mach-s3c2410/bast-irq.c + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * http://www.simtec.co.uk/products/EB2410ITX/ + * + * 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 + * + * Modifications: + * 08-Jan-2003 BJD Moved from central IRQ code + */ + + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/ioport.h> +#include <linux/ptrace.h> +#include <linux/sysdev.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/mach/irq.h> +#include <asm/hardware/s3c2410/irq.h> + +#if 0 +#include <asm/debug-ll.h> +#endif + +#define irqdbf(x...) +#define irqdbf2(x...) + + +/* handle PC104 ISA interrupts from the system CPLD */ + +/* table of ISA irq nos to the relevant mask... zero means + * the irq is not implemented +*/ +static unsigned char bast_pc104_irqmasks[] = { + 0, /* 0 */ + 0, /* 1 */ + 0, /* 2 */ + 1, /* 3 */ + 0, /* 4 */ + 2, /* 5 */ + 0, /* 6 */ + 4, /* 7 */ + 0, /* 8 */ + 0, /* 9 */ + 8, /* 10 */ + 0, /* 11 */ + 0, /* 12 */ + 0, /* 13 */ + 0, /* 14 */ + 0, /* 15 */ +}; + +static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 }; + +static void +bast_pc104_mask(unsigned int irqno) +{ + unsigned long temp; + + temp = __raw_readb(BAST_VA_PC104_IRQMASK); + temp &= ~bast_pc104_irqmasks[irqno]; + __raw_writeb(temp, BAST_VA_PC104_IRQMASK); + + if (temp == 0) + bast_extint_mask(IRQ_ISA); +} + +static void +bast_pc104_ack(unsigned int irqno) +{ + bast_extint_ack(IRQ_ISA); +} + +static void +bast_pc104_unmask(unsigned int irqno) +{ + unsigned long temp; + + temp = __raw_readb(BAST_VA_PC104_IRQMASK); + temp |= bast_pc104_irqmasks[irqno]; + __raw_writeb(temp, BAST_VA_PC104_IRQMASK); + + bast_extint_unmask(IRQ_ISA); +} + +static struct bast_pc104_chip = { + .mask = bast_pc104_mask, + .unmask = bast_pc104_unmask, + .ack = bast_pc104_ack +}; + +static void +bast_irq_pc104_demux(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned int stat; + unsigned int irqno; + int i; + + stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf; + + for (i = 0; i < 4 && stat != 0; i++) { + if (stat & 1) { + irqno = bast_pc104_irqs[i]; + desc = irq_desc + irqno; + + desc->handle(irqno, desc, regs); + } + + stat >>= 1; + } +} diff --git a/arch/arm/mach-s3c2410/bast.h b/arch/arm/mach-s3c2410/bast.h new file mode 100644 index 00000000000..e5d03311752 --- /dev/null +++ b/arch/arm/mach-s3c2410/bast.h @@ -0,0 +1,2 @@ + +extern void bast_init_irq(void); diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c new file mode 100644 index 00000000000..e23f534d4e1 --- /dev/null +++ b/arch/arm/mach-s3c2410/clock.c @@ -0,0 +1,507 @@ +/* linux/arch/arm/mach-s3c2410/clock.c + * + * Copyright (c) 2004-2005 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2410 Clock control support + * + * Based on, and code from linux/arch/arm/mach-versatile/clock.c + ** + ** Copyright (C) 2004 ARM Limited. + ** Written by Deep Blue Solutions Limited. + * + * + * 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/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/device.h> +#include <linux/sysdev.h> + +#include <linux/interrupt.h> +#include <linux/ioport.h> + +#include <asm/hardware.h> +#include <asm/atomic.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include <asm/hardware/clock.h> +#include <asm/arch/regs-clock.h> + +#include "clock.h" +#include "cpu.h" + +/* clock information */ + +static LIST_HEAD(clocks); +static DECLARE_MUTEX(clocks_sem); + +/* old functions */ + +void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable) +{ + unsigned long clkcon; + unsigned long flags; + + local_irq_save(flags); + + clkcon = __raw_readl(S3C2410_CLKCON); + clkcon &= ~clocks; + + if (enable) + clkcon |= clocks; + + /* ensure none of the special function bits set */ + clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER); + + __raw_writel(clkcon, S3C2410_CLKCON); + + local_irq_restore(flags); +} + +/* enable and disable calls for use with the clk struct */ + +static int clk_null_enable(struct clk *clk, int enable) +{ + return 0; +} + +int s3c24xx_clkcon_enable(struct clk *clk, int enable) +{ + s3c24xx_clk_enable(clk->ctrlbit, enable); + return 0; +} + +/* Clock API calls */ + +struct clk *clk_get(struct device *dev, const char *id) +{ + struct clk *p; + struct clk *clk = ERR_PTR(-ENOENT); + int idno; + + idno = (dev == NULL) ? -1 : to_platform_device(dev)->id; + + down(&clocks_sem); + + list_for_each_entry(p, &clocks, list) { + if (p->id == idno && + strcmp(id, p->name) == 0 && + try_module_get(p->owner)) { + clk = p; + break; + } + } + + /* check for the case where a device was supplied, but the + * clock that was being searched for is not device specific */ + + if (IS_ERR(clk)) { + list_for_each_entry(p, &clocks, list) { + if (p->id == -1 && strcmp(id, p->name) == 0 && + try_module_get(p->owner)) { + clk = p; + break; + } + } + } + + up(&clocks_sem); + return clk; +} + +void clk_put(struct clk *clk) +{ + module_put(clk->owner); +} + +int clk_enable(struct clk *clk) +{ + if (IS_ERR(clk)) + return -EINVAL; + + return (clk->enable)(clk, 1); +} + +void clk_disable(struct clk *clk) +{ + if (!IS_ERR(clk)) + (clk->enable)(clk, 0); +} + + +int clk_use(struct clk *clk) +{ + atomic_inc(&clk->used); + return 0; +} + + +void clk_unuse(struct clk *clk) +{ + atomic_dec(&clk->used); +} + +unsigned long clk_get_rate(struct clk *clk) +{ + if (IS_ERR(clk)) + return 0; + + if (clk->rate != 0) + return clk->rate; + + while (clk->parent != NULL && clk->rate == 0) + clk = clk->parent; + + return clk->rate; +} + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + return rate; +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return -EINVAL; +} + +struct clk *clk_get_parent(struct clk *clk) +{ + return clk->parent; +} + +EXPORT_SYMBOL(clk_get); +EXPORT_SYMBOL(clk_put); +EXPORT_SYMBOL(clk_enable); +EXPORT_SYMBOL(clk_disable); +EXPORT_SYMBOL(clk_use); +EXPORT_SYMBOL(clk_unuse); +EXPORT_SYMBOL(clk_get_rate); +EXPORT_SYMBOL(clk_round_rate); +EXPORT_SYMBOL(clk_set_rate); +EXPORT_SYMBOL(clk_get_parent); + +/* base clocks */ + +static struct clk clk_xtal = { + .name = "xtal", + .id = -1, + .rate = 0, + .parent = NULL, + .ctrlbit = 0, +}; + +static struct clk clk_f = { + .name = "fclk", + .id = -1, + .rate = 0, + .parent = NULL, + .ctrlbit = 0, +}; + +static struct clk clk_h = { + .name = "hclk", + .id = -1, + .rate = 0, + .parent = NULL, + .ctrlbit = 0, +}; + +static struct clk clk_p = { + .name = "pclk", + .id = -1, + .rate = 0, + .parent = NULL, + .ctrlbit = 0, +}; + +/* clocks that could be registered by external code */ + +struct clk s3c24xx_dclk0 = { + .name = "dclk0", + .id = -1, +}; + +struct clk s3c24xx_dclk1 = { + .name = "dclk1", + .id = -1, +}; + +struct clk s3c24xx_clkout0 = { + .name = "clkout0", + .id = -1, +}; + +struct clk s3c24xx_clkout1 = { + .name = "clkout1", + .id = -1, +}; + +struct clk s3c24xx_uclk = { + .name = "uclk", + .id = -1, +}; + + +/* clock definitions */ + +static struct clk init_clocks[] = { + { .name = "nand", + .id = -1, + .parent = &clk_h, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_NAND + }, + { .name = "lcd", + .id = -1, + .parent = &clk_h, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_LCDC + }, + { .name = "usb-host", + .id = -1, + .parent = &clk_h, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_USBH + }, + { .name = "usb-device", + .id = -1, + .parent = &clk_h, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_USBD + }, + { .name = "timers", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_PWMT + }, + { .name = "sdi", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_SDI + }, + { .name = "uart", + .id = 0, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_UART0 + }, + { .name = "uart", + .id = 1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_UART1 + }, + { .name = "uart", + .id = 2, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_UART2 + }, + { .name = "gpio", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_GPIO + }, + { .name = "rtc", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_RTC + }, + { .name = "adc", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_ADC + }, + { .name = "i2c", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_IIC + }, + { .name = "iis", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_IIS + }, + { .name = "spi", + .id = -1, + .parent = &clk_p, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2410_CLKCON_SPI + }, + { .name = "watchdog", + .id = -1, + .parent = &clk_p, + .ctrlbit = 0 + } +}; + +/* initialise the clock system */ + +int s3c24xx_register_clock(struct clk *clk) +{ + clk->owner = THIS_MODULE; + atomic_set(&clk->used, 0); + + if (clk->enable == NULL) + clk->enable = clk_null_enable; + + /* add to the list of available clocks */ + + down(&clocks_sem); + list_add(&clk->list, &clocks); + up(&clocks_sem); + + return 0; +} + +/* initalise all the clocks */ + +int __init s3c24xx_setup_clocks(unsigned long xtal, + unsigned long fclk, + unsigned long hclk, + unsigned long pclk) +{ + struct clk *clkp = init_clocks; + int ptr; + int ret; + + printk(KERN_INFO "S3C2410 Clocks, (c) 2004 Simtec Electronics\n"); + + /* initialise the main system clocks */ + + clk_xtal.rate = xtal; + + clk_h.rate = hclk; + clk_p.rate = pclk; + clk_f.rate = fclk; + + /* it looks like just setting the register here is not good + * enough, and causes the odd hang at initial boot time, so + * do all of them indivdually. + * + * I think disabling the LCD clock if the LCD is active is + * very dangerous, and therefore the bootloader should be + * careful to not enable the LCD clock if it is not needed. + * + * and of course, this looks neater + */ + + s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_ADC, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0); + s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0); + + /* assume uart clocks are correctly setup */ + + /* register our clocks */ + + if (s3c24xx_register_clock(&clk_xtal) < 0) + printk(KERN_ERR "failed to register master xtal\n"); + + if (s3c24xx_register_clock(&clk_f) < 0) + printk(KERN_ERR "failed to register cpu fclk\n"); + + if (s3c24xx_register_clock(&clk_h) < 0) + printk(KERN_ERR "failed to register cpu hclk\n"); + + if (s3c24xx_register_clock(&clk_p) < 0) + printk(KERN_ERR "failed to register cpu pclk\n"); + + /* register clocks from clock array */ + + for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { + ret = s3c24xx_register_clock(clkp); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + } + + return 0; +} + +/* S3C2440 extended clock support */ + +#ifdef CONFIG_CPU_S3C2440 + +static struct clk s3c2440_clk_upll = { + .name = "upll", + .id = -1, +}; + +static struct clk s3c2440_clk_cam = { + .name = "camif", + .parent = &clk_h, + .id = -1, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2440_CLKCON_CAMERA, +}; + +static struct clk s3c2440_clk_ac97 = { + .name = "ac97", + .parent = &clk_p, + .id = -1, + .enable = s3c24xx_clkcon_enable, + .ctrlbit = S3C2440_CLKCON_CAMERA, +}; + +static int s3c2440_clk_add(struct sys_device *sysdev) +{ + unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); + + s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate) * 2; + + printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n", + print_mhz(s3c2440_clk_upll.rate)); + + s3c24xx_register_clock(&s3c2440_clk_ac97); + s3c24xx_register_clock(&s3c2440_clk_cam); + s3c24xx_register_clock(&s3c2440_clk_upll); + + clk_disable(&s3c2440_clk_ac97); + clk_disable(&s3c2440_clk_cam); + + return 0; +} + +static struct sysdev_driver s3c2440_clk_driver = { + .add = s3c2440_clk_add, +}; + +static int s3c24xx_clk_driver(void) +{ + return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver); +} + +arch_initcall(s3c24xx_clk_driver); + +#endif /* CONFIG_CPU_S3C2440 */ diff --git a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h new file mode 100644 index 00000000000..7953b6f397b --- /dev/null +++ b/arch/arm/mach-s3c2410/clock.h @@ -0,0 +1,44 @@ +/* + * linux/arch/arm/mach-s3c2410/clock.h + * + * Copyright (c) 2004-2005 Simtec Electronics + * http://www.simtec.co.uk/products/SWLINUX/ + * Written by Ben Dooks, <ben@simtec.co.uk> + * + * 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. +*/ + +struct clk { + struct list_head list; + struct module *owner; + struct clk *parent; + const char *name; + int id; + atomic_t used; + unsigned long rate; + unsigned long ctrlbit; + int (*enable)(struct clk *, int enable); +}; + +/* other clocks which may be registered by board support */ + +extern struct clk s3c24xx_dclk0; +extern struct clk s3c24xx_dclk1; +extern struct clk s3c24xx_clkout0; +extern struct clk s3c24xx_clkout1; +extern struct clk s3c24xx_uclk; + +/* exports for arch/arm/mach-s3c2410 + * + * Please DO NOT use these outside of arch/arm/mach-s3c2410 +*/ + +extern int s3c24xx_clkcon_enable(struct clk *clk, int enable); +extern int s3c24xx_register_clock(struct clk *clk); + +extern int s3c24xx_setup_clocks(unsigned long xtal, + unsigned long fclk, + unsigned long hclk, + unsigned long pclk); diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c new file mode 100644 index 00000000000..ca366e9e264 --- /dev/null +++ b/arch/arm/mach-s3c2410/cpu.c @@ -0,0 +1,241 @@ < |