227 lines
4.7 KiB
C

/* linux/arch/arm/mach-s3c64xx/s3c6400.c
*
* Copyright (c) 2006, Samsung Electronics
* All rights reserved.
*
* Samsung S3C6400 Mobile CPU support
*
* 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.
*
* derived from linux/arch/arm/mach-s3c2410/devs.c, written by
* Ben Dooks <ben@simtec.co.uk>
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/sysdev.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/clk.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/proc-fns.h>
#include <asm/arch/idle.h>
#include <asm/arch/regs-s3c6410-clock.h>
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/map.h>
#include <asm/arch/nand.h>
#include <asm/plat-s3c24xx/s3c6400.h>
#include <asm/plat-s3c24xx/devs.h>
#include <asm/plat-s3c24xx/cpu.h>
#include "pm-s3c6410.h"
/* Serial port registrations */
static struct map_desc s3c6400_iodesc[] __initdata = {
IODESC_ENT(TIMER),
IODESC_ENT(LCD),
IODESC_ENT(HOSTIFB),
IODESC_ENT(IIS),
IODESC_ENT(AC97),
IODESC_ENT(OTG),
IODESC_ENT(OTGSFR),
IODESC_ENT(CAMIF),
};
/* s3c6400_idle
*
* use the standard idle call by ensuring the idle mode
* in power config, then issuing the idle co-processor
* instruction
*/
static void s3c6400_idle(void)
{
unsigned long tmp;
/* ensure our idle mode is to go to idle */
/* Set WFI instruction to SLEEP mode */
tmp = __raw_readl(S3C_PWR_CFG);
tmp &= ~(0x3<<5);
tmp |= (0x1<<5);
__raw_writel(tmp, S3C_PWR_CFG);
cpu_do_idle();
}
void __init s3c6400_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
s3c24xx_init_uartdevs("s3c-uart", s3c2410_uart_resources, cfg, no);
#if defined (CONFIG_S3C_SIR)
s3c24xx_uart_src[3]->name = "s3c-irda";
#endif
/* rename devices that are s3c2413/s3c2443/s3c6400 specific */
s3c_device_lcd.name = "s3c-lcd";
s3c_device_nand.name = "s3c-nand";
s3c_device_tvenc.name = "s3c-tvenc";
s3c_device_tvscaler.name = "s3c-tvscaler";
}
struct sysdev_class s3c6400_sysclass = {
set_kset_name("s3c6410-core"),
};
static struct sys_device s3c6400_sysdev = {
.cls = &s3c6400_sysclass,
};
static int __init s3c6400_core_init(void)
{
return sysdev_class_register(&s3c6400_sysclass);
}
core_initcall(s3c6400_core_init);
void __init s3c6400_map_io(struct map_desc *mach_desc, int size)
{
/* register our io-tables */
iotable_init(s3c6400_iodesc, ARRAY_SIZE(s3c6400_iodesc));
iotable_init(mach_desc, size);
/* rename any peripherals used differing from the s3c2412 */
/* set our idle function */
s3c24xx_idle = s3c6400_idle;
}
int __init s3c6400_init(void)
{
int ret;
printk("s3c6410: Initialising architecture\n");
ret = sysdev_register(&s3c6400_sysdev);
if (ret != 0)
printk(KERN_ERR "failed to register sysdev for s3c6410\n");
return ret;
}
static int mem_proc_read (
char *buffer,
char **buffer_location,
off_t offset,
int buffer_length,
int *zero,
void *ptr
)
{
return 0;
}
static int mem_proc_write (
struct file *file,
const char *buffer,
unsigned long count,
void *data
)
{
ulong address = 0, size = 0x100;
ulong i = 0, j = 0;
volatile uint *addr;
char flag = 'b';
uint temp=0;
printk("buffers: %s\n", buffer);
sscanf(buffer, "%lx %lx %c", &address, &size, &flag);
switch (flag) {
case 'b':
for (i = address; i < address + size; i += 4 * 4) {
printk("0x%08lx: %08x %08x %08x %08x\n",
i,
*(uint *) i,
*(uint *) (i + 0x04),
*(uint *) (i + 0x08),
*(uint *) (i + 0x0c));
}
break;
case 'l':
for (i = address; i < address + size; i += 4 * 4) {
printk("0x%08lx: %08x %08x %08x %08x\n",
i,
swab32(*(uint *) i),
swab32(*(uint *) (i + 0x04)),
swab32(*(uint *) (i + 0x08)),
swab32(*(uint *) (i + 0x0c)));
}
break;
case 'w':
for (j = 0; j < 0x20000; j++) {
temp = 0;
for (i = address; i < address + size; i += 4) {
addr = (volatile uint *)i;
temp += *addr;
// *(volatile uint *)i = temp+1;
}
if (!(j%0x1000)) {
printk("%08x\n", temp);
}
}
break;
}
return count;
}
static struct proc_dir_entry *evb_resource_dump;
int __init mem_rw_proc (void)
{
evb_resource_dump = create_proc_entry("memory", 0666, &proc_root);
evb_resource_dump->read_proc = mem_proc_read;
evb_resource_dump->write_proc = mem_proc_write;
evb_resource_dump->nlink = 1;
return 0;
}
module_init(mem_rw_proc);