Commit 8a0997a0 authored by Ben Dooks's avatar Ben Dooks Committed by Russell King

[ARM PATCH] 1793/1: S3C2410 - arch/arm/mach-s3c2410 [ repost of 1790/1 ]

Patch from Ben Dooks

Core support for S3C2410 based machines

machine support for Simtec BAST, VR1000 and
IPAQ H1940

repost of 1790/1 with configuration definition fixed
parent ae510d4c
menu "S3C2410 Implementations"
config ARCH_BAST
bool "Simtec Electronics BAST (EB2410ITX)"
depends on ARCH_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"
depends on ARCH_S3C2410
help
say Y here if you are using the HP IPAQ H1940
http://www.handhelds.org/projects/h1940.html
config MACH_VR1000
bool "Simtec VR1000"
depends on ARCH_S3C2410
help
say Y here if you are using the Simtec VR1000 board.
endmenu
#
# Makefile for the linux kernel.
#
# Object file lists.
obj-y := s3c2410.o irq.o
obj-m :=
obj-n :=
obj- :=
obj-$(CONFIG_ARCH_BAST) += mach-bast.o
obj-$(CONFIG_MACH_H1940) += mach-h1940.o
obj-$(CONFIG_ARCH_H1940) += mach-h1940.o
obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o
#obj-$(CONFIG_PCI) +=$(pci-y)
#obj-$(CONFIG_LEDS) +=$(leds-y)
/* 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;
}
}
extern void bast_init_irq(void);
/* linux/arch/arm/mach-s3c2410/irq.c
*
* Copyright (c) 2003 Simtec Electronics
* 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 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/interrupt.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/arch/regs-irq.h>
#include <asm/arch/regs-lcd.h>
#if 0
#include <asm/debug-ll.h>
#endif
#define irqdbf(x...)
#define irqdbf2(x...)
static void
s3c_irq_mask(unsigned int irqno)
{
unsigned long mask;
irqno -= IRQ_EINT0;
mask = __raw_readl(S3C2410_INTMSK);
mask |= 1UL << irqno;
__raw_writel(mask, S3C2410_INTMSK);
}
static inline void
s3c_irq_ack(unsigned int irqno)
{
unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
__raw_writel(bitval, S3C2410_SRCPND);
__raw_writel(bitval, S3C2410_INTPND);
}
static inline void
s3c_irq_maskack(unsigned int irqno)
{
unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
unsigned long mask;
mask = __raw_readl(S3C2410_INTMSK);
__raw_writel(mask|bitval, S3C2410_INTMSK);
__raw_writel(bitval, S3C2410_SRCPND);
__raw_writel(bitval, S3C2410_INTPND);
}
static void
s3c_irq_unmask(unsigned int irqno)
{
unsigned long mask;
if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
irqdbf2("s3c_irq_unmask %d\n", irqno);
irqno -= IRQ_EINT0;
mask = __raw_readl(S3C2410_INTMSK);
mask &= ~(1UL << irqno);
__raw_writel(mask, S3C2410_INTMSK);
}
static struct irqchip s3c_irq_level_chip = {
.ack = s3c_irq_maskack,
.mask = s3c_irq_mask,
.unmask = s3c_irq_unmask
};
static struct irqchip s3c_irq_chip = {
.ack = s3c_irq_ack,
.mask = s3c_irq_mask,
.unmask = s3c_irq_unmask
};
/* S3C2410_EINTMASK
* S3C2410_EINTPEND
*/
#define EXTINT_OFF (IRQ_EINT4 - 4)
static void
s3c_irqext_mask(unsigned int irqno)
{
unsigned long mask;
irqno -= EXTINT_OFF;
mask = __raw_readl(S3C2410_EINTMASK);
mask |= ( 1UL << irqno);
__raw_writel(mask, S3C2410_EINTMASK);
if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) {
/* check to see if all need masking */
if ((mask & (0xf << 4)) == (0xf << 4)) {
/* all masked, mask the parent */
s3c_irq_mask(IRQ_EINT4t7);
}
} else {
/* todo: the same check as above for the rest of the irq regs...*/
}
}
static void
s3c_irqext_ack(unsigned int irqno)
{
unsigned long req;
unsigned long bit;
unsigned long mask;
bit = 1UL << (irqno - EXTINT_OFF);
mask = __raw_readl(S3C2410_EINTMASK);
__raw_writel(bit, S3C2410_EINTPEND);
req = __raw_readl(S3C2410_EINTPEND);
req &= ~mask;
/* not sure if we should be acking the parent irq... */
if (irqno <= IRQ_EINT7 ) {
if ((req & 0xf0) == 0)
s3c_irq_ack(IRQ_EINT4t7);
} else {
if ((req >> 8) == 0)
s3c_irq_ack(IRQ_EINT8t23);
}
}
static void
s3c_irqext_unmask(unsigned int irqno)
{
unsigned long mask;
irqno -= EXTINT_OFF;
mask = __raw_readl(S3C2410_EINTMASK);
mask &= ~( 1UL << irqno);
__raw_writel(mask, S3C2410_EINTMASK);
s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23);
}
/* todo - put type handler in here */
static int
s3c_irqext_type(unsigned int irq, unsigned int type)
{
irqdbf("s3c_irqext_type: called for irq %d, type %d\n", irq, type);
return 0;
}
static struct irqchip s3c_irqext_chip = {
.mask = s3c_irqext_mask,
.unmask = s3c_irqext_unmask,
.ack = s3c_irqext_ack,
.type = s3c_irqext_type
};
/* mask values for the parent registers for each of the interrupt types */
#define INTMSK_UART0 (1UL << (IRQ_UART0 - IRQ_EINT0))
#define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0))
#define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0))
#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
static inline void
s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
int subcheck)
{
unsigned long mask;
unsigned long submask;
submask = __raw_readl(S3C2410_INTSUBMSK);
mask = __raw_readl(S3C2410_INTMSK);
submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
/* check to see if we need to mask the parent IRQ */
if ((submask & subcheck) == subcheck) {
__raw_writel(mask | parentbit, S3C2410_INTMSK);
}
/* write back masks */
__raw_writel(submask, S3C2410_INTSUBMSK);
}
static inline void
s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
{
unsigned long mask;
unsigned long submask;
submask = __raw_readl(S3C2410_INTSUBMSK);
mask = __raw_readl(S3C2410_INTMSK);
submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
mask &= ~parentbit;
/* write back masks */
__raw_writel(submask, S3C2410_INTSUBMSK);
__raw_writel(mask, S3C2410_INTMSK);
}
static inline void
s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group)
{
unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
s3c_irqsub_mask(irqno, parentmask, group);
__raw_writel(bit, S3C2410_SUBSRCPND);
/* only ack parent if we've got all the irqs (seems we must
* ack, all and hope that the irq system retriggers ok when
* the interrupt goes off again)
*/
if (1) {
__raw_writel(parentmask, S3C2410_SRCPND);
__raw_writel(parentmask, S3C2410_INTPND);
}
}
/* UART0 */
static void
s3c_irq_uart0_mask(unsigned int irqno)
{
s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
}
static void
s3c_irq_uart0_unmask(unsigned int irqno)
{
s3c_irqsub_unmask(irqno, INTMSK_UART0);
}
static void
s3c_irq_uart0_ack(unsigned int irqno)
{
s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
}
static struct irqchip s3c_irq_uart0 = {
.mask = s3c_irq_uart0_mask,
.unmask = s3c_irq_uart0_unmask,
.ack = s3c_irq_uart0_ack,
};
/* UART1 */
static void
s3c_irq_uart1_mask(unsigned int irqno)
{
s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
}
static void
s3c_irq_uart1_unmask(unsigned int irqno)
{
s3c_irqsub_unmask(irqno, INTMSK_UART1);
}
static void
s3c_irq_uart1_ack(unsigned int irqno)
{
s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
}
static struct irqchip s3c_irq_uart1 = {
.mask = s3c_irq_uart1_mask,
.unmask = s3c_irq_uart1_unmask,
.ack = s3c_irq_uart1_ack,
};
/* UART2 */
static void
s3c_irq_uart2_mask(unsigned int irqno)
{
s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
}
static void
s3c_irq_uart2_unmask(unsigned int irqno)
{
s3c_irqsub_unmask(irqno, INTMSK_UART2);
}
static void
s3c_irq_uart2_ack(unsigned int irqno)
{
s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
}
static struct irqchip s3c_irq_uart2 = {
.mask = s3c_irq_uart2_mask,
.unmask = s3c_irq_uart2_unmask,
.ack = s3c_irq_uart2_ack,
};
/* ADC and Touchscreen */
static void
s3c_irq_adc_mask(unsigned int irqno)
{
s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
}
static void
s3c_irq_adc_unmask(unsigned int irqno)
{
s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
}
static void
s3c_irq_adc_ack(unsigned int irqno)
{
s3c_irqsub_maskack(irqno, INTMSK_ADCPARENT, 3 << 9);
}
static struct irqchip s3c_irq_adc = {
.mask = s3c_irq_adc_mask,
.unmask = s3c_irq_adc_unmask,
.ack = s3c_irq_adc_ack,
};
#if 0
/* LCD (todo) */
static void
s3c_irq_lcd_mask(unsigned int irqno)
{
}
static void
s3c_irq_lcd_unmask(unsigned int irqno)
{
}
static void
s3c_irq_lcd_ack(unsigned int irqno)
{
}
static struct irqchip s3c_irq_lcd = {
.mask = s3c_irq_lcd_mask,
.unmask = s3c_irq_lcd_unmask,
.ack = s3c_irq_lcd_ack,
};
#endif
/* irq demux */
static void s3c_irq_demux_uart(unsigned int start,
struct pt_regs *regs)
{
unsigned int subsrc, submsk;
unsigned int offset = start - IRQ_S3CUART_RX0;
struct irqdesc *desc;
/* read the current pending interrupts, and the mask
* for what it is available */
subsrc = __raw_readl(S3C2410_SUBSRCPND);
submsk = __raw_readl(S3C2410_INTSUBMSK);
irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
start, offset, subsrc, submsk);
subsrc &= ~submsk;
subsrc >>= offset;
subsrc &= 7;
if (subsrc != 0) {
desc = irq_desc + start;
if (subsrc & 1)
desc->handle(start, desc, regs);
desc++;
if (subsrc & 2)
desc->handle(start+1, desc, regs);
desc++;
if (subsrc & 4)
desc->handle(start+2, desc, regs);
}
}
/* uart demux entry points */
static void
s3c_irq_demux_uart0(unsigned int irq,
struct irqdesc *desc,
struct pt_regs *regs)
{
irq = irq;
s3c_irq_demux_uart(IRQ_S3CUART_RX0, regs);
}
static void
s3c_irq_demux_uart1(unsigned int irq,
struct irqdesc *desc,
struct pt_regs *regs)
{
irq = irq;
s3c_irq_demux_uart(IRQ_S3CUART_RX1, regs);
}
static void
s3c_irq_demux_uart2(unsigned int irq,
struct irqdesc *desc,
struct pt_regs *regs)
{
irq = irq;
s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs);
}
void __init s3c2410_init_irq(void)
{
unsigned long pend;
int irqno;
int i;
irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
/* first, clear all interrupts pending... */
for (i = 0; i < 4; i++) {
pend = __raw_readl(S3C2410_EINTPEND);
if (pend == 0)
break;
__raw_writel(pend, S3C2410_EINTPEND);
printk("irq: clearing pending ext status %08x\n", (int)pend);
}
for (i = 0; i < 4; i++) {
pend = __raw_readl(S3C2410_INTPND);
if (pend == 0)
break;
__raw_writel(pend, S3C2410_SRCPND);
__raw_writel(pend, S3C2410_INTPND);
printk("irq: clearing pending status %08x\n", (int)pend);
}
for (i = 0; i < 4; i++) {
pend = __raw_readl(S3C2410_SUBSRCPND);
if (pend == 0)
break;
printk("irq: clearing subpending status %08x\n", (int)pend);
__raw_writel(pend, S3C2410_SUBSRCPND);
}
/* register the main interrupts */
irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
for (irqno = IRQ_EINT0; irqno < IRQ_ADCPARENT; irqno++) {
/* set all the s3c2410 internal irqs */
switch (irqno) {
case IRQ_EINT4t7:
case IRQ_EINT8t23:
/* these are already dealt with, so should never
* appear */
break;
/* deal with the special IRQs (cascaded) */
case IRQ_UART0:
case IRQ_UART1:
case IRQ_UART2:
case IRQ_LCD:
case IRQ_ADCPARENT:
set_irq_chip(irqno, &s3c_irq_level_chip);
set_irq_handler(irqno, do_level_IRQ);
break;
case IRQ_RESERVED6:
case IRQ_RESERVED24:
/* no IRQ here */
break;
default:
//irqdbf("registering irq %d (s3c irq)\n", irqno);
set_irq_chip(irqno, &s3c_irq_chip);
set_irq_handler(irqno, do_edge_IRQ);
set_irq_flags(irqno, IRQF_VALID);
}
}
/* setup the cascade irq handlers */
set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
//set_irq_chained_handler(IRQ_LCD, s3c_irq_demux_);
//set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_);
/* external interrupts */
for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
irqdbf("registering irq %d (extended s3c irq)\n", irqno);
set_irq_chip(irqno, &s3c_irqext_chip);
set_irq_handler(irqno, do_edge_IRQ);
set_irq_flags(irqno, IRQF_VALID);
}
/* register the uart interrupts */
irqdbf("s3c2410: registering external interrupts\n");
for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
set_irq_chip(irqno, &s3c_irq_uart0);
set_irq_handler(irqno, do_level_IRQ);
set_irq_flags(irqno, IRQF_VALID);
}
for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
set_irq_chip(irqno, &s3c_irq_uart1);
set_irq_handler(irqno, do_level_IRQ);
set_irq_flags(irqno, IRQF_VALID);
}
for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
set_irq_chip(irqno, &s3c_irq_uart2);
set_irq_handler(irqno, do_level_IRQ);
set_irq_flags(irqno, IRQF_VALID);
}
for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
irqdbf("registering irq %d (s3c adc irq)\n", irqno);
set_irq_chip(irqno, &s3c_irq_adc);
set_irq_handler(irqno, do_edge_IRQ);
set_irq_flags(irqno, IRQF_VALID);
}
irqdbf("s3c2410: registered interrupt handlers\n");
}
/* linux/arch/arm/mach-s3c2410/mach-bast.c
*
* Copyright (c) 2003 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 version 2 as
* published by the Free Software Foundation.
*
* Modifications:
* 16-May-2003 BJD Created initial version
* 16-Aug-2003 BJD Fixed header files and copyright, added URL
* 05-Sep-2003 BJD Moved to v2.6 kernel
* 06-Jan-2003 BJD Updates for <arch/map.h>
* 18-Jan-2003 BJD Added serial port configuration
*/
#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 <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/arch/bast-map.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
//#include <asm/debug-ll.h>
#include <asm/arch/regs-serial.h>
#include "s3c2410.h"
/* macros for virtual address mods for the io space entries */
#define VA_C5(item) ((item) + BAST_VAM_CS5)
#define VA_C4(item) ((item) + BAST_VAM_CS4)
#define VA_C3(item) ((item) + BAST_VAM_CS3)
#define VA_C2(item) ((item) + BAST_VAM_CS2)
/* macros to modify the physical addresses for io space */
#define PA_CS2(item) ((item) + S3C2410_CS2)
#define PA_CS3(item) ((item) + S3C2410_CS3)
#define PA_CS4(item) ((item) + S3C2410_CS4)
#define PA_CS5(item) ((item) + S3C2410_CS5)
static struct map_desc bast_iodesc[] __initdata = {
/* ISA IO areas */
{ S3C2410_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ S3C2410_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
/* we could possibly compress the next set down into a set of smaller tables
* pagetables, but that would mean using an L2 section, and it still means
* we cannot actually feed the same register to an LDR due to 16K spacing
*/
/* bast CPLD control registers, and external interrupt controls */
{ BAST_VA_CTRL1, BAST_PA_CTRL1, SZ_1M, MT_DEVICE },
{ BAST_VA_CTRL2, BAST_PA_CTRL2, SZ_1M, MT_DEVICE },
{ BAST_VA_CTRL3, BAST_PA_CTRL3, SZ_1M, MT_DEVICE },
{ BAST_VA_CTRL4, BAST_PA_CTRL4, SZ_1M, MT_DEVICE },
/* PC104 IRQ mux */
{ BAST_VA_PC104_IRQREQ, BAST_PA_PC104_IRQREQ, SZ_1M, MT_DEVICE },
{ BAST_VA_PC104_IRQRAW, BAST_PA_PC104_IRQRAW, SZ_1M, MT_DEVICE },
{ BAST_VA_PC104_IRQMASK, BAST_PA_PC104_IRQMASK, SZ_1M, MT_DEVICE },
/* onboard 8bit lcd port */
{ BAST_VA_LCD_RCMD1, BAST_PA_LCD_RCMD1, SZ_1M, MT_DEVICE },
{ BAST_VA_LCD_WCMD1, BAST_PA_LCD_WCMD1, SZ_1M, MT_DEVICE },
{ BAST_VA_LCD_RDATA1, BAST_PA_LCD_RDATA1, SZ_1M, MT_DEVICE },
{ BAST_VA_LCD_WDATA1, BAST_PA_LCD_WDATA1, SZ_1M, MT_DEVICE },
{ BAST_VA_LCD_RCMD2, BAST_PA_LCD_RCMD2, SZ_1M, MT_DEVICE },
{ BAST_VA_LCD_WCMD2, BAST_PA_LCD_WCMD2, SZ_1M, MT_DEVICE },
{ BAST_VA_LCD_RDATA2, BAST_PA_LCD_RDATA2, SZ_1M, MT_DEVICE },
{ BAST_VA_LCD_WDATA2, BAST_PA_LCD_WDATA2, SZ_1M, MT_DEVICE },
/* peripheral space... one for each of fast/slow/byte/16bit */
/* note, ide is only decoded in word space, even though some registers
* are only 8bit */
/* slow, byte */
{ VA_C2(BAST_VA_ISAIO), PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ VA_C2(BAST_VA_ISAMEM), PA_CS2(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
{ VA_C2(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE },
{ VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
{ VA_C2(BAST_VA_DM9000), PA_CS2(BAST_PA_DM9000), SZ_1M, MT_DEVICE },
{ VA_C2(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
{ VA_C2(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C2(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
{ VA_C2(BAST_VA_IDESECAUX), PA_CS3(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE },
/* slow, word */
{ VA_C3(BAST_VA_ISAIO), PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ VA_C3(BAST_VA_ISAMEM), PA_CS3(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
{ VA_C3(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE },
{ VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
{ VA_C3(BAST_VA_DM9000), PA_CS3(BAST_PA_DM9000), SZ_1M, MT_DEVICE },
{ VA_C3(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
{ VA_C3(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C3(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
{ VA_C3(BAST_VA_IDESECAUX), PA_CS3(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE },
/* fast, byte */
{ VA_C4(BAST_VA_ISAIO), PA_CS4(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ VA_C4(BAST_VA_ISAMEM), PA_CS4(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
{ VA_C4(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE },
{ VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
{ VA_C4(BAST_VA_DM9000), PA_CS4(BAST_PA_DM9000), SZ_1M, MT_DEVICE },
{ VA_C4(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
{ VA_C4(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C4(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
{ VA_C4(BAST_VA_IDESECAUX), PA_CS5(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE },
/* fast, word */
{ VA_C5(BAST_VA_ISAIO), PA_CS5(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ VA_C5(BAST_VA_ISAMEM), PA_CS5(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
{ VA_C5(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE },
{ VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
{ VA_C5(BAST_VA_DM9000), PA_CS5(BAST_PA_DM9000), SZ_1M, MT_DEVICE },
{ VA_C5(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
{ VA_C5(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C5(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
{ VA_C5(BAST_VA_IDESECAUX), PA_CS5(BAST_PA_IDESECAUX), SZ_1M, MT_DEVICE },
};
#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
/* base baud rate for all our UARTs */
static unsigned long bast_serial_clock = 24*1000*1000;
static struct s3c2410_uartcfg bast_uartcfgs[] = {
[0] = {
.hwport = 0,
.flags = 0,
.clock = &bast_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
[1] = {
.hwport = 1,
.flags = 0,
.clock = &bast_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
/* port 2 is not actually used */
[2] = {
.hwport = 2,
.flags = 0,
.clock = &bast_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
}
};
void __init bast_map_io(void)
{
s3c2410_map_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
s3c2410_uartcfgs = bast_uartcfgs;
}
void __init bast_init_irq(void)
{
//llprintk("bast_init_irq:\n");
s3c2410_init_irq();
}
MACHINE_START(BAST, "Simtec-BAST")
MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(bast_map_io)
INITIRQ(bast_init_irq)
MACHINE_END
/* linux/arch/arm/mach-s3c2410/mach-ipaq.c
*
* Copyright (c) 2003 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* http://www.handhelds.org/projects/h1940.html
*
* 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.
*
* Modifications:
* 16-May-2003 BJD Created initial version
* 16-Aug-2003 BJD Fixed header files and copyright, added URL
* 05-Sep-2003 BJD Moved to v2.6 kernel
* 06-Jan-2003 BJD Updates for <arch/map.h>
* 18-Jan-2003 BJD Added serial port configuration
* 17-Feb-2003 BJD Copied to mach-ipaq.c
*/
#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 <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/hardware.h>
#include <asm/hardware/iomd.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
//#include <asm/debug-ll.h>
#include <asm/arch/regs-serial.h>
#include "s3c2410.h"
static struct map_desc ipaq_iodesc[] __initdata = {
/* nothing here yet */
};
#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
static struct s3c2410_uartcfg ipaq_uartcfgs[] = {
[0] = {
.hwport = 0,
.flags = 0,
.clock = &s3c2410_hclk,
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x51,
},
[1] = {
.hwport = 1,
.flags = 0,
.clock = &s3c2410_hclk,
.ucon = 0x245,
.ulcon = 0x03,
.ufcon = 0x00,
},
/* IR port */
[2] = {
.hwport = 2,
.flags = 0,
.clock = &s3c2410_hclk,
.ucon = 0x3c5,
.ulcon = 0x43,
.ufcon = 0x51,
}
};
void __init ipaq_map_io(void)
{
s3c2410_map_io(ipaq_iodesc, ARRAY_SIZE(ipaq_iodesc));
s3c2410_uartcfgs = ipaq_uartcfgs;
}
void __init ipaq_init_irq(void)
{
//llprintk("ipaq_init_irq:\n");
s3c2410_init_irq();
}
MACHINE_START(H1940, "IPAQ-H1940")
MAINTAINER("Ben Dooks <ben@fluff.org>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(ipaq_map_io)
INITIRQ(ipaq_init_irq)
MACHINE_END
/* linux/arch/arm/mach-s3c2410/mach-vr1000.c
*
* Copyright (c) 2003 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* http://www.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.
*
* Modifications:
* 16-May-2003 BJD Created initial version
* 16-Aug-2003 BJD Fixed header files and copyright, added URL
* 05-Sep-2003 BJD Moved to v2.6 kernel
* 06-Jan-2003 BJD Updates for <arch/map.h>
* 18-Jan-2003 BJD Added serial port configuration
* 05-Apr-2004 BJD Copied to make mach-vr1000.c
*/
#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 <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/arch/bast-map.h>
#include <asm/arch/vr1000-map.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
//#include <asm/debug-ll.h>
#include <asm/arch/regs-serial.h>
#include "s3c2410.h"
/* macros for virtual address mods for the io space entries */
#define VA_C5(item) ((item) + BAST_VAM_CS5)
#define VA_C4(item) ((item) + BAST_VAM_CS4)
#define VA_C3(item) ((item) + BAST_VAM_CS3)
#define VA_C2(item) ((item) + BAST_VAM_CS2)
/* macros to modify the physical addresses for io space */
#define PA_CS2(item) ((item) + S3C2410_CS2)
#define PA_CS3(item) ((item) + S3C2410_CS3)
#define PA_CS4(item) ((item) + S3C2410_CS4)
#define PA_CS5(item) ((item) + S3C2410_CS5)
static struct map_desc vr1000_iodesc[] __initdata = {
/* ISA IO areas */
{ S3C2410_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
{ S3C2410_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
/* we could possibly compress the next set down into a set of smaller tables
* pagetables, but that would mean using an L2 section, and it still means
* we cannot actually feed the same register to an LDR due to 16K spacing
*/
/* bast CPLD control registers, and external interrupt controls */
{ VR1000_VA_CTRL1, VR1000_PA_CTRL1, SZ_1M, MT_DEVICE },
{ VR1000_VA_CTRL2, VR1000_PA_CTRL2, SZ_1M, MT_DEVICE },
{ VR1000_VA_CTRL3, VR1000_PA_CTRL3, SZ_1M, MT_DEVICE },
{ VR1000_VA_CTRL4, VR1000_PA_CTRL4, SZ_1M, MT_DEVICE },
/* peripheral space... one for each of fast/slow/byte/16bit */
/* note, ide is only decoded in word space, even though some registers
* are only 8bit */
/* slow, byte */
{ VA_C2(VR1000_VA_DM9000), PA_CS2(VR1000_PA_DM9000), SZ_1M, MT_DEVICE },
{ VA_C2(VR1000_VA_IDEPRI), PA_CS3(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
{ VA_C2(VR1000_VA_IDESEC), PA_CS3(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C2(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
{ VA_C2(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
/* slow, word */
{ VA_C3(VR1000_VA_DM9000), PA_CS3(VR1000_PA_DM9000), SZ_1M, MT_DEVICE },
{ VA_C3(VR1000_VA_IDEPRI), PA_CS3(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
{ VA_C3(VR1000_VA_IDESEC), PA_CS3(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C3(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
{ VA_C3(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
/* fast, byte */
{ VA_C4(VR1000_VA_DM9000), PA_CS4(VR1000_PA_DM9000), SZ_1M, MT_DEVICE },
{ VA_C4(VR1000_VA_IDEPRI), PA_CS5(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
{ VA_C4(VR1000_VA_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C4(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
{ VA_C4(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
/* fast, word */
{ VA_C5(VR1000_VA_DM9000), PA_CS5(VR1000_PA_DM9000), SZ_1M, MT_DEVICE },
{ VA_C5(VR1000_VA_IDEPRI), PA_CS5(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
{ VA_C5(VR1000_VA_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
{ VA_C5(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
{ VA_C5(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
};
#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
/* base baud rate for all our UARTs */
static unsigned long vr1000_serial_clock = 3692307;
static struct s3c2410_uartcfg vr1000_uartcfgs[] = {
[0] = {
.hwport = 0,
.flags = 0,
.clock = &vr1000_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
[1] = {
.hwport = 1,
.flags = 0,
.clock = &vr1000_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
/* port 2 is not actually used */
[2] = {
.hwport = 2,
.flags = 0,
.clock = &vr1000_serial_clock,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
}
};
void __init vr1000_map_io(void)
{
s3c2410_map_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
s3c2410_uartcfgs = vr1000_uartcfgs;
}
void __init vr1000_init_irq(void)
{
//llprintk("vr1000init_irq:\n");
s3c2410_init_irq();
}
MACHINE_START(VR1000, "Simtec-VR1000")
MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(vr1000_map_io)
INITIRQ(vr1000_init_irq)
MACHINE_END
/* linux/arch/arm/mach-s3c2410/s3c2410.c
*
* Copyright (c) 2003 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 version 2 as
* published by the Free Software Foundation.
*
* Modifications:
* 16-May-2003 BJD Created initial version
* 16-Aug-2003 BJD Fixed header files and copyright, added URL
* 05-Sep-2003 BJD Moved to kernel v2.6
* 18-Jan-2003 BJD Added serial port configuration
*/
#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/device.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/mach-types.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-serial.h>
int s3c2410_clock_tick_rate = 12*1000*1000; /* current timers at 12MHz */
/* serial port setup */
struct s3c2410_uartcfg *s3c2410_uartcfgs;
/* clock info */
unsigned long s3c2410_fclk;
unsigned long s3c2410_hclk;
unsigned long s3c2410_pclk;
#ifndef MHZ
#define MHZ (1000*1000)
#endif
#define print_mhz(m) ((m) / MHZ), ((m / 1000) % 1000)
#define IODESC_ENT(x) { S3C2410_VA_##x, S3C2410_PA_##x, S3C2410_SZ_##x, MT_DEVICE }
static struct map_desc s3c2410_iodesc[] __initdata = {
IODESC_ENT(IRQ),
IODESC_ENT(MEMCTRL),
IODESC_ENT(USBHOST),
IODESC_ENT(DMA),
IODESC_ENT(CLKPWR),
IODESC_ENT(LCD),
IODESC_ENT(NAND),
IODESC_ENT(UART),
IODESC_ENT(TIMER),
IODESC_ENT(USBDEV),
IODESC_ENT(WATCHDOG),
IODESC_ENT(IIC),
IODESC_ENT(IIS),
IODESC_ENT(GPIO),
IODESC_ENT(RTC),
IODESC_ENT(ADC),
IODESC_ENT(SPI),
IODESC_ENT(SDI)
};
static struct resource s3c_uart0_resource[] = {
[0] = {
.start = S3C2410_PA_UART0,
.end = S3C2410_PA_UART0 + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX0,
.end = IRQ_S3CUART_ERR0,
.flags = IORESOURCE_IRQ,
}
};
static struct resource s3c_uart1_resource[] = {
[0] = {
.start = S3C2410_PA_UART1,
.end = S3C2410_PA_UART1 + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX1,
.end = IRQ_S3CUART_ERR1,
.flags = IORESOURCE_IRQ,
}
};
static struct resource s3c_uart2_resource[] = {
[0] = {
.start = S3C2410_PA_UART2,
.end = S3C2410_PA_UART2 + 0x3fff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX2,
.end = IRQ_S3CUART_ERR2,
.flags = IORESOURCE_IRQ,
}
};
/* our uart devices */
static struct platform_device s3c_uart0 = {
.name = "s3c2410-uart",
.id = 0,
.num_resources = ARRAY_SIZE(s3c_uart0_resource),
.resource = s3c_uart0_resource,
};
static struct platform_device s3c_uart1 = {
.name = "s3c2410-uart",
.id = 1,
.num_resources = ARRAY_SIZE(s3c_uart1_resource),
.resource = s3c_uart1_resource,
};
static struct platform_device s3c_uart2 = {
.name = "s3c2410-uart",
.id = 2,
.num_resources = ARRAY_SIZE(s3c_uart2_resource),
.resource = s3c_uart2_resource,
};
static struct platform_device *uart_devices[] __initdata = {
&s3c_uart0,
&s3c_uart1,
&s3c_uart2
};
void __init s3c2410_map_io(struct map_desc *mach_desc, int size)
{
unsigned long tmp;
/* register our io-tables */
iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
iotable_init(mach_desc, size);
/* now we've got our machine bits initialised, work out what
* clocks we've got */
s3c2410_fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), 12*MHZ);
tmp = __raw_readl(S3C2410_CLKDIVN);
//printk("tmp=%08x, fclk=%d\n", tmp, s3c2410_fclk);
/* work out clock scalings */
s3c2410_hclk = s3c2410_fclk / ((tmp & S3C2410_CLKDIVN_HDIVN) ? 2 : 1);
s3c2410_pclk = s3c2410_hclk / ((tmp & S3C2410_CLKDIVN_PDIVN) ? 2 : 1);
/* print brieft summary of clocks, etc */
printk("S3C2410: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
print_mhz(s3c2410_fclk), print_mhz(s3c2410_hclk),
print_mhz(s3c2410_pclk));
}
static int __init s3c2410_init(void)
{
int ret;
printk("S3C2410: Initialising architecture\n");
ret = platform_add_devices(uart_devices, ARRAY_SIZE(uart_devices));
return ret;
}
arch_initcall(s3c2410_init);
extern void s3c2410_map_io(struct map_desc *, int count);
extern void s3c2410_init_irq(void);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment