Commit 7f275437 authored by Ben Dooks's avatar Ben Dooks

Merge branch 'next-s3c64xx' into next-merged

parents c6ad1158 a9c5d23a
......@@ -517,6 +517,13 @@ config ARCH_S3C2410
BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
the Samsung SMDK2410 development board (and derivatives).
config ARCH_S3C64XX
bool "Samsung S3C64XX"
select GENERIC_GPIO
select HAVE_CLK
help
Samsung S3C64XX series based systems
config ARCH_SHARK
bool "Shark"
select CPU_SA110
......@@ -620,6 +627,7 @@ source "arch/arm/mach-orion5x/Kconfig"
source "arch/arm/mach-kirkwood/Kconfig"
source "arch/arm/plat-s3c24xx/Kconfig"
source "arch/arm/plat-s3c64xx/Kconfig"
source "arch/arm/plat-s3c/Kconfig"
if ARCH_S3C2410
......@@ -631,6 +639,11 @@ source "arch/arm/mach-s3c2442/Kconfig"
source "arch/arm/mach-s3c2443/Kconfig"
endif
if ARCH_S3C64XX
source "arch/arm/mach-s3c6400/Kconfig"
source "arch/arm/mach-s3c6410/Kconfig"
endif
source "arch/arm/mach-lh7a40x/Kconfig"
source "arch/arm/mach-imx/Kconfig"
......
......@@ -121,7 +121,10 @@ endif
machine-$(CONFIG_ARCH_OMAP3) := omap2
plat-$(CONFIG_ARCH_OMAP) := omap
machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443
machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0
plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c
machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410
plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
machine-$(CONFIG_ARCH_VERSATILE) := versatile
machine-$(CONFIG_ARCH_IMX) := imx
......
......@@ -69,12 +69,12 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
/*
* Make sure we clear all existing interrupts
*/
writel(0, base + VIC_VECT_ADDR);
writel(0, base + VIC_PL190_VECT_ADDR);
for (i = 0; i < 19; i++) {
unsigned int value;
value = readl(base + VIC_VECT_ADDR);
writel(value, base + VIC_VECT_ADDR);
value = readl(base + VIC_PL190_VECT_ADDR);
writel(value, base + VIC_PL190_VECT_ADDR);
}
for (i = 0; i < 16; i++) {
......@@ -82,7 +82,7 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
writel(VIC_VECT_CNTL_ENABLE | i, reg);
}
writel(32, base + VIC_DEF_VECT_ADDR);
writel(32, base + VIC_PL190_DEF_VECT_ADDR);
for (i = 0; i < 32; i++) {
unsigned int irq = irq_start + i;
......
This diff is collapsed.
......@@ -29,15 +29,17 @@
#define VIC_INT_SOFT 0x18
#define VIC_INT_SOFT_CLEAR 0x1c
#define VIC_PROTECT 0x20
#define VIC_VECT_ADDR 0x30
#define VIC_DEF_VECT_ADDR 0x34
#define VIC_PL190_VECT_ADDR 0x30 /* PL190 only */
#define VIC_PL190_DEF_VECT_ADDR 0x34 /* PL190 only */
#define VIC_VECT_ADDR0 0x100 /* 0 to 15 */
#define VIC_VECT_CNTL0 0x200 /* 0 to 15 */
#define VIC_VECT_ADDR0 0x100 /* 0 to 15 (0..31 PL192) */
#define VIC_VECT_CNTL0 0x200 /* 0 to 15 (0..31 PL192) */
#define VIC_ITCR 0x300 /* VIC test control register */
#define VIC_VECT_CNTL_ENABLE (1 << 5)
#define VIC_PL192_VECT_ADDR 0xF00
#ifndef __ASSEMBLY__
void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources);
#endif
......
......@@ -13,34 +13,20 @@
#ifndef __ASM_ARCH_MAP_H
#define __ASM_ARCH_MAP_H
#include <plat/map-base.h>
#include <plat/map.h>
#define S3C2410_ADDR(x) S3C_ADDR(x)
/* interrupt controller is the first thing we put in, to make
* the assembly code for the irq detection easier
*/
#define S3C24XX_VA_IRQ S3C_VA_IRQ
#define S3C2410_PA_IRQ (0x4A000000)
#define S3C24XX_SZ_IRQ SZ_1M
/* memory controller registers */
#define S3C24XX_VA_MEMCTRL S3C_VA_MEM
#define S3C2410_PA_MEMCTRL (0x48000000)
#define S3C24XX_SZ_MEMCTRL SZ_1M
/* USB host controller */
#define S3C2410_PA_USBHOST (0x49000000)
#define S3C24XX_SZ_USBHOST SZ_1M
/* DMA controller */
#define S3C2410_PA_DMA (0x4B000000)
#define S3C24XX_SZ_DMA SZ_1M
/* Clock and Power management */
#define S3C24XX_VA_CLKPWR S3C_VA_SYS
#define S3C2410_PA_CLKPWR (0x4C000000)
#define S3C24XX_SZ_CLKPWR SZ_1M
/* LCD controller */
#define S3C2410_PA_LCD (0x4D000000)
......@@ -48,48 +34,12 @@
/* NAND flash controller */
#define S3C2410_PA_NAND (0x4E000000)
#define S3C24XX_SZ_NAND SZ_1M
/* UARTs */
#define S3C24XX_VA_UART S3C_VA_UART
#define S3C2410_PA_UART (0x50000000)
#define S3C24XX_SZ_UART SZ_1M
/* Timers */
#define S3C24XX_VA_TIMER S3C_VA_TIMER
#define S3C2410_PA_TIMER (0x51000000)
#define S3C24XX_SZ_TIMER SZ_1M
/* USB Device port */
#define S3C2410_PA_USBDEV (0x52000000)
#define S3C24XX_SZ_USBDEV SZ_1M
/* Watchdog */
#define S3C24XX_VA_WATCHDOG S3C_VA_WATCHDOG
#define S3C2410_PA_WATCHDOG (0x53000000)
#define S3C24XX_SZ_WATCHDOG SZ_1M
/* IIC hardware controller */
#define S3C2410_PA_IIC (0x54000000)
#define S3C24XX_SZ_IIC SZ_1M
/* IIS controller */
#define S3C2410_PA_IIS (0x55000000)
#define S3C24XX_SZ_IIS SZ_1M
/* GPIO ports */
/* the calculation for the VA of this must ensure that
* it is the same distance apart from the UART in the
* phsyical address space, as the initial mapping for the IO
* is done as a 1:1 maping. This puts it (currently) at
* 0xFA800000, which is not in the way of any current mapping
* by the base system.
*/
#define S3C2410_PA_GPIO (0x56000000)
#define S3C24XX_VA_GPIO ((S3C2410_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART)
#define S3C24XX_SZ_GPIO SZ_1M
/* RTC */
#define S3C2410_PA_RTC (0x57000000)
......@@ -97,15 +47,12 @@
/* ADC */
#define S3C2410_PA_ADC (0x58000000)
#define S3C24XX_SZ_ADC SZ_1M
/* SPI */
#define S3C2410_PA_SPI (0x59000000)
#define S3C24XX_SZ_SPI SZ_1M
/* SDI */
#define S3C2410_PA_SDI (0x5A000000)
#define S3C24XX_SZ_SDI SZ_1M
/* CAMIF */
#define S3C2440_PA_CAMIF (0x4F000000)
......@@ -120,13 +67,6 @@
#define S3C2443_PA_HSMMC (0x4A800000)
#define S3C2443_SZ_HSMMC (256)
/* ISA style IO, for each machine to sort out mappings for, if it
* implements it. We reserve two 16M regions for ISA.
*/
#define S3C24XX_VA_ISA_WORD S3C2410_ADDR(0x02000000)
#define S3C24XX_VA_ISA_BYTE S3C2410_ADDR(0x03000000)
/* physical addresses of all the chip-select areas */
#define S3C2410_CS0 (0x00000000)
......@@ -158,21 +98,9 @@
#define S3C24XX_PA_RTC S3C2410_PA_RTC
#define S3C24XX_PA_ADC S3C2410_PA_ADC
#define S3C24XX_PA_SPI S3C2410_PA_SPI
#define S3C24XX_PA_SDI S3C2410_PA_SDI
#define S3C24XX_PA_NAND S3C2410_PA_NAND
/* deal with the registers that move under the 2412/2413 */
#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
#ifndef __ASSEMBLY__
extern void __iomem *s3c24xx_va_gpio2;
#endif
#ifdef CONFIG_CPU_S3C2412_ONLY
#define S3C24XX_VA_GPIO2 (S3C24XX_VA_GPIO + 0x10)
#else
#define S3C24XX_VA_GPIO2 s3c24xx_va_gpio2
#endif
#else
#define s3c24xx_va_gpio2 S3C24XX_VA_GPIO
#define S3C24XX_VA_GPIO2 S3C24XX_VA_GPIO
#endif
#define S3C_PA_UART S3C24XX_PA_UART
#endif /* __ASM_ARCH_MAP_H */
/* linux/arch/arm/mach-s3c2410/include/mach/tick.h
*
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C2410 - timer tick support
*/
#define SRCPND_TIMER4 (1<<(IRQ_TIMER4 - IRQ_EINT0))
static inline int s3c24xx_ostimer_pending(void)
{
return __raw_readl(S3C2410_SRCPND) & SRCPND_TIMER4;
}
/* arch/arm/mach-s3c2410/include/mach/uncompress.h
*
* Copyright (c) 2003, 2007 Simtec Electronics
......
......@@ -93,12 +93,6 @@ static int s3c2412_upll_enable(struct clk *clk, int enable)
/* clock selections */
/* CPU EXTCLK input */
static struct clk clk_ext = {
.name = "extclk",
.id = -1,
};
static struct clk clk_erefclk = {
.name = "erefclk",
.id = -1,
......@@ -773,5 +767,6 @@ int __init s3c2412_baseclk_add(void)
s3c2412_clkcon_enable(clkp, 0);
}
s3c_pwmclk_init();
return 0;
}
......@@ -147,12 +147,6 @@ static unsigned long s3c2443_roundrate_clksrc256(struct clk *clk,
/* clock selections */
/* CPU EXTCLK input */
static struct clk clk_ext = {
.name = "ext",
.id = -1,
};
static struct clk clk_mpllref = {
.name = "mpllref",
.parent = &clk_xtal,
......@@ -167,14 +161,6 @@ static struct clk clk_mpll = {
};
#endif
static struct clk clk_epllref;
static struct clk clk_epll = {
.name = "epll",
.parent = &clk_epllref,
.id = -1,
};
static struct clk clk_i2s_ext = {
.name = "i2s-ext",
.id = -1,
......@@ -1072,6 +1058,7 @@ void __init s3c2443_init_clocks(int xtal)
}
clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
clk_epll.parent = &clk_epllref;
clk_usb_bus.parent = &clk_usb_bus_host;
/* ensure usb bus clock is within correct rate of 48MHz */
......@@ -1120,4 +1107,6 @@ void __init s3c2443_init_clocks(int xtal)
(clkp->enable)(clkp, 0);
}
s3c_pwmclk_init();
}
/* arch/arm/mach-s3c2410/include/mach/debug-macro.S
*
* 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.
*/
/* pull in the relevant register and map files. */
#include <mach/map.h>
#include <plat/regs-serial.h>
.macro addruart, rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1
ldreq \rx, = S3C24XX_PA_UART
ldrne \rx, = S3C24XX_VA_UART
#if CONFIG_DEBUG_S3C_UART != 0
add \rx, \rx, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
#endif
.endm
/* include the reset of the code which will do the work, we're only
* compiling for a single cpu processor type so the default of s3c2440
* will be fine with us.
*/
#include <plat/debug-macro.S>
/* arch/arm/mach-s3c24a0/include/mach/io.h
*
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben-linux@fluff.org>
*
* IO access and mapping routines for the S3C24A0
*/
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
/* No current ISA/PCI bus support. */
#define __io(a) ((void __iomem *)(a))
#define __mem_pci(a) (a)
#endif
/* linux/arch/arm/mach-s3c24a0/include/mach/irqs.h
*
* Copyright (c) 2003-2005 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 version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_ARCH_24A0_IRQS_H
#define __ASM_ARCH_24A0_IRQS_H __FILE__
#define IRQ_EINT0t2 S3C2410_IRQ(0) /* 16 */
/* for generic entry-macro.S */
#define IRQ_EINT0 IRQ_EINT0t2
#define IRQ_EINT3t6 S3C2410_IRQ(1)
#define IRQ_EINT7t10 S3C2410_IRQ(2)
#define IRQ_EINT11t14 S3C2410_IRQ(3)
#define IRQ_EINT15t18 S3C2410_IRQ(4) /* 20 */
#define IRQ_TICK S3C2410_IRQ(5)
#define IRQ_DCTQ S3C2410_IRQ(6)
#define IRQ_MC S3C2410_IRQ(7)
#define IRQ_ME S3C2410_IRQ(8) /* 24 */
#define IRQ_KEYPAD S3C2410_IRQ(9)
#define IRQ_TIMER0 S3C2410_IRQ(10)
#define IRQ_TIMER1 S3C2410_IRQ(11)
#define IRQ_TIMER2 S3C2410_IRQ(12)
#define IRQ_TIMER3_4 S3C2410_IRQ(13)
#define IRQ_OS_TIMER IRQ_TIMER3_4
#define IRQ_LCD S3C2410_IRQ(14)
#define IRQ_CAM_C S3C2410_IRQ(15)
#define IRQ_WDT_BATFLT S3C2410_IRQ(16) /* 32 */
#define IRQ_UART0 S3C2410_IRQ(17)
#define IRQ_CAM_P S3C2410_IRQ(18)
#define IRQ_MODEM S3C2410_IRQ(19)
#define IRQ_DMA S3C2410_IRQ(20)
#define IRQ_SDI S3C2410_IRQ(21)
#define IRQ_SPI0 S3C2410_IRQ(22)
#define IRQ_UART1 S3C2410_IRQ(23)
#define IRQ_AC97_NFLASH S3C2410_IRQ(24) /* 40 */
#define IRQ_USBD S3C2410_IRQ(25)
#define IRQ_USBH S3C2410_IRQ(26)
#define IRQ_IIC S3C2410_IRQ(27)
#define IRQ_IRDA_MSTICK S3C2410_IRQ(28) /* 44 */
#define IRQ_VLX_SPI1 S3C2410_IRQ(29)
#define IRQ_RTC S3C2410_IRQ(30) /* 46 */
#define IRQ_ADC_PEN S3C2410_IRQ(31)
/* interrupts generated from the external interrupts sources */
#define IRQ_EINT00 S3C2410_IRQ(32) /* 48 */
#define IRQ_EINT1 S3C2410_IRQ(33)
#define IRQ_EINT2 S3C2410_IRQ(34)
#define IRQ_EINT3 S3C2410_IRQ(35)
#define IRQ_EINT4 S3C2410_IRQ(36)
#define IRQ_EINT5 S3C2410_IRQ(37)
#define IRQ_EINT6 S3C2410_IRQ(38)
#define IRQ_EINT7 S3C2410_IRQ(39)
#define IRQ_EINT8 S3C2410_IRQ(40)
#define IRQ_EINT9 S3C2410_IRQ(41)
#define IRQ_EINT10 S3C2410_IRQ(42)
#define IRQ_EINT11 S3C2410_IRQ(43)
#define IRQ_EINT12 S3C2410_IRQ(44)
#define IRQ_EINT13 S3C2410_IRQ(45)
#define IRQ_EINT14 S3C2410_IRQ(46)
#define IRQ_EINT15 S3C2410_IRQ(47)
#define IRQ_EINT16 S3C2410_IRQ(48)
#define IRQ_EINT17 S3C2410_IRQ(49)
#define IRQ_EINT18 S3C2410_IRQ(50)
/* SUB IRQS */
#define IRQ_S3CUART_RX0 S3C2410_IRQ(51) /* 67 */
#define IRQ_S3CUART_TX0 S3C2410_IRQ(52)
#define IRQ_S3CUART_ERR0 S3C2410_IRQ(53)
#define IRQ_S3CUART_RX1 S3C2410_IRQ(54)
#define IRQ_S3CUART_TX1 S3C2410_IRQ(55)
#define IRQ_S3CUART_ERR1 S3C2410_IRQ(56)
#define IRQ_S3CUART_RX2 (0x0)
#define IRQ_S3CUART_TX2 (0x0)
#define IRQ_S3CUART_ERR2 (0x0)
#define IRQ_IRDA S3C2410_IRQ(57)
#define IRQ_MSTICK S3C2410_IRQ(58)
#define IRQ_RESERVED0 S3C2410_IRQ(59)
#define IRQ_RESERVED1 S3C2410_IRQ(60)
#define IRQ_RESERVED2 S3C2410_IRQ(61)
#define IRQ_TIMER3 S3C2410_IRQ(62)
#define IRQ_TIMER4 S3C2410_IRQ(63)
#define IRQ_WDT S3C2410_IRQ(64)
#define IRQ_BATFLT S3C2410_IRQ(65)
#define IRQ_POST S3C2410_IRQ(66)
#define IRQ_DISP_FIFO S3C2410_IRQ(67)
#define IRQ_PENUP S3C2410_IRQ(68)
#define IRQ_PENDN S3C2410_IRQ(69)
#define IRQ_ADC S3C2410_IRQ(70)
#define IRQ_DISP_FRAME S3C2410_IRQ(71)
#define IRQ_NFLASH S3C2410_IRQ(72)
#define IRQ_AC97 S3C2410_IRQ(73)
#define IRQ_SPI1 S3C2410_IRQ(74)
#define IRQ_VLX S3C2410_IRQ(75)
#define IRQ_DMA0 S3C2410_IRQ(76)
#define IRQ_DMA1 S3C2410_IRQ(77)
#define IRQ_DMA2 S3C2410_IRQ(78)
#define IRQ_DMA3 S3C2410_IRQ(79)
#define IRQ_TC (0x0)
#define NR_IRQS (IRQ_DMA3+1)
#endif /* __ASM_ARCH_24A0_IRQS_H */
/* linux/arch/arm/mach-s3c24a0/include/mach/map.h
*
* Copyright 2003,2007 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* S3C24A0 - Memory map definitions
*
* 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.
*/
#ifndef __ASM_ARCH_24A0_MAP_H
#define __ASM_ARCH_24A0_MAP_H __FILE__
#include <plat/map-base.h>
#include <plat/map.h>
#define S3C24A0_PA_IO_BASE (0x40000000)
#define S3C24A0_PA_CLKPWR (0x40000000)
#define S3C24A0_PA_IRQ (0x40200000)
#define S3C24A0_PA_DMA (0x40400000)
#define S3C24A0_PA_MEMCTRL (0x40C00000)
#define S3C24A0_PA_NAND (0x40C00000)
#define S3C24A0_PA_SROM (0x40C20000)
#define S3C24A0_PA_SDRAM (0x40C40000)
#define S3C24A0_PA_BUSM (0x40CE0000)
#define S3C24A0_PA_USBHOST (0x41000000)
#define S3C24A0_PA_MODEMIF (0x41180000)
#define S3C24A0_PA_IRDA (0x41800000)
#define S3C24A0_PA_TIMER (0x44000000)
#define S3C24A0_PA_WATCHDOG (0x44100000)
#define S3C24A0_PA_RTC (0x44200000)
#define S3C24A0_PA_UART (0x44400000)
#define S3C24A0_PA_UART0 (S3C24A0_PA_UART)
#define S3C24A0_PA_UART1 (S3C24A0_PA_UART + 0x4000)
#define S3C24A0_PA_SPI (0x44500000)
#define S3C24A0_PA_IIC (0x44600000)
#define S3C24A0_PA_IIS (0x44700000)
#define S3C24A0_PA_GPIO (0x44800000)
#define S3C24A0_PA_KEYIF (0x44900000)
#define S3C24A0_PA_USBDEV (0x44A00000)
#define S3C24A0_PA_AC97 (0x45000000)
#define S3C24A0_PA_ADC (0x45800000)
#define S3C24A0_PA_SDI (0x46000000)
#define S3C24A0_PA_MS (0x46100000)
#define S3C24A0_PA_LCD (0x4A000000)
#define S3C24A0_PA_VPOST (0x4A100000)
/* physical addresses of all the chip-select areas */
#define S3C24A0_CS0 (0x00000000)
#define S3C24A0_CS1 (0x04000000)
#define S3C24A0_CS2 (0x08000000)
#define S3C24A0_CS3 (0x0C000000)
#define S3C24A0_CS4 (0x10000000)
#define S3C24A0_CS5 (0x40000000)
#define S3C24A0_SDRAM_PA (S3C24A0_CS4)
/* Use a single interface for common resources between S3C24XX cpus */
#define S3C24XX_PA_IRQ S3C24A0_PA_IRQ
#define S3C24XX_PA_MEMCTRL S3C24A0_PA_MEMCTRL
#define S3C24XX_PA_USBHOST S3C24A0_PA_USBHOST
#define S3C24XX_PA_DMA S3C24A0_PA_DMA
#define S3C24XX_PA_CLKPWR S3C24A0_PA_CLKPWR
#define S3C24XX_PA_LCD S3C24A0_PA_LCD
#define S3C24XX_PA_UART S3C24A0_PA_UART
#define S3C24XX_PA_TIMER S3C24A0_PA_TIMER
#define S3C24XX_PA_USBDEV S3C24A0_PA_USBDEV
#define S3C24XX_PA_WATCHDOG S3C24A0_PA_WATCHDOG
#define S3C24XX_PA_IIC S3C24A0_PA_IIC
#define S3C24XX_PA_IIS S3C24A0_PA_IIS
#define S3C24XX_PA_GPIO S3C24A0_PA_GPIO
#define S3C24XX_PA_RTC S3C24A0_PA_RTC
#define S3C24XX_PA_ADC S3C24A0_PA_ADC
#define S3C24XX_PA_SPI S3C24A0_PA_SPI
#define S3C24XX_PA_SDI S3C24A0_PA_SDI
#define S3C24XX_PA_NAND S3C24A0_PA_NAND
#define S3C_PA_UART S3C24A0_PA_UART
#endif /* __ASM_ARCH_24A0_MAP_H */
/* linux/arch/arm/mach-s3c24a0/include/mach/memory.h
* from linux/include/asm-arm/arch-rpc/memory.h
*
* Copyright (C) 1996,1997,1998 Russell King.
*
* 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.
*/
#ifndef __ASM_ARCH_24A0_MEMORY_H
#define __ASM_ARCH_24A0_MEMORY_H __FILE__
#define PHYS_OFFSET UL(0x10000000)
#define __virt_to_bus(x) __virt_to_phys(x)
#define __bus_to_virt(x) __phys_to_virt(x)
#endif
/* linux/arch/arm/mach-s3c24a0/include/mach/regs-clock.h
*
* Copyright (c) 2003,2004,2005,2006 Simtec Electronics <linux@simtec.co.uk>
* http://armlinux.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.
*
* S3C24A0 clock register definitions
*/
#ifndef __ASM_ARCH_24A0_REGS_CLOCK_H
#define __ASM_ARCH_24A0_REGS_CLOCK_H __FILE__
#define S3C24A0_MPLLCON S3C2410_CLKREG(0x10)
#define S3C24A0_UPLLCON S3C2410_CLKREG(0x14)
#define S3C24A0_CLKCON S3C2410_CLKREG(0x20)
#define S3C24A0_CLKSRC S3C2410_CLKREG(0x24)
#define S3C24A0_CLKDIVN S3C2410_CLKREG(0x28)
/* CLKCON register bits */
#define S3C24A0_CLKCON_VLX (1<<29)
#define S3C24A0_CLKCON_VPOST (1<<28)
#define S3C24A0_CLKCON_WDT (1<<27) /* reserved */
#define S3C24A0_CLKCON_MPEGDCTQ (1<<26)
#define S3C24A0_CLKCON_VPOSTIF (1<<25)
#define S3C24A0_CLKCON_MPEG4IF (1<<24)
#define S3C24A0_CLKCON_CAM_UPLL (1<<23)
#define S3C24A0_CLKCON_LCDC (1<<22)
#define S3C24A0_CLKCON_CAM_HCLK (1<<21)
#define S3C24A0_CLKCON_MPEG4 (1<<20)
#define S3C24A0_CLKCON_KEYPAD (1<<19)
#define S3C24A0_CLKCON_ADC (1<<18)
#define S3C24A0_CLKCON_SDI (1<<17)
#define S3C24A0_CLKCON_MS (1<<16) /* memory stick */
#define S3C24A0_CLKCON_USBD (1<<15)
#define S3C24A0_CLKCON_GPIO (1<<14)
#define S3C24A0_CLKCON_IIS (1<<13)
#define S3C24A0_CLKCON_IIC (1<<12)
#define S3C24A0_CLKCON_SPI (1<<11)
#define S3C24A0_CLKCON_UART1 (1<<10)
#define S3C24A0_CLKCON_UART0 (1<<9)
#define S3C24A0_CLKCON_PWMT (1<<8)
#define S3C24A0_CLKCON_USBH (1<<7)
#define S3C24A0_CLKCON_AC97 (1<<6)
#define S3C24A0_CLKCON_IrDA (1<<4)
#define S3C24A0_CLKCON_IDLE (1<<2)
#define S3C24A0_CLKCON_MON (1<<1)
#define S3C24A0_CLKCON_STOP (1<<0)
/* CLKSRC register bits */
#define S3C24A0_CLKSRC_OSC (1<<8) /* CLKSRC */
#define S3C24A0_CLKSRC_UPLL (1<<7)
#define S3C24A0_CLKSRC_MPLL (1<<5)
#define S3C24A0_CLKSRC_EXT (1<<4)
/* Use a single interface with the common code, for s3c24xx */
#define S3C2410_MPLLCON S3C24A0_MPLLCON
#define S3C2410_UPLLCON S3C24A0_UPLLCON
#define S3C2410_CLKCON S3C24A0_CLKCON
#define S3C2410_CLKSLOW S3C24A0_CLKSRC
#define S3C2410_CLKDIVN S3C24A0_CLKDIVN
#define S3C2410_CLKCON_IDLE S3C24A0_CLKCON_IDLE
#define S3C2410_CLKCON_POWER S3C24A0_CLKCON_STOP
#define S3C2410_CLKCON_LCDC S3C24A0_CLKCON_LCDC
#define S3C2410_CLKCON_USBH S3C24A0_CLKCON_USBH
#define S3C2410_CLKCON_USBD S3C24A0_CLKCON_USBD
#define S3C2410_CLKCON_PWMT S3C24A0_CLKCON_PWMT
#define S3C2410_CLKCON_SDI S3C24A0_CLKCON_SDI
#define S3C2410_CLKCON_UART0 S3C24A0_CLKCON_UART0
#define S3C2410_CLKCON_UART1 S3C24A0_CLKCON_UART1
#define S3C2410_CLKCON_GPIO S3C24A0_CLKCON_GPIO
#define S3C2410_CLKCON_ADC S3C24A0_CLKCON_ADC
#define S3C2410_CLKCON_IIC S3C24A0_CLKCON_IIC
#define S3C2410_CLKCON_IIS S3C24A0_CLKCON_IIS
#define S3C2410_CLKCON_SPI S3C24A0_CLKCON_SPI
#define S3C2410_CLKSLOW_UCLK_OFF S3C24A0_CLKSRC_UPLL
#define S3C2410_CLKSLOW_MPLL_OFF S3C24A0_CLKSRC_MPLL
#define S3C2410_CLKSLOW_SLOW (0xFF)
#define S3C2410_CLKSLOW_GET_SLOWVAL(x) (0x1)
#endif /* __ASM_ARCH_24A0_REGS_CLOCK_H */
/* linux/arch/arm/mach-s3c24a0/include/mach/regs-irq.h
*
* Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
* http://www.simtec.co.uk/products/SWLINUX/
*
* 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.
*/
#ifndef ___ASM_ARCH_24A0_REGS_IRQ_H
#define ___ASM_ARCH_24A0_REGS_IRQ_H __FILE__
#define S3C2410_EINTMASK S3C2410_EINTREG(0x034)
#define S3C2410_EINTPEND S3C2410_EINTREG(0X038)
#define S3C24XX_EINTMASK S3C24XX_EINTREG(0x034)
#define S3C24XX_EINTPEND S3C24XX_EINTREG(0X038)
#endif /* __ASM_ARCH_24A0_REGS_IRQ_H */
/* linux/arch/arm/mach-s3c24a0/include/mach/system.h
*
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C24A0 - System function defines and includes
*
* 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 <mach/hardware.h>
#include <asm/io.h>
#include <mach/map.h>
static void arch_idle(void)
{
/* currently no specific idle support. */
}
void (*s3c24xx_reset_hook)(void);
#include <asm/plat-s3c24xx/system-reset.h>
/* linux/arch/arm/mach-s3c24a0/include/mach/tick.h
*
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C24A0 - timer tick support
*/
#define SUBSRC_TIMER4 (1 << (IRQ_TIMER4 - IRQ_S3CUART_RX0))
static inline int s3c24xx_ostimer_pending(void)
{
return __raw_readl(S3C2410_SUBSRCPND) & SUBSRC_TIMER4;
}
/* linux/arch/arm/mach-s3c24a0/include/mach/timex.h
*
* Copyright (c) 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 - time parameters
*
* 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.
*/
#ifndef __ASM_ARCH_TIMEX_H
#define __ASM_ARCH_TIMEX_H
#define CLOCK_TICK_RATE 12000000
#endif /* __ASM_ARCH_TIMEX_H */
/* linux/include/asm-arm/arch-s3c24ao/vmalloc.h
*
* Copyright 2008 Simtec Electronics <linux@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.
*
* S3C24A0 vmalloc definition
*/
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END (0xE0000000)
#endif /* __ASM_ARCH_VMALLOC_H */
# arch/arm/mach-s3c6400/Kconfig
#
# Copyright 2008 Openmoko, Inc.
# Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
#
# Licensed under GPLv2
# Currently nothing here, this will be added later
# arch/arm/mach-s3c6400/Makefile
#
# Copyright 2008 Openmoko, Inc.
# Copyright 2008 Simtec Electronics
#
# Licensed under GPLv2
obj-y :=
obj-m :=
obj-n :=
obj- :=
# Core support for S3C6400 system
obj-n += blank.o
zreladdr-y := 0x50008000
params_phys-y := 0x50000100
/* arch/arm/mach-s3c6400/include/mach/debug-macro.S
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* 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.
*/
/* pull in the relevant register and map files. */
#include <mach/map.h>
#include <plat/regs-serial.h>
/* note, for the boot process to work we have to keep the UART
* virtual address aligned to an 1MiB boundary for the L1
* mapping the head code makes. We keep the UART virtual address
* aligned and add in the offset when we load the value here.
*/
.macro addruart, rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1
ldreq \rx, = S3C_PA_UART
ldrne \rx, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
#if CONFIG_DEBUG_S3C_UART != 0
add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
#endif
.endm
/* include the reset of the code which will do the work, we're only
* compiling for a single cpu processor type so the default of s3c2440
* will be fine with us.
*/
#include <plat/debug-macro.S>
/* linux/arch/arm/mach-s3c6400/include/mach/dma.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C6400 - DMA support
*/
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H __FILE__
/* currently nothing here, placeholder */
#endif /* __ASM_ARCH_IRQ_H */
/* arch/arm/mach-s3c6400/include/mach/entry-macro.S
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* Low-level IRQ helper macros for the Samsung S3C64XX series
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <asm/hardware/vic.h>
#include <mach/map.h>
#include <plat/irqs.h>
.macro disable_fiq
.endm
.macro get_irqnr_preamble, base, tmp
ldr \base, =S3C_VA_VIC0
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
@ check the vic0
mov \irqnr, # S3C_IRQ_OFFSET + 31
ldr \irqstat, [ \base, # VIC_IRQ_STATUS ]
teq \irqstat, #0
@ otherwise try vic1
addeq \tmp, \base, #(S3C_VA_VIC1 - S3C_VA_VIC0)
addeq \irqnr, \irqnr, #32
ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
teqeq \irqstat, #0
clzne \irqstat, \irqstat
subne \irqnr, \irqnr, \irqstat
.endm
/* arch/arm/mach-s3c6400/include/mach/gpio.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* S3C6400 - GPIO lib 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.
*/
#define gpio_get_value __gpio_get_value
#define gpio_set_value __gpio_set_value
#define gpio_cansleep __gpio_cansleep
#define gpio_to_irq __gpio_to_irq
#define ARCH_NR_GPIOS 188
#include <asm-generic/gpio.h>
/* linux/arch/arm/mach-s3c6400/include/mach/hardware.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C6400 - Hardware support
*/
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H __FILE__
/* currently nothing here, placeholder */
#endif /* __ASM_ARCH_IRQ_H */
/* linux/arch/arm/mach-s3c6400/include/mach/irqs.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C6400 - IRQ definitions
*/
#ifndef __ASM_ARCH_IRQS_H
#define __ASM_ARCH_IRQS_H __FILE__
#ifndef __ASM_ARM_IRQ_H
#error "Do not include this directly, instead #include <asm/irq.h>"
#endif
#include <plat/irqs.h>
#endif /* __ASM_ARCH_IRQ_H */
/* linux/arch/arm/mach-s3c6400/include/mach/map.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* S3C64XX - Memory map definitions
*
* 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.
*/
#ifndef __ASM_ARCH_MAP_H
#define __ASM_ARCH_MAP_H __FILE__
#include <plat/map-base.h>
#define S3C_PA_UART (0x7F005000)
#define S3C_PA_UART0 (S3C_PA_UART + 0x00)
#define S3C_PA_UART1 (S3C_PA_UART + 0x400)
#define S3C_PA_UART2 (S3C_PA_UART + 0x800)
#define S3C_PA_UART3 (S3C_PA_UART + 0xC00)
#define S3C_UART_OFFSET (0x400)
/* See notes on UART VA mapping in debug-macro.S */
#define S3C_VA_UARTx(x) (S3C_VA_UART + (S3C_PA_UART & 0xfffff) + ((x) * S3C_UART_OFFSET))
#define S3C_VA_UART0 S3C_VA_UARTx(0)
#define S3C_VA_UART1 S3C_VA_UARTx(1)
#define S3C_VA_UART2 S3C_VA_UARTx(2)
#define S3C_VA_UART3 S3C_VA_UARTx(3)
#define S3C64XX_PA_SYSCON (0x7E00F000)
#define S3C64XX_PA_TIMER (0x7F006000)
#define S3C64XX_PA_GPIO (0x7F008000)
#define S3C64XX_VA_GPIO S3C_ADDR(0x00500000)
#define S3C64XX_SZ_GPIO SZ_4K
#define S3C64XX_PA_SDRAM (0x50000000)
#define S3C64XX_PA_VIC0 (0x71200000)
#define S3C64XX_PA_VIC1 (0x71300000)
/* place VICs close together */
#define S3C_VA_VIC0 (S3C_VA_IRQ + 0x00)
#define S3C_VA_VIC1 (S3C_VA_IRQ + 0x10000)
/* compatibiltiy defines. */
#define S3C_PA_TIMER S3C64XX_PA_TIMER
#endif /* __ASM_ARCH_6400_MAP_H */
/* arch/arm/mach-s3c6400/include/mach/memory.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.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.
*/
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
#define PHYS_OFFSET UL(0x50000000)
#define __virt_to_bus(x) __virt_to_phys(x)
#define __bus_to_virt(x) __phys_to_virt(x)
#endif
/* linux/arch/arm/mach-s3c6400/include/mach/pwm-clock.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64xx - pwm clock and timer support
*/
/**
* pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
* @tcfg: The timer TCFG1 register bits shifted down to 0.
*
* Return true if the given configuration from TCFG1 is a TCLK instead
* any of the TDIV clocks.
*/
static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
{
return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
}
/**
* tcfg_to_divisor() - convert tcfg1 setting to a divisor
* @tcfg1: The tcfg1 setting, shifted down.
*
* Get the divisor value for the given tcfg1 setting. We assume the
* caller has already checked to see if this is not a TCLK source.
*/
static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
{
return 1 << tcfg1;
}
/**
* pwm_tdiv_has_div1() - does the tdiv setting have a /1
*
* Return true if we have a /1 in the tdiv setting.
*/
static inline unsigned int pwm_tdiv_has_div1(void)
{
return 1;
}
/**
* pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
* @div: The divisor to calculate the bit information for.
*
* Turn a divisor into the necessary bit field for TCFG1.
*/
static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
{
return ilog2(div);
}
#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
/* linux/arch/arm/mach-s3c6400/include/mach/regs-irq.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* S3C64XX - IRQ register definitions
*
* 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.
*/
#ifndef __ASM_ARCH_REGS_IRQ_H
#define __ASM_ARCH_REGS_IRQ_H __FILE__
#include <asm/hardware/vic.h>
#endif /* __ASM_ARCH_6400_REGS_IRQ_H */
/* linux/arch/arm/mach-s3c6400/include/mach/system.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C6400 - system implementation
*/
#ifndef __ASM_ARCH_SYSTEM_H
#define __ASM_ARCH_SYSTEM_H __FILE__
static void arch_idle(void)
{
/* nothing here yet */
}
static void arch_reset(char mode)
{
/* nothing here yet */
}
#endif /* __ASM_ARCH_IRQ_H */
/* linux/arch/arm/mach-s3c6400/include/mach/tick.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* S3C64XX - Timer tick support definitions
*
* 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.
*/
#ifndef __ASM_ARCH_TICK_H
#define __ASM_ARCH_TICK_H __FILE__
/* note, the timer interrutps turn up in 2 places, the vic and then
* the timer block. We take the VIC as the base at the moment.
*/
static inline u32 s3c24xx_ostimer_pending(void)
{
u32 pend = __raw_readl(S3C_VA_VIC0 + VIC_RAW_STATUS);
return pend & 1 << (IRQ_TIMER4_VIC - S3C64XX_IRQ_VIC0(0));
}
#define TICK_MAX (0xffffffff)
#endif /* __ASM_ARCH_6400_TICK_H */
/* arch/arm/mach-s3c6400/include/mach/uncompress.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* S3C6400 - uncompress code
*
* 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.
*/
#ifndef __ASM_ARCH_UNCOMPRESS_H
#define __ASM_ARCH_UNCOMPRESS_H
#include <mach/map.h>
#include <plat/uncompress.h>
static void arch_detect_cpu(void)
{
/* we do not need to do any cpu detection here at the moment. */
fifo_mask = S3C2440_UFSTAT_TXMASK;
fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
}
#endif /* __ASM_ARCH_UNCOMPRESS_H */
# arch/arm/mach-s3c6410/Kconfig
#
# Copyright 2008 Openmoko, Inc.
# Copyright 2008 Simtec Electronics
#
# Licensed under GPLv2
# Configuration options for the S3C6410 CPU
config CPU_S3C6410
bool
select CPU_S3C6400_INIT
select CPU_S3C6400_CLOCK
help
Enable S3C6410 CPU support
config MACH_SMDK6410
bool "SMDK6410"
select CPU_S3C6410
help
Machine support for the Samsung SMDK6410
# arch/arm/plat-s3c6410/Makefile
#
# Copyright 2008 Openmoko, Inc.
# Copyright 2008 Simtec Electronics
#
# Licensed under GPLv2
obj-y :=
obj-m :=
obj-n :=
obj- :=
# Core support for S3C6410 system
obj-$(CONFIG_CPU_S3C6410) += cpu.o
# machine support
obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o
/* linux/arch/arm/mach-s3c6410/cpu.c
*
* Copyright 2008 Simtec Electronics
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.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.
*/
#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/clk.h>
#include <linux/io.h>
#include <linux/sysdev.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <plat/cpu-freq.h>
#include <plat/regs-serial.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/clock.h>
#include <plat/s3c6400.h>
#include <plat/s3c6410.h>
/* Initial IO mappings */
static struct map_desc s3c6410_iodesc[] __initdata = {
};
/* s3c6410_map_io
*
* register the standard cpu IO areas
*/
void __init s3c6410_map_io(void)
{
iotable_init(s3c6410_iodesc, ARRAY_SIZE(s3c6410_iodesc));
}
void __init s3c6410_init_clocks(int xtal)
{
printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
s3c24xx_register_baseclocks(xtal);
s3c64xx_register_clocks();
s3c6400_register_clocks();
s3c6400_setup_clocks();
}
void __init s3c6410_init_irq(void)
{
/* VIC0 is missing IRQ7, VIC1 is fully populated. */
s3c64xx_init_irq(~0 & ~(1 << 7), ~0);
}
struct sysdev_class s3c6410_sysclass = {
.name = "s3c6410-core",
};
static struct sys_device s3c6410_sysdev = {
.cls = &s3c6410_sysclass,
};
static int __init s3c6410_core_init(void)
{
return sysdev_class_register(&s3c6410_sysclass);
}
core_initcall(s3c6410_core_init);
int __init s3c6410_init(void)
{
printk("S3C6410: Initialising architecture\n");
return sysdev_register(&s3c6410_sysdev);
}
/* linux/arch/arm/mach-s3c6410/mach-smdk6410.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.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.
*
*/
#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/serial_core.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <plat/regs-serial.h>
#include <plat/s3c6410.h>
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
#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 smdk6410_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x51,
},
[1] = {
.hwport = 1,
.flags = 0,
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x51,
},
};
struct map_desc smdk6410_iodesc[] = {};
static struct platform_device *smdk6410_devices[] __initdata = {
};
static void __init smdk6410_map_io(void)
{
s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));
}
static void __init smdk6410_machine_init(void)
{
platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
}
MACHINE_START(SMDK6410, "SMDK6410")
/* Maintainer: Ben Dooks <ben@fluff.org> */
.phys_io = S3C_PA_UART & 0xfff00000,
.io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C64XX_PA_SDRAM + 0x100,
.init_irq = s3c6410_init_irq,
.map_io = smdk6410_map_io,
.init_machine = smdk6410_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END
......@@ -6,8 +6,8 @@
config PLAT_S3C
bool
depends on ARCH_S3C2410
default y if ARCH_S3C2410
depends on ARCH_S3C2410 || ARCH_S3C24A0 || ARCH_S3C64XX
default y
select NO_IOPORT
help
Base platform code for any Samsung S3C device
......@@ -16,24 +16,24 @@ config PLAT_S3C
config CPU_LLSERIAL_S3C2410_ONLY
bool
depends on ARCH_S3C2410
depends on PLAT_S3C
default y if CPU_LLSERIAL_S3C2410 && !CPU_LLSERIAL_S3C2440
config CPU_LLSERIAL_S3C2440_ONLY
bool
depends on ARCH_S3C2410
depends on PLAT_S3C
default y if CPU_LLSERIAL_S3C2440 && !CPU_LLSERIAL_S3C2410
config CPU_LLSERIAL_S3C2410
bool
depends on ARCH_S3C2410
depends on PLAT_S3C
help
Selected if there is an S3C2410 (or register compatible) serial
low-level implementation needed
config CPU_LLSERIAL_S3C2440
bool
depends on ARCH_S3C2410
depends on PLAT_S3C
help
Selected if there is an S3C2440 (or register compatible) serial
low-level implementation needed
......
......@@ -239,6 +239,16 @@ struct clk clk_xtal = {
.ctrlbit = 0,
};
struct clk clk_ext = {
.name = "ext",
.id = -1,
};
struct clk clk_epll = {
.name = "epll",
.id = -1,
};
struct clk clk_mpll = {
.name = "mpll",
.id = -1,
......
......@@ -45,7 +45,13 @@ extern struct clk clk_h;
extern struct clk clk_p;
extern struct clk clk_mpll;
extern struct clk clk_upll;
extern struct clk clk_epll;
extern struct clk clk_xtal;
extern struct clk clk_ext;
/* S3C64XX specific clocks */
extern struct clk clk_27m;
extern struct clk clk_48m;
/* exports for arch/arm/mach-s3c2410
*
......@@ -61,6 +67,8 @@ extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
extern int s3c24xx_register_baseclocks(unsigned long xtal);
extern void s3c64xx_register_clocks(void);
extern void s3c24xx_setup_clocks(unsigned long fclk,
unsigned long hclk,
unsigned long pclk);
......@@ -70,3 +78,11 @@ extern void s3c2412_setup_clocks(void);
extern void s3c244x_setup_clocks(void);
extern void s3c2443_setup_clocks(void);
/* S3C64XX specific functions and clocks */
extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
/* Init for pwm clock code */
extern void s3c_pwmclk_init(void);
......@@ -44,8 +44,10 @@ extern void s3c_init_cpu(unsigned long idcode,
/* core initialisation functions */
extern void s3c24xx_init_irq(void);
extern void s3c64xx_init_irq(u32 vic0, u32 vic1);
extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
extern void s3c64xx_init_io(struct map_desc *mach_desc, int size);
extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
......
......@@ -20,7 +20,7 @@
.endm
#ifndef fifo_level
#define fifo_level fifo_level_s3c2410
#define fifo_level fifo_level_s3c2440
#endif
.macro fifo_full_s3c2440 rd, rx
......
......@@ -17,6 +17,7 @@ struct s3c24xx_uart_resources {
};
extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
extern struct s3c24xx_uart_resources s3c64xx_uart_resources[];
extern struct platform_device *s3c24xx_uart_devs[];
extern struct platform_device *s3c24xx_uart_src[];
......
......@@ -77,6 +77,12 @@
#define S3C2440_UCON_FCLK (3<<10)
#define S3C2443_UCON_EPLL (3<<10)
#define S3C6400_UCON_CLKMASK (3<<10)
#define S3C6400_UCON_PCLK (0<<10)
#define S3C6400_UCON_PCLK2 (2<<10)
#define S3C6400_UCON_UCLK0 (1<<10)
#define S3C6400_UCON_UCLK1 (3<<10)
#define S3C2440_UCON2_FCLK_EN (1<<15)
#define S3C2440_UCON0_DIVMASK (15 << 12)
#define S3C2440_UCON1_DIVMASK (15 << 12)
......@@ -149,6 +155,14 @@
#define S3C2410_UFSTAT_RXMASK (15<<0)
#define S3C2410_UFSTAT_RXSHIFT (0)
/* UFSTAT S3C24A0 */
#define S3C24A0_UFSTAT_TXFULL (1 << 14)
#define S3C24A0_UFSTAT_RXFULL (1 << 6)
#define S3C24A0_UFSTAT_TXMASK (63 << 8)
#define S3C24A0_UFSTAT_TXSHIFT (8)
#define S3C24A0_UFSTAT_RXMASK (63)
#define S3C24A0_UFSTAT_RXSHIFT (0)
/* UFSTAT S3C2443 same as S3C2440 */
#define S3C2440_UFSTAT_TXFULL (1<<14)
#define S3C2440_UFSTAT_RXFULL (1<<6)
......
......@@ -10,7 +10,6 @@
* S3C2410 Timer configuration
*/
#ifndef __ASM_ARCH_REGS_TIMER_H
#define __ASM_ARCH_REGS_TIMER_H
......@@ -21,6 +20,8 @@
#define S3C2410_TCFG1 S3C_TIMERREG(0x04)
#define S3C2410_TCON S3C_TIMERREG(0x08)
#define S3C64XX_TINT_CSTAT S3C_TIMERREG(0x44)
#define S3C2410_TCFG_PRESCALER0_MASK (255<<0)
#define S3C2410_TCFG_PRESCALER1_MASK (255<<8)
#define S3C2410_TCFG_PRESCALER1_SHIFT (8)
......@@ -72,6 +73,14 @@
#define S3C2410_TCFG1_MUX_TCLK (4<<0)
#define S3C2410_TCFG1_MUX_MASK (15<<0)
#define S3C64XX_TCFG1_MUX_DIV1 (0<<0)
#define S3C64XX_TCFG1_MUX_DIV2 (1<<0)
#define S3C64XX_TCFG1_MUX_DIV4 (2<<0)
#define S3C64XX_TCFG1_MUX_DIV8 (3<<0)
#define S3C64XX_TCFG1_MUX_DIV16 (4<<0)
#define S3C64XX_TCFG1_MUX_TCLK (5<<0) /* 3 sets of TCLK */
#define S3C64XX_TCFG1_MUX_MASK (15<<0)
#define S3C2410_TCFG1_SHIFT(x) ((x) * 4)
/* for each timer, we have an count buffer, an compare buffer and
......
......@@ -37,7 +37,7 @@ static void arch_detect_cpu(void);
/* how many bytes we allow into the FIFO at a time in FIFO mode */
#define FIFO_MAX (14)
#define uart_base S3C24XX_PA_UART + (0x4000*CONFIG_S3C_LOWLEVEL_UART_PORT)
#define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
static __inline__ void
uart_wr(unsigned int reg, unsigned int val)
......
......@@ -14,20 +14,20 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/log2.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <asm/irq.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <plat/clock.h>
#include <plat/cpu.h>
#include <plat/regs-timer.h>
#include <mach/pwm-clock.h>
/* Each of the timers 0 through 5 go through the following
* clock tree, with the inputs depending on the timers.
......@@ -168,11 +168,6 @@ static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk)
return container_of(clk, struct pwm_tdiv_clk, clk);
}
static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
{
return 1 << (1 + tcfg1);
}
static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk)
{
unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
......@@ -181,7 +176,7 @@ static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk)
tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
tcfg1 &= S3C2410_TCFG1_MUX_MASK;
if (tcfg1 == S3C2410_TCFG1_MUX_TCLK)
if (pwm_cfg_src_is_tclk(tcfg1))
divisor = to_tdiv(clk)->divisor;
else
divisor = tcfg_to_divisor(tcfg1);
......@@ -198,7 +193,9 @@ static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk,
parent_rate = clk_get_rate(clk->parent);
divisor = parent_rate / rate;
if (divisor <= 2)
if (divisor <= 1 && pwm_tdiv_has_div1())
divisor = 1;
else if (divisor <= 2)
divisor = 2;
else if (divisor <= 4)
divisor = 4;
......@@ -212,25 +209,7 @@ static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk,
static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk)
{
unsigned long bits;
switch (divclk->divisor) {
case 2:
bits = S3C2410_TCFG1_MUX_DIV2;
break;
case 4:
bits = S3C2410_TCFG1_MUX_DIV4;
break;
case 8:
bits = S3C2410_TCFG1_MUX_DIV8;
break;
case 16:
default:
bits = S3C2410_TCFG1_MUX_DIV16;
break;
}
return bits;
return pwm_tdiv_div_bits(divclk->divisor);
}
static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk)
......@@ -271,7 +250,7 @@ static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate)
/* Update the current MUX settings if we are currently
* selected as the clock source for this clock. */
if (tcfg1 != S3C2410_TCFG1_MUX_TCLK)
if (!pwm_cfg_src_is_tclk(tcfg1))
clk_pwm_tdiv_update(divclk);
return 0;
......@@ -358,7 +337,7 @@ static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
unsigned long shift = S3C2410_TCFG1_SHIFT(id);
if (parent == s3c24xx_pwmclk_tclk(id))
bits = S3C2410_TCFG1_MUX_TCLK << shift;
bits = S3C_TCFG1_MUX_TCLK << shift;
else if (parent == s3c24xx_pwmclk_tdiv(id))
bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
else
......@@ -420,7 +399,7 @@ static __init int clk_pwm_tin_register(struct clk *pwm)
tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
tcfg1 &= S3C2410_TCFG1_MUX_MASK;
if (tcfg1 == S3C2410_TCFG1_MUX_TCLK)
if (pwm_cfg_src_is_tclk(tcfg1))
parent = s3c24xx_pwmclk_tclk(id);
else
parent = s3c24xx_pwmclk_tdiv(id);
......@@ -428,7 +407,16 @@ static __init int clk_pwm_tin_register(struct clk *pwm)
return clk_set_parent(pwm, parent);
}
static __init int s3c24xx_pwmclk_init(void)
/**
* s3c_pwmclk_init() - initialise pwm clocks
*
* Initialise and register the clocks which provide the inputs for the
* pwm timer blocks.
*
* Note, this call is required by the time core, so must be called after
* the base clocks are added and before any of the initcalls are run.
*/
__init void s3c_pwmclk_init(void)
{
struct clk *clk_timers;
unsigned int clk;
......@@ -437,7 +425,7 @@ static __init int s3c24xx_pwmclk_init(void)
clk_timers = clk_get(NULL, "timers");
if (IS_ERR(clk_timers)) {
printk(KERN_ERR "%s: no parent clock\n", __func__);
return -EINVAL;
return;
}
for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++) {
......@@ -445,7 +433,7 @@ static __init int s3c24xx_pwmclk_init(void)
ret = s3c24xx_register_clock(&clk_timer_scaler[clk]);
if (ret < 0) {
printk(KERN_ERR "error adding pwm scaler%d clock\n", clk);
goto err;
return;
}
}
......@@ -453,7 +441,7 @@ static __init int s3c24xx_pwmclk_init(void)
ret = s3c24xx_register_clock(&clk_timer_tclk[clk]);
if (ret < 0) {
printk(KERN_ERR "error adding pww tclk%d\n", clk);
goto err;
return;
}
}
......@@ -461,7 +449,7 @@ static __init int s3c24xx_pwmclk_init(void)
ret = clk_pwm_tdiv_register(clk);
if (ret < 0) {
printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk);
goto err;
return;
}
}
......@@ -469,14 +457,7 @@ static __init int s3c24xx_pwmclk_init(void)
ret = clk_pwm_tin_register(&clk_tin[clk]);
if (ret < 0) {
printk(KERN_ERR "error adding pwm%d tin clock\n", clk);
goto err;
return;
}
}
return 0;
err:
return ret;
}
arch_initcall(s3c24xx_pwmclk_init);
......@@ -26,6 +26,7 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/leds.h>
......@@ -36,6 +37,7 @@
#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <asm/mach/time.h>
#include <mach/tick.h>
#include <plat/clock.h>
#include <plat/cpu.h>
......@@ -43,6 +45,10 @@
static unsigned long timer_startval;
static unsigned long timer_usec_ticks;
#ifndef TICK_MAX
#define TICK_MAX (0xffff)
#endif
#define TIMER_USEC_SHIFT 16
/* we use the shifted arithmetic to work out the ratio of timer ticks
......@@ -91,12 +97,9 @@ static inline unsigned long timer_ticks_to_usec(unsigned long ticks)
* IRQs are disabled before entering here from do_gettimeofday()
*/
#define SRCPND_TIMER4 (1<<(IRQ_TIMER4 - IRQ_EINT0))
static unsigned long s3c2410_gettimeoffset (void)
{
unsigned long tdone;
unsigned long irqpend;
unsigned long tval;
/* work out how many ticks have gone since last timer interrupt */
......@@ -106,8 +109,7 @@ static unsigned long s3c2410_gettimeoffset (void)
/* check to see if there is an interrupt pending */
irqpend = __raw_readl(S3C2410_SRCPND);
if (irqpend & SRCPND_TIMER4) {
if (s3c24xx_ostimer_pending()) {
/* re-read the timer, and try and fix up for the missed
* interrupt. Note, the interrupt may go off before the
* timer has re-loaded from wrapping.
......@@ -146,6 +148,10 @@ static struct irqaction s3c2410_timer_irq = {
machine_is_anubis() || \
machine_is_osiris())
static struct clk *tin;
static struct clk *tdiv;
static struct clk *timerclk;
/*
* Set up timer interrupt, and return the current time in seconds.
*
......@@ -159,13 +165,7 @@ static void s3c2410_timer_setup (void)
unsigned long tcfg1;
unsigned long tcfg0;
tcnt = 0xffff; /* default value for tcnt */
/* read the current timer configuration bits */
tcon = __raw_readl(S3C2410_TCON);
tcfg1 = __raw_readl(S3C2410_TCFG1);
tcfg0 = __raw_readl(S3C2410_TCFG0);
tcnt = TICK_MAX; /* default value for tcnt */
/* configure the system for whichever machine is in use */
......@@ -174,11 +174,13 @@ static void s3c2410_timer_setup (void)
timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
tcnt = 12000000 / HZ;
tcfg1 = __raw_readl(S3C2410_TCFG1);
tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
__raw_writel(tcfg1, S3C2410_TCFG1);
} else {
unsigned long pclk;
struct clk *clk;
struct clk *tscaler;
/* for the h1940 (and others), we use the pclk from the core
* to generate the timer values. since values around 50 to
......@@ -189,29 +191,25 @@ static void s3c2410_timer_setup (void)
* (8.45 ticks per usec)
*/
/* this is used as default if no other timer can be found */
clk = clk_get(NULL, "timers");
if (IS_ERR(clk))
panic("failed to get clock for system timer");
clk_enable(clk);
pclk = clk_get_rate(clk);
pclk = clk_get_rate(timerclk);
/* configure clock tick */
timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
tcfg1 |= S3C2410_TCFG1_MUX4_DIV2;
tscaler = clk_get_parent(tdiv);
tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
tcfg0 |= ((6 - 1) / 2) << S3C2410_TCFG_PRESCALER1_SHIFT;
clk_set_rate(tscaler, pclk / 3);
clk_set_rate(tdiv, pclk / 6);
clk_set_parent(tin, tdiv);
tcnt = (pclk / 6) / HZ;
tcnt = clk_get_rate(tin) / HZ;
}
tcon = __raw_readl(S3C2410_TCON);
tcfg0 = __raw_readl(S3C2410_TCFG0);
tcfg1 = __raw_readl(S3C2410_TCFG1);
/* timers reload after counting zero, so reduce the count by 1 */
tcnt--;
......@@ -220,7 +218,7 @@ static void s3c2410_timer_setup (void)
tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks);
/* check to see if timer is within 16bit range... */
if (tcnt > 0xffff) {
if (tcnt > TICK_MAX) {
panic("setup_timer: HZ is too small, cannot configure timer!");
return;
}
......@@ -247,8 +245,35 @@ static void s3c2410_timer_setup (void)
__raw_writel(tcon, S3C2410_TCON);
}
static void __init s3c2410_timer_resources(void)
{
struct platform_device tmpdev;
tmpdev.dev.bus = &platform_bus_type;
tmpdev.id = 4;
timerclk = clk_get(NULL, "timers");
if (IS_ERR(timerclk))
panic("failed to get clock for system timer");
clk_enable(timerclk);
if (!use_tclk1_12()) {
tin = clk_get(&tmpdev.dev, "pwm-tin");
if (IS_ERR(tin))
panic("failed to get pwm-tin clock for system timer");
tdiv = clk_get(&tmpdev.dev, "pwm-tdiv");
if (IS_ERR(tdiv))
panic("failed to get pwm-tdiv clock for system timer");
}
clk_enable(tin);
}
static void __init s3c2410_timer_init(void)
{
s3c2410_timer_resources();
s3c2410_timer_setup();
setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
}
......
......@@ -6,8 +6,8 @@
config PLAT_S3C24XX
bool
depends on ARCH_S3C2410
default y if ARCH_S3C2410
depends on ARCH_S3C2410 || ARCH_S3C24A0
default y
select NO_IOPORT
select ARCH_REQUIRE_GPIOLIB
help
......
......@@ -192,8 +192,8 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
static struct resource s3c_nand_resource[] = {
[0] = {
.start = S3C2410_PA_NAND,
.end = S3C2410_PA_NAND + S3C24XX_SZ_NAND - 1,
.start = S3C24XX_PA_NAND,
.end = S3C24XX_PA_NAND + S3C24XX_SZ_NAND - 1,
.flags = IORESOURCE_MEM,
}
};
......@@ -390,8 +390,8 @@ struct platform_device s3c_device_hwmon = {
static struct resource s3c_sdi_resource[] = {
[0] = {
.start = S3C2410_PA_SDI,
.end = S3C2410_PA_SDI + S3C24XX_SZ_SDI - 1,
.start = S3C24XX_PA_SDI,
.end = S3C24XX_PA_SDI + S3C24XX_SZ_SDI - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
......
/* linux/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
*
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C24xx - pwm clock and timer support
*/
/**
* pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
* @cfg: The timer TCFG1 register bits shifted down to 0.
*
* Return true if the given configuration from TCFG1 is a TCLK instead
* any of the TDIV clocks.
*/
static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
{
return tcfg == S3C2410_TCFG1_MUX_TCLK;
}
/**
* tcfg_to_divisor() - convert tcfg1 setting to a divisor
* @tcfg1: The tcfg1 setting, shifted down.
*
* Get the divisor value for the given tcfg1 setting. We assume the
* caller has already checked to see if this is not a TCLK source.
*/
static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
{
return 1 << (1 + tcfg1);
}
/**
* pwm_tdiv_has_div1() - does the tdiv setting have a /1
*
* Return true if we have a /1 in the tdiv setting.
*/
static inline unsigned int pwm_tdiv_has_div1(void)
{
return 0;
}
/**
* pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
* @div: The divisor to calculate the bit information for.
*
* Turn a divisor into the necessary bit field for TCFG1.
*/
static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
{
return ilog2(div) - 1;
}
#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
/* linux/include/asm-arm/plat-s3c24xx/map.h
*
* Copyright (c) 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C24XX - Memory map definitions
*
* 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.
*/
#ifndef __ASM_PLAT_S3C24XX_MAP_H
#define __ASM_PLAT_S3C24XX_MAP_H
/* interrupt controller is the first thing we put in, to make
* the assembly code for the irq detection easier
*/
#define S3C24XX_VA_IRQ S3C_VA_IRQ
#define S3C2410_PA_IRQ (0x4A000000)
#define S3C24XX_SZ_IRQ SZ_1M
/* memory controller registers */
#define S3C24XX_VA_MEMCTRL S3C_VA_MEM
#define S3C2410_PA_MEMCTRL (0x48000000)
#define S3C24XX_SZ_MEMCTRL SZ_1M
/* UARTs */
#define S3C24XX_VA_UART S3C_VA_UART
#define S3C2410_PA_UART (0x50000000)
#define S3C24XX_SZ_UART SZ_1M
#define S3C_UART_OFFSET (0x4000)
/* Timers */
#define S3C24XX_VA_TIMER S3C_VA_TIMER
#define S3C2410_PA_TIMER (0x51000000)
#define S3C24XX_SZ_TIMER SZ_1M
/* Clock and Power management */
#define S3C24XX_VA_CLKPWR S3C_VA_SYS
#define S3C24XX_SZ_CLKPWR SZ_1M
/* USB Device port */
#define S3C2410_PA_USBDEV (0x52000000)
#define S3C24XX_SZ_USBDEV SZ_1M
/* Watchdog */
#define S3C24XX_VA_WATCHDOG S3C_VA_WATCHDOG
#define S3C2410_PA_WATCHDOG (0x53000000)
#define S3C24XX_SZ_WATCHDOG SZ_1M
/* Standard size definitions for peripheral blocks. */
#define S3C24XX_SZ_IIC SZ_1M
#define S3C24XX_SZ_IIS SZ_1M
#define S3C24XX_SZ_ADC SZ_1M
#define S3C24XX_SZ_SPI SZ_1M
#define S3C24XX_SZ_SDI SZ_1M
#define S3C24XX_SZ_NAND SZ_1M
#define S3C24XX_SZ_USBHOST SZ_1M
/* GPIO ports */
/* the calculation for the VA of this must ensure that
* it is the same distance apart from the UART in the
* phsyical address space, as the initial mapping for the IO
* is done as a 1:1 maping. This puts it (currently) at
* 0xFA800000, which is not in the way of any current mapping
* by the base system.
*/
#define S3C2410_PA_GPIO (0x56000000)
#define S3C24XX_VA_GPIO ((S3C24XX_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART)
#define S3C24XX_SZ_GPIO SZ_1M
/* ISA style IO, for each machine to sort out mappings for, if it
* implements it. We reserve two 16M regions for ISA.
*/
#define S3C24XX_VA_ISA_WORD S3C2410_ADDR(0x02000000)
#define S3C24XX_VA_ISA_BYTE S3C2410_ADDR(0x03000000)
/* deal with the registers that move under the 2412/2413 */
#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
#ifndef __ASSEMBLY__
extern void __iomem *s3c24xx_va_gpio2;
#endif
#ifdef CONFIG_CPU_S3C2412_ONLY
#define S3C24XX_VA_GPIO2 (S3C24XX_VA_GPIO + 0x10)
#else
#define S3C24XX_VA_GPIO2 s3c24xx_va_gpio2
#endif
#else
#define s3c24xx_va_gpio2 S3C24XX_VA_GPIO
#define S3C24XX_VA_GPIO2 S3C24XX_VA_GPIO
#endif
#endif /* __ASM_PLAT_S3C24XX_MAP_H */
......@@ -272,5 +272,6 @@ int __init s3c2410_baseclk_add(void)
(clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
(clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
s3c_pwmclk_init();
return 0;
}
# arch/arm/plat-s3c64xx/Kconfig
#
# Copyright 2008 Openmoko, Inc.
# Copyright 2008 Simtec Electronics
# Ben Dooks <ben@simtec.co.uk>
#
# Licensed under GPLv2
config PLAT_S3C64XX
bool
depends on ARCH_S3C64XX
select PLAT_S3C
select ARM_VIC
default y
select NO_IOPORT
select ARCH_REQUIRE_GPIOLIB
help
Base platform code for any Samsung S3C64XX device
if PLAT_S3C64XX
# Configuration options shared by all S3C64XX implementations
config CPU_S3C6400_INIT
bool
help
Common initialisation code for the S3C6400 that is shared
by other CPUs in the series, such as the S3C6410.
config CPU_S3C6400_CLOCK
bool
help
Common clock support code for the S3C6400 that is shared
by other CPUs in the series, such as the S3C6410.
endif
# arch/arm/plat-s3c64xx/Makefile
#
# Copyright 2008 Openmoko, Inc.
# Copyright 2008 Simtec Electronics
#
# Licensed under GPLv2
obj-y :=
obj-m :=
obj-n := dummy.o
obj- :=
# Core files
obj-y += dev-uart.o
obj-y += cpu.o
obj-y += irq.o
obj-y += irq-eint.o
obj-y += clock.o
# CPU support
obj-$(CONFIG_CPU_S3C6400_INIT) += s3c6400-init.o
obj-$(CONFIG_CPU_S3C6400_CLOCK) += s3c6400-clock.o
/* linux/arch/arm/plat-s3c64xx/clock.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX Base clock 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.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <plat/regs-sys.h>
#include <plat/regs-clock.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/clock.h>
struct clk clk_27m = {
.name = "clk_27m",
.id = -1,
.rate = 27000000,
};
static int clk_48m_ctrl(struct clk *clk, int enable)
{
unsigned long flags;
u32 val;
/* can't rely on clock lock, this register has other usages */
local_irq_save(flags);
val = __raw_readl(S3C64XX_OTHERS);
if (enable)
val |= S3C64XX_OTHERS_USBMASK;
else
val &= ~S3C64XX_OTHERS_USBMASK;
__raw_writel(val, S3C64XX_OTHERS);
local_irq_restore(flags);
return 0;
}
struct clk clk_48m = {
.name = "clk_48m",
.id = -1,
.rate = 48000000,
.enable = clk_48m_ctrl,
};
static int inline s3c64xx_gate(void __iomem *reg,
struct clk *clk,
int enable)
{
unsigned int ctrlbit = clk->ctrlbit;
u32 con;
con = __raw_readl(reg);
if (enable)
con |= ctrlbit;
else
con &= ~ctrlbit;
__raw_writel(con, reg);
return 0;
}
static int s3c64xx_pclk_ctrl(struct clk *clk, int enable)
{
return s3c64xx_gate(S3C_PCLK_GATE, clk, enable);
}
static int s3c64xx_hclk_ctrl(struct clk *clk, int enable)
{
return s3c64xx_gate(S3C_HCLK_GATE, clk, enable);
}
int s3c64xx_sclk_ctrl(struct clk *clk, int enable)
{
return s3c64xx_gate(S3C_SCLK_GATE, clk, enable);
}
static struct clk init_clocks_disable[] = {
{
.name = "nand",
.id = -1,
.parent = &clk_h,
}, {
.name = "adc",
.id = -1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_TSADC,
}, {
.name = "i2c",
.id = -1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_IIC,
}, {
.name = "iis",
.id = 0,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_IIS0,
}, {
.name = "iis",
.id = 1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_IIS1,
}, {
.name = "spi",
.id = 0,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_SPI0,
}, {
.name = "spi",
.id = 1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_SPI1,
}, {
.name = "48m",
.id = 0,
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_MMC0_48,
}, {
.name = "48m",
.id = 1,
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_MMC1_48,
}, {
.name = "48m",
.id = 2,
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_MMC2_48,
},
};
static struct clk init_clocks[] = {
{
.name = "lcd",
.id = -1,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_LCD,
}, {
.name = "gpio",
.id = -1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_GPIO,
}, {
.name = "usb-host",
.id = -1,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_UHOST,
}, {
.name = "hsmmc",
.id = 0,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_HSMMC0,
}, {
.name = "hsmmc",
.id = 1,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_HSMMC1,
}, {
.name = "hsmmc",
.id = 2,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_HSMMC2,
}, {
.name = "timers",
.id = -1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_PWM,
}, {
.name = "uart",
.id = 0,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_UART0,
}, {
.name = "uart",
.id = 1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_UART1,
}, {
.name = "uart",
.id = 2,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_UART2,
}, {
.name = "uart",
.id = 3,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_UART3,
}, {
.name = "rtc",
.id = -1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_RTC,
}, {
.name = "watchdog",
.id = -1,
.parent = &clk_p,
.ctrlbit = S3C_CLKCON_PCLK_WDT,
}, {
.name = "ac97",
.id = -1,
.parent = &clk_p,
.ctrlbit = S3C_CLKCON_PCLK_AC97,
}
};
static struct clk *clks[] __initdata = {
&clk_ext,
&clk_epll,
&clk_27m,
&clk_48m,
};
void s3c64xx_register_clocks(void)
{
struct clk *clkp;
int ret;
int ptr;
s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
clkp = init_clocks;
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);
}
}
clkp = init_clocks_disable;
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
(clkp->enable)(clkp, 0);
}
s3c_pwmclk_init();
}
/* linux/arch/arm/plat-s3c64xx/cpu.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX 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.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <plat/regs-serial.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/clock.h>
#include <plat/s3c6400.h>
#include <plat/s3c6410.h>
/* table of supported CPUs */
static const char name_s3c6400[] = "S3C6400";
static const char name_s3c6410[] = "S3C6410";
static struct cpu_table cpu_ids[] __initdata = {
{
.idcode = 0x36400000,
.idmask = 0xfffff000,
.map_io = s3c6400_map_io,
.init_clocks = s3c6400_init_clocks,
.init_uarts = s3c6400_init_uarts,
.init = s3c6400_init,
.name = name_s3c6400,
}, {
.idcode = 0x36410100,
.idmask = 0xffffff00,
.map_io = s3c6410_map_io,
.init_clocks = s3c6410_init_clocks,
.init_uarts = s3c6410_init_uarts,
.init = s3c6410_init,
.name = name_s3c6410,
},
};
/* minimal IO mapping */
/* see notes on uart map in arch/arm/mach-s3c6400/include/mach/debug-macro.S */
#define UART_OFFS (S3C_PA_UART & 0xfffff)
static struct map_desc s3c_iodesc[] __initdata = {
{
.virtual = (unsigned long)S3C_VA_SYS,
.pfn = __phys_to_pfn(S3C64XX_PA_SYSCON),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)(S3C_VA_UART + UART_OFFS),
.pfn = __phys_to_pfn(S3C_PA_UART),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_VIC0,
.pfn = __phys_to_pfn(S3C64XX_PA_VIC0),
.length = SZ_16K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_VIC1,
.pfn = __phys_to_pfn(S3C64XX_PA_VIC1),
.length = SZ_16K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_TIMER,
.pfn = __phys_to_pfn(S3C_PA_TIMER),
.length = SZ_16K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C64XX_VA_GPIO,
.pfn = __phys_to_pfn(S3C64XX_PA_GPIO),
.length = SZ_4K,
.type = MT_DEVICE,
},
};
/* read cpu identification code */
void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
{
unsigned long idcode;
/* initialise the io descriptors we need for initialisation */
iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
iotable_init(mach_desc, size);
idcode = __raw_readl(S3C_VA_SYS + 0x118);
s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
}
/* linux/arch/arm/plat-s3c64xx/dev-uart.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* Base S3C64XX UART resource and device definitions
*
* 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/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <plat/devs.h>
/* Serial port registrations */
/* 64xx uarts are closer together */
static struct resource s3c64xx_uart0_resource[] = {
[0] = {
.start = S3C_PA_UART0,
.end = S3C_PA_UART0 + 0x100,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX0,
.end = IRQ_S3CUART_RX0,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = IRQ_S3CUART_TX0,
.end = IRQ_S3CUART_TX0,
.flags = IORESOURCE_IRQ,
},
[3] = {
.start = IRQ_S3CUART_ERR0,
.end = IRQ_S3CUART_ERR0,
.flags = IORESOURCE_IRQ,
}
};
static struct resource s3c64xx_uart1_resource[] = {
[0] = {
.start = S3C_PA_UART1,
.end = S3C_PA_UART1 + 0x100,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX1,
.end = IRQ_S3CUART_RX1,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = IRQ_S3CUART_TX1,
.end = IRQ_S3CUART_TX1,
.flags = IORESOURCE_IRQ,
},
[3] = {
.start = IRQ_S3CUART_ERR1,
.end = IRQ_S3CUART_ERR1,
.flags = IORESOURCE_IRQ,
},
};
static struct resource s3c6xx_uart2_resource[] = {
[0] = {
.start = S3C_PA_UART2,
.end = S3C_PA_UART2 + 0x100,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX2,
.end = IRQ_S3CUART_RX2,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = IRQ_S3CUART_TX2,
.end = IRQ_S3CUART_TX2,
.flags = IORESOURCE_IRQ,
},
[3] = {
.start = IRQ_S3CUART_ERR2,
.end = IRQ_S3CUART_ERR2,
.flags = IORESOURCE_IRQ,
},
};
static struct resource s3c64xx_uart3_resource[] = {
[0] = {
.start = S3C_PA_UART3,
.end = S3C_PA_UART3 + 0x100,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX3,
.end = IRQ_S3CUART_RX3,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = IRQ_S3CUART_TX3,
.end = IRQ_S3CUART_TX3,
.flags = IORESOURCE_IRQ,
},
[3] = {
.start = IRQ_S3CUART_ERR3,
.end = IRQ_S3CUART_ERR3,
.flags = IORESOURCE_IRQ,
},
};
struct s3c24xx_uart_resources s3c64xx_uart_resources[] __initdata = {
[0] = {
.resources = s3c64xx_uart0_resource,
.nr_resources = ARRAY_SIZE(s3c64xx_uart0_resource),
},
[1] = {
.resources = s3c64xx_uart1_resource,
.nr_resources = ARRAY_SIZE(s3c64xx_uart1_resource),
},
[2] = {
.resources = s3c6xx_uart2_resource,
.nr_resources = ARRAY_SIZE(s3c6xx_uart2_resource),
},
[3] = {
.resources = s3c64xx_uart3_resource,
.nr_resources = ARRAY_SIZE(s3c64xx_uart3_resource),
},
};
/* uart devices */
static struct platform_device s3c24xx_uart_device0 = {
.id = 0,
};
static struct platform_device s3c24xx_uart_device1 = {
.id = 1,
};
static struct platform_device s3c24xx_uart_device2 = {
.id = 2,
};
static struct platform_device s3c24xx_uart_device3 = {
.id = 3,
};
struct platform_device *s3c24xx_uart_src[4] = {
&s3c24xx_uart_device0,
&s3c24xx_uart_device1,
&s3c24xx_uart_device2,
&s3c24xx_uart_device3,
};
struct platform_device *s3c24xx_uart_devs[4] = {
};
/* linux/arch/arm/plat-s3c64xx/include/mach/irqs.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - Common IRQ support
*/
#ifndef __ASM_PLAT_S3C64XX_IRQS_H
#define __ASM_PLAT_S3C64XX_IRQS_H __FILE__
/* we keep the first set of CPU IRQs out of the range of
* the ISA space, so that the PC104 has them to itself
* and we don't end up having to do horrible things to the
* standard ISA drivers....
*
* note, since we're using the VICs, our start must be a
* mulitple of 32 to allow the common code to work
*/
#define S3C_IRQ_OFFSET (32)
#define S3C_IRQ(x) ((x) + S3C_IRQ_OFFSET)
#define S3C_VIC0_BASE S3C_IRQ(0)
#define S3C_VIC1_BASE S3C_IRQ(32)
/* UART interrupts, each UART has 4 intterupts per channel so
* use the space between the ISA and S3C main interrupts. Note, these
* are not in the same order as the S3C24XX series! */
#define IRQ_S3CUART_BASE0 (16)
#define IRQ_S3CUART_BASE1 (20)
#define IRQ_S3CUART_BASE2 (24)
#define IRQ_S3CUART_BASE3 (28)
#define UART_IRQ_RXD (0)
#define UART_IRQ_ERR (1)
#define UART_IRQ_TXD (2)
#define UART_IRQ_MODEM (3)
#define IRQ_S3CUART_RX0 (IRQ_S3CUART_BASE0 + UART_IRQ_RXD)
#define IRQ_S3CUART_TX0 (IRQ_S3CUART_BASE0 + UART_IRQ_TXD)
#define IRQ_S3CUART_ERR0 (IRQ_S3CUART_BASE0 + UART_IRQ_ERR)
#define IRQ_S3CUART_RX1 (IRQ_S3CUART_BASE1 + UART_IRQ_RXD)
#define IRQ_S3CUART_TX1 (IRQ_S3CUART_BASE1 + UART_IRQ_TXD)
#define IRQ_S3CUART_ERR1 (IRQ_S3CUART_BASE1 + UART_IRQ_ERR)
#define IRQ_S3CUART_RX2 (IRQ_S3CUART_BASE2 + UART_IRQ_RXD)
#define IRQ_S3CUART_TX2 (IRQ_S3CUART_BASE2 + UART_IRQ_TXD)
#define IRQ_S3CUART_ERR2 (IRQ_S3CUART_BASE2 + UART_IRQ_ERR)
#define IRQ_S3CUART_RX3 (IRQ_S3CUART_BASE3 + UART_IRQ_RXD)
#define IRQ_S3CUART_TX3 (IRQ_S3CUART_BASE3 + UART_IRQ_TXD)
#define IRQ_S3CUART_ERR3 (IRQ_S3CUART_BASE3 + UART_IRQ_ERR)
/* VIC based IRQs */
#define S3C64XX_IRQ_VIC0(x) (S3C_VIC0_BASE + (x))
#define S3C64XX_IRQ_VIC1(x) (S3C_VIC1_BASE + (x))
/* VIC0 */
#define IRQ_EINT0_3 S3C64XX_IRQ_VIC0(0)
#define IRQ_EINT4_11 S3C64XX_IRQ_VIC0(1)
#define IRQ_RTC_TIC S3C64XX_IRQ_VIC0(2)
#define IRQ_CAMIF_C S3C64XX_IRQ_VIC0(3)
#define IRQ_CAMIF_P S3C64XX_IRQ_VIC0(4)
#define IRQ_CAMIF_MC S3C64XX_IRQ_VIC0(5)
#define IRQ_S3C6410_IIS S3C64XX_IRQ_VIC0(6)
#define IRQ_S3C6400_CAMIF_MP S3C64XX_IRQ_VIC0(6)
#define IRQ_CAMIF_WE_C S3C64XX_IRQ_VIC0(7)
#define IRQ_S3C6410_G3D S3C64XX_IRQ_VIC0(8)
#define IRQ_S3C6400_CAMIF_WE_P S3C64XX_IRQ_VIC0(8)
#define IRQ_POST0 S3C64XX_IRQ_VIC0(9)
#define IRQ_ROTATOR S3C64XX_IRQ_VIC0(10)
#define IRQ_2D S3C64XX_IRQ_VIC0(11)
#define IRQ_TVENC S3C64XX_IRQ_VIC0(12)
#define IRQ_SCALER S3C64XX_IRQ_VIC0(13)
#define IRQ_BATF S3C64XX_IRQ_VIC0(14)
#define IRQ_JPEG S3C64XX_IRQ_VIC0(15)
#define IRQ_MFC S3C64XX_IRQ_VIC0(16)
#define IRQ_SDMA0 S3C64XX_IRQ_VIC0(17)
#define IRQ_SDMA1 S3C64XX_IRQ_VIC0(18)
#define IRQ_ARM_DMAERR S3C64XX_IRQ_VIC0(19)
#define IRQ_ARM_DMA S3C64XX_IRQ_VIC0(20)
#define IRQ_ARM_DMAS S3C64XX_IRQ_VIC0(21)
#define IRQ_KEYPAD S3C64XX_IRQ_VIC0(22)
#define IRQ_TIMER0_VIC S3C64XX_IRQ_VIC0(23)
#define IRQ_TIMER1_VIC S3C64XX_IRQ_VIC0(24)
#define IRQ_TIMER2_VIC S3C64XX_IRQ_VIC0(25)
#define IRQ_WDT S3C64XX_IRQ_VIC0(26)
#define IRQ_TIMER3_VIC S3C64XX_IRQ_VIC0(27)
#define IRQ_TIMER4_VIC S3C64XX_IRQ_VIC0(28)
#define IRQ_LCD_FIFO S3C64XX_IRQ_VIC0(29)
#define IRQ_LCD_VSYNC S3C64XX_IRQ_VIC0(30)
#define IRQ_LCD_SYSTEM S3C64XX_IRQ_VIC0(31)
/* VIC1 */
#define IRQ_EINT12_19 S3C64XX_IRQ_VIC1(0)
#define IRQ_EINT20_27 S3C64XX_IRQ_VIC1(1)
#define IRQ_PCM0 S3C64XX_IRQ_VIC1(2)
#define IRQ_PCM1 S3C64XX_IRQ_VIC1(3)
#define IRQ_AC97 S3C64XX_IRQ_VIC1(4)
#define IRQ_UART0 S3C64XX_IRQ_VIC1(5)
#define IRQ_UART1 S3C64XX_IRQ_VIC1(6)
#define IRQ_UART2 S3C64XX_IRQ_VIC1(7)
#define IRQ_UART3 S3C64XX_IRQ_VIC1(8)
#define IRQ_DMA0 S3C64XX_IRQ_VIC1(9)
#define IRQ_DMA1 S3C64XX_IRQ_VIC1(10)
#define IRQ_ONENAND0 S3C64XX_IRQ_VIC1(11)
#define IRQ_ONENAND1 S3C64XX_IRQ_VIC1(12)
#define IRQ_NFC S3C64XX_IRQ_VIC1(13)
#define IRQ_CFCON S3C64XX_IRQ_VIC1(14)
#define IRQ_UHOST S3C64XX_IRQ_VIC1(15)
#define IRQ_SPI0 S3C64XX_IRQ_VIC1(16)
#define IRQ_SPI1 S3C64XX_IRQ_VIC1(17)
#define IRQ_IIC S3C64XX_IRQ_VIC1(18)
#define IRQ_HSItx S3C64XX_IRQ_VIC1(19)
#define IRQ_HSIrx S3C64XX_IRQ_VIC1(20)
#define IRQ_RESERVED S3C64XX_IRQ_VIC1(21)
#define IRQ_MSM S3C64XX_IRQ_VIC1(22)
#define IRQ_HOSTIF S3C64XX_IRQ_VIC1(23)
#define IRQ_HSMMC0 S3C64XX_IRQ_VIC1(24)
#define IRQ_HSMMC1 S3C64XX_IRQ_VIC1(25)
#define IRQ_HSMMC2 IRQ_SPI1 /* shared with SPI1 */
#define IRQ_OTG S3C64XX_IRQ_VIC1(26)
#define IRQ_IRDA S3C64XX_IRQ_VIC1(27)
#define IRQ_RTC_ALARM S3C64XX_IRQ_VIC1(28)
#define IRQ_SEC S3C64XX_IRQ_VIC1(29)
#define IRQ_PENDN S3C64XX_IRQ_VIC1(30)
#define IRQ_TC IRQ_PENDN
#define IRQ_ADC S3C64XX_IRQ_VIC1(31)
#define S3C64XX_TIMER_IRQ(x) S3C_IRQ(64 + (x))
#define IRQ_TIMER0 S3C64XX_TIMER_IRQ(0)
#define IRQ_TIMER1 S3C64XX_TIMER_IRQ(1)
#define IRQ_TIMER2 S3C64XX_TIMER_IRQ(2)
#define IRQ_TIMER3 S3C64XX_TIMER_IRQ(3)
#define IRQ_TIMER4 S3C64XX_TIMER_IRQ(4)
/* Since the IRQ_EINT(x) are a linear mapping on current s3c64xx series
* we just defined them as an IRQ_EINT(x) macro from S3C_IRQ_EINT_BASE
* which we place after the pair of VICs. */
#define S3C_IRQ_EINT_BASE S3C_IRQ(64+5)
#define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE)
#define IRQ_EINT(x) S3C_EINT(x)
/* Next the external interrupt groups. These are similar to the IRQ_EINT(x)
* that they are sourced from the GPIO pins but with a different scheme for
* priority and source indication.
*
* The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO
* interrupts, but for historical reasons they are kept apart from these
* next interrupts.
*
* Use IRQ_EINT_GROUP(group, offset) to get the number for use in the
* machine specific support files.
*/
#define IRQ_EINT_GROUP1_NR (15)
#define IRQ_EINT_GROUP2_NR (8)
#define IRQ_EINT_GROUP3_NR (5)
#define IRQ_EINT_GROUP4_NR (14)
#define IRQ_EINT_GROUP5_NR (7)
#define IRQ_EINT_GROUP6_NR (10)
#define IRQ_EINT_GROUP7_NR (16)
#define IRQ_EINT_GROUP8_NR (15)
#define IRQ_EINT_GROUP9_NR (9)
#define IRQ_EINT_GROUP_BASE S3C_EINT(28)
#define IRQ_EINT_GROUP1_BASE (IRQ_EINT_GROUP_BASE + 0x00)
#define IRQ_EINT_GROUP2_BASE (IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR)
#define IRQ_EINT_GROUP3_BASE (IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR)
#define IRQ_EINT_GROUP4_BASE (IRQ_EINT_GROUP3_BASE + IRQ_EINT_GROUP3_NR)
#define IRQ_EINT_GROUP5_BASE (IRQ_EINT_GROUP4_BASE + IRQ_EINT_GROUP4_NR)
#define IRQ_EINT_GROUP6_BASE (IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR)
#define IRQ_EINT_GROUP7_BASE (IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR)
#define IRQ_EINT_GROUP8_BASE (IRQ_EINT_GROUP7_BASE + IRQ_EINT_GROUP7_NR)
#define IRQ_EINT_GROUP9_BASE (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR)
#define IRQ_EINT_GROUP(group, no) (IRQ_EINT_GROUP##group##__BASE + (x))
/* Set the default NR_IRQS */
#define NR_IRQS (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1)
#endif /* __ASM_PLAT_S3C64XX_IRQS_H */
/* arch/arm/plat-s3c64xx/include/plat/pll.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX PLL code
*
* 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.
*/
#define S3C6400_PLL_MDIV_MASK ((1 << (25-16+1)) - 1)
#define S3C6400_PLL_PDIV_MASK ((1 << (13-8+1)) - 1)
#define S3C6400_PLL_SDIV_MASK ((1 << (2-0+1)) - 1)
#define S3C6400_PLL_MDIV_SHIFT (16)
#define S3C6400_PLL_PDIV_SHIFT (8)
#define S3C6400_PLL_SDIV_SHIFT (0)
#include <asm/div64.h>
static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
u32 pllcon)
{
u32 mdiv, pdiv, sdiv;
u64 fvco = baseclk;
mdiv = (pllcon >> S3C6400_PLL_MDIV_SHIFT) & S3C6400_PLL_MDIV_MASK;
pdiv = (pllcon >> S3C6400_PLL_PDIV_SHIFT) & S3C6400_PLL_PDIV_MASK;
sdiv = (pllcon >> S3C6400_PLL_SDIV_SHIFT) & S3C6400_PLL_SDIV_MASK;
fvco *= mdiv;
do_div(fvco, (pdiv << sdiv));
return (unsigned long)fvco;
}
#define S3C6400_EPLL_MDIV_MASK ((1 << (23-16)) - 1)
#define S3C6400_EPLL_PDIV_MASK ((1 << (13-8)) - 1)
#define S3C6400_EPLL_SDIV_MASK ((1 << (2-0)) - 1)
#define S3C6400_EPLL_MDIV_SHIFT (16)
#define S3C6400_EPLL_PDIV_SHIFT (8)
#define S3C6400_EPLL_SDIV_SHIFT (0)
#define S3C6400_EPLL_KDIV_MASK (0xffff)
static inline unsigned long s3c6400_get_epll(unsigned long baseclk)
{
unsigned long result;
u32 epll0 = __raw_readl(S3C_EPLL_CON0);
u32 epll1 = __raw_readl(S3C_EPLL_CON1);
u32 mdiv, pdiv, sdiv, kdiv;
u64 tmp;
mdiv = (epll0 >> S3C6400_EPLL_MDIV_SHIFT) & S3C6400_EPLL_MDIV_MASK;
pdiv = (epll0 >> S3C6400_EPLL_PDIV_SHIFT) & S3C6400_EPLL_PDIV_MASK;
sdiv = (epll0 >> S3C6400_EPLL_SDIV_SHIFT) & S3C6400_EPLL_SDIV_MASK;
kdiv = epll1 & S3C6400_EPLL_KDIV_MASK;
/* We need to multiple baseclk by mdiv (the integer part) and kdiv
* which is in 2^16ths, so shift mdiv up (does not overflow) and
* add kdiv before multiplying. The use of tmp is to avoid any
* overflows before shifting bac down into result when multipling
* by the mdiv and kdiv pair.
*/
tmp = baseclk;
tmp *= (mdiv << 16) + kdiv;
do_div(tmp, (pdiv << sdiv));
result = tmp >> 16;
return result;
}
/* arch/arm/plat-s3c64xx/include/plat/regs-clock.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX clock register definitions
*
* 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.
*/
#ifndef __PLAT_REGS_CLOCK_H
#define __PLAT_REGS_CLOCK_H __FILE__
#define S3C_CLKREG(x) (S3C_VA_SYS + (x))
#define S3C_APLL_LOCK S3C_CLKREG(0x00)
#define S3C_MPLL_LOCK S3C_CLKREG(0x04)
#define S3C_EPLL_LOCK S3C_CLKREG(0x08)
#define S3C_APLL_CON S3C_CLKREG(0x0C)
#define S3C_MPLL_CON S3C_CLKREG(0x10)
#define S3C_EPLL_CON0 S3C_CLKREG(0x14)
#define S3C_EPLL_CON1 S3C_CLKREG(0x18)
#define S3C_CLK_SRC S3C_CLKREG(0x1C)
#define S3C_CLK_DIV0 S3C_CLKREG(0x20)
#define S3C_CLK_DIV1 S3C_CLKREG(0x24)
#define S3C_CLK_DIV2 S3C_CLKREG(0x28)
#define S3C_CLK_OUT S3C_CLKREG(0x2C)
#define S3C_HCLK_GATE S3C_CLKREG(0x30)
#define S3C_PCLK_GATE S3C_CLKREG(0x34)
#define S3C_SCLK_GATE S3C_CLKREG(0x38)
/* CLKDIV0 */
#define S3C6400_CLKDIV0_MFC_MASK (0xf << 28)
#define S3C6400_CLKDIV0_MFC_SHIFT (28)
#define S3C6400_CLKDIV0_JPEG_MASK (0xf << 24)
#define S3C6400_CLKDIV0_JPEG_SHIFT (24)
#define S3C6400_CLKDIV0_CAM_MASK (0xf << 20)
#define S3C6400_CLKDIV0_CAM_SHIFT (20)
#define S3C6400_CLKDIV0_SECURITY_MASK (0x3 << 18)
#define S3C6400_CLKDIV0_SECURITY_SHIFT (18)
#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12)
#define S3C6400_CLKDIV0_PCLK_SHIFT (12)
#define S3C6400_CLKDIV0_HCLK2_MASK (0x7 << 9)
#define S3C6400_CLKDIV0_HCLK2_SHIFT (9)
#define S3C6400_CLKDIV0_HCLK_MASK (0x1 << 8)
#define S3C6400_CLKDIV0_HCLK_SHIFT (8)
#define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4)
#define S3C6400_CLKDIV0_MPLL_SHIFT (4)
#define S3C6400_CLKDIV0_ARM_MASK (0x3 << 0)
#define S3C6410_CLKDIV0_ARM_MASK (0x7 << 0)
#define S3C6400_CLKDIV0_ARM_SHIFT (0)
/* CLKDIV1 */
#define S3C6410_CLKDIV1_FIMC_MASK (0xf << 24)
#define S3C6410_CLKDIV1_FIMC_SHIFT (24)
#define S3C6400_CLKDIV1_UHOST_MASK (0xf << 20)
#define S3C6400_CLKDIV1_UHOST_SHIFT (20)
#define S3C6400_CLKDIV1_SCALER_MASK (0xf << 16)
#define S3C6400_CLKDIV1_SCALER_SHIFT (16)
#define S3C6400_CLKDIV1_LCD_MASK (0xf << 12)
#define S3C6400_CLKDIV1_LCD_SHIFT (12)
#define S3C6400_CLKDIV1_MMC2_MASK (0xf << 8)
#define S3C6400_CLKDIV1_MMC2_SHIFT (8)
#define S3C6400_CLKDIV1_MMC1_MASK (0xf << 4)
#define S3C6400_CLKDIV1_MMC1_SHIFT (4)
#define S3C6400_CLKDIV1_MMC0_MASK (0xf << 0)
#define S3C6400_CLKDIV1_MMC0_SHIFT (0)
/* CLKDIV2 */
#define S3C6410_CLKDIV2_AUDIO2_MASK (0xf << 24)
#define S3C6410_CLKDIV2_AUDIO2_SHIFT (24)
#define S3C6400_CLKDIV2_IRDA_MASK (0xf << 20)
#define S3C6400_CLKDIV2_IRDA_SHIFT (20)
#define S3C6400_CLKDIV2_UART_MASK (0xf << 16)
#define S3C6400_CLKDIV2_UART_SHIFT (16)
#define S3C6400_CLKDIV2_AUDIO1_MASK (0xf << 12)
#define S3C6400_CLKDIV2_AUDIO1_SHIFT (12)
#define S3C6400_CLKDIV2_AUDIO0_MASK (0xf << 8)
#define S3C6400_CLKDIV2_AUDIO0_SHIFT (8)
#define S3C6400_CLKDIV2_SPI1_MASK (0xf << 4)
#define S3C6400_CLKDIV2_SPI1_SHIFT (4)
#define S3C6400_CLKDIV2_SPI0_MASK (0xf << 0)
#define S3C6400_CLKDIV2_SPI0_SHIFT (0)
/* HCLK GATE Registers */
#define S3C_CLKCON_HCLK_BUS (1<<30)
#define S3C_CLKCON_HCLK_SECUR (1<<29)
#define S3C_CLKCON_HCLK_SDMA1 (1<<28)
#define S3C_CLKCON_HCLK_SDMA2 (1<<27)
#define S3C_CLKCON_HCLK_UHOST (1<<26)
#define S3C_CLKCON_HCLK_IROM (1<<25)
#define S3C_CLKCON_HCLK_DDR1 (1<<24)
#define S3C_CLKCON_HCLK_DDR0 (1<<23)
#define S3C_CLKCON_HCLK_MEM1 (1<<22)
#define S3C_CLKCON_HCLK_MEM0 (1<<21)
#define S3C_CLKCON_HCLK_USB (1<<20)
#define S3C_CLKCON_HCLK_HSMMC2 (1<<19)
#define S3C_CLKCON_HCLK_HSMMC1 (1<<18)
#define S3C_CLKCON_HCLK_HSMMC0 (1<<17)
#define S3C_CLKCON_HCLK_MDP (1<<16)
#define S3C_CLKCON_HCLK_DHOST (1<<15)
#define S3C_CLKCON_HCLK_IHOST (1<<14)
#define S3C_CLKCON_HCLK_DMA1 (1<<13)
#define S3C_CLKCON_HCLK_DMA0 (1<<12)
#define S3C_CLKCON_HCLK_JPEG (1<<11)
#define S3C_CLKCON_HCLK_CAMIF (1<<10)
#define S3C_CLKCON_HCLK_SCALER (1<<9)
#define S3C_CLKCON_HCLK_2D (1<<8)
#define S3C_CLKCON_HCLK_TV (1<<7)
#define S3C_CLKCON_HCLK_POST0 (1<<5)
#define S3C_CLKCON_HCLK_ROT (1<<4)
#define S3C_CLKCON_HCLK_LCD (1<<3)
#define S3C_CLKCON_HCLK_TZIC (1<<2)
#define S3C_CLKCON_HCLK_INTC (1<<1)
#define S3C_CLKCON_HCLK_MFC (1<<0)
/* PCLK GATE Registers */
#define S3C6410_CLKCON_PCLK_I2C1 (1<<27)
#define S3C6410_CLKCON_PCLK_IIS2 (1<<26)
#define S3C_CLKCON_PCLK_SKEY (1<<24)
#define S3C_CLKCON_PCLK_CHIPID (1<<23)
#define S3C_CLKCON_PCLK_SPI1 (1<<22)
#define S3C_CLKCON_PCLK_SPI0 (1<<21)
#define S3C_CLKCON_PCLK_HSIRX (1<<20)
#define S3C_CLKCON_PCLK_HSITX (1<<19)
#define S3C_CLKCON_PCLK_GPIO (1<<18)
#define S3C_CLKCON_PCLK_IIC (1<<17)
#define S3C_CLKCON_PCLK_IIS1 (1<<16)
#define S3C_CLKCON_PCLK_IIS0 (1<<15)
#define S3C_CLKCON_PCLK_AC97 (1<<14)
#define S3C_CLKCON_PCLK_TZPC (1<<13)
#define S3C_CLKCON_PCLK_TSADC (1<<12)
#define S3C_CLKCON_PCLK_KEYPAD (1<<11)
#define S3C_CLKCON_PCLK_IRDA (1<<10)
#define S3C_CLKCON_PCLK_PCM1 (1<<9)
#define S3C_CLKCON_PCLK_PCM0 (1<<8)
#define S3C_CLKCON_PCLK_PWM (1<<7)
#define S3C_CLKCON_PCLK_RTC (1<<6)
#define S3C_CLKCON_PCLK_WDT (1<<5)
#define S3C_CLKCON_PCLK_UART3 (1<<4)
#define S3C_CLKCON_PCLK_UART2 (1<<3)
#define S3C_CLKCON_PCLK_UART1 (1<<2)
#define S3C_CLKCON_PCLK_UART0 (1<<1)
#define S3C_CLKCON_PCLK_MFC (1<<0)
/* SCLK GATE Registers */
#define S3C_CLKCON_SCLK_UHOST (1<<30)
#define S3C_CLKCON_SCLK_MMC2_48 (1<<29)
#define S3C_CLKCON_SCLK_MMC1_48 (1<<28)
#define S3C_CLKCON_SCLK_MMC0_48 (1<<27)
#define S3C_CLKCON_SCLK_MMC2 (1<<26)
#define S3C_CLKCON_SCLK_MMC1 (1<<25)
#define S3C_CLKCON_SCLK_MMC0 (1<<24)
#define S3C_CLKCON_SCLK_SPI1_48 (1<<23)
#define S3C_CLKCON_SCLK_SPI0_48 (1<<22)
#define S3C_CLKCON_SCLK_SPI1 (1<<21)
#define S3C_CLKCON_SCLK_SPI0 (1<<20)
#define S3C_CLKCON_SCLK_DAC27 (1<<19)
#define S3C_CLKCON_SCLK_TV27 (1<<18)
#define S3C_CLKCON_SCLK_SCALER27 (1<<17)
#define S3C_CLKCON_SCLK_SCALER (1<<16)
#define S3C_CLKCON_SCLK_LCD27 (1<<15)
#define S3C_CLKCON_SCLK_LCD (1<<14)
#define S3C6400_CLKCON_SCLK_POST1_27 (1<<13)
#define S3C6410_CLKCON_FIMC (1<<13)
#define S3C_CLKCON_SCLK_POST0_27 (1<<12)
#define S3C6400_CLKCON_SCLK_POST1 (1<<11)
#define S3C6410_CLKCON_SCLK_AUDIO2 (1<<11)
#define S3C_CLKCON_SCLK_POST0 (1<<10)
#define S3C_CLKCON_SCLK_AUDIO1 (1<<9)
#define S3C_CLKCON_SCLK_AUDIO0 (1<<8)
#define S3C_CLKCON_SCLK_SECUR (1<<7)
#define S3C_CLKCON_SCLK_IRDA (1<<6)
#define S3C_CLKCON_SCLK_UART (1<<5)
#define S3C_CLKCON_SCLK_ONENAND (1<<4)
#define S3C_CLKCON_SCLK_MFC (1<<3)
#define S3C_CLKCON_SCLK_CAM (1<<2)
#define S3C_CLKCON_SCLK_JPEG (1<<1)
/* CLKSRC */
#define S3C6400_CLKSRC_APLL_MOUT (1 << 0)
#define S3C6400_CLKSRC_MPLL_MOUT (1 << 1)
#define S3C6400_CLKSRC_EPLL_MOUT (1 << 2)
#define S3C6400_CLKSRC_APLL_MOUT_SHIFT (0)
#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT (1)
#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2)
#define S3C6400_CLKSRC_MFC (1 << 4)
#define S3C6410_CLKSRC_TV27_MASK (0x1 << 31)
#define S3C6410_CLKSRC_TV27_SHIFT (31)
#define S3C6410_CLKSRC_DAC27_MASK (0x1 << 30)
#define S3C6410_CLKSRC_DAC27_SHIFT (30)
#define S3C6400_CLKSRC_SCALER_MASK (0x3 << 28)
#define S3C6400_CLKSRC_SCALER_SHIFT (28)
#define S3C6400_CLKSRC_LCD_MASK (0x3 << 26)
#define S3C6400_CLKSRC_LCD_SHIFT (26)
#define S3C6400_CLKSRC_IRDA_MASK (0x3 << 24)
#define S3C6400_CLKSRC_IRDA_SHIFT (24)
#define S3C6400_CLKSRC_MMC2_MASK (0x3 << 22)
#define S3C6400_CLKSRC_MMC2_SHIFT (22)
#define S3C6400_CLKSRC_MMC1_MASK (0x3 << 20)
#define S3C6400_CLKSRC_MMC1_SHIFT (20)
#define S3C6400_CLKSRC_MMC0_MASK (0x3 << 18)
#define S3C6400_CLKSRC_MMC0_SHIFT (18)
#define S3C6400_CLKSRC_SPI1_MASK (0x3 << 16)
#define S3C6400_CLKSRC_SPI1_SHIFT (16)
#define S3C6400_CLKSRC_SPI0_MASK (0x3 << 14)
#define S3C6400_CLKSRC_SPI0_SHIFT (14)
#define S3C6400_CLKSRC_UART_MASK (0x1 << 13)
#define S3C6400_CLKSRC_UART_SHIFT (13)
#define S3C6400_CLKSRC_AUDIO1_MASK (0x7 << 10)
#define S3C6400_CLKSRC_AUDIO1_SHIFT (10)
#define S3C6400_CLKSRC_AUDIO0_MASK (0x7 << 7)
#define S3C6400_CLKSRC_AUDIO0_SHIFT (7)
#define S3C6400_CLKSRC_UHOST_MASK (0x3 << 5)
#define S3C6400_CLKSRC_UHOST_SHIFT (5)
#endif /* _PLAT_REGS_CLOCK_H */
/* arch/arm/plat-s3c64xx/include/plat/regs-sys.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX system register definitions
*
* 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.
*/
#ifndef __PLAT_REGS_SYS_H
#define __PLAT_REGS_SYS_H __FILE__
#define S3C_SYSREG(x) (S3C_VA_SYS + (x))
#define S3C64XX_OTHERS S3C_SYSREG(0x900)
#define S3C64XX_OTHERS_USBMASK (1 << 16)
#endif /* _PLAT_REGS_SYS_H */
/* arch/arm/plat-s3c64xx/include/plat/s3c6400.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* Header file for s3c6400 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.
*/
/* Common init code for S3C6400 related SoCs */
extern void s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s3c6400_register_clocks(void);
extern void s3c6400_setup_clocks(void);
#ifdef CONFIG_CPU_S3C6400
extern int s3c6400_init(void);
extern void s3c6400_map_io(void);
extern void s3c6400_init_clocks(int xtal);
#define s3c6400_init_uarts s3c6400_common_init_uarts
#else
#define s3c6400_init_clocks NULL
#define s3c6400_init_uarts NULL
#define s3c6400_map_io NULL
#define s3c6400_init NULL
#endif
/* arch/arm/plat-s3c64xx/include/plat/s3c6410.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* Header file for s3c6410 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.
*/
#ifdef CONFIG_CPU_S3C6410
extern int s3c6410_init(void);
extern void s3c6410_init_irq(void);
extern void s3c6410_map_io(void);
extern void s3c6410_init_clocks(int xtal);
#define s3c6410_init_uarts s3c6400_common_init_uarts
#else
#define s3c6410_init_clocks NULL
#define s3c6410_init_uarts NULL
#define s3c6410_map_io NULL
#define s3c6410_init NULL
#endif
/* arch/arm/plat-s3c64xx/irq-eint.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - Interrupt handling for IRQ_EINT(x)
*
* 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/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/hardware/vic.h>
#include <plat/regs-irqtype.h>
#include <mach/map.h>
#include <plat/cpu.h>
/* GPIO is 0x7F008xxx, */
#define S3C64XX_GPIOREG(x) (S3C64XX_VA_GPIO + (x))
#define S3C64XX_EINT0CON0 S3C64XX_GPIOREG(0x900)
#define S3C64XX_EINT0CON1 S3C64XX_GPIOREG(0x904)
#define S3C64XX_EINT0FLTCON0 S3C64XX_GPIOREG(0x910)
#define S3C64XX_EINT0FLTCON1 S3C64XX_GPIOREG(0x914)
#define S3C64XX_EINT0FLTCON2 S3C64XX_GPIOREG(0x918)
#define S3C64XX_EINT0FLTCON3 S3C64XX_GPIOREG(0x91C)
#define S3C64XX_EINT0MASK S3C64XX_GPIOREG(0x920)
#define S3C64XX_EINT0PEND S3C64XX_GPIOREG(0x924)
#define eint_offset(irq) ((irq) - IRQ_EINT(0))
#define eint_irq_to_bit(irq) (1 << eint_offset(irq))
static inline void s3c_irq_eint_mask(unsigned int irq)
{
u32 mask;
mask = __raw_readl(S3C64XX_EINT0MASK);
mask |= eint_irq_to_bit(irq);
__raw_writel(mask, S3C64XX_EINT0MASK);
}
static void s3c_irq_eint_unmask(unsigned int irq)
{
u32 mask;
mask = __raw_readl(S3C64XX_EINT0MASK);
mask |= eint_irq_to_bit(irq);
__raw_writel(mask, S3C64XX_EINT0MASK);
}
static inline void s3c_irq_eint_ack(unsigned int irq)
{
__raw_writel(eint_irq_to_bit(irq), S3C64XX_EINT0PEND);
}
static void s3c_irq_eint_maskack(unsigned int irq)
{
/* compiler should in-line these */
s3c_irq_eint_mask(irq);
s3c_irq_eint_ack(irq);
}
static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
{
int offs = eint_offset(irq);
int shift;
u32 ctrl, mask;
u32 newvalue = 0;
void __iomem *reg;
if (offs > 27)
return -EINVAL;
if (offs <= 15)
reg = S3C64XX_EINT0CON0;
else
reg = S3C64XX_EINT0CON1;
switch (type) {
case IRQ_TYPE_NONE:
printk(KERN_WARNING "No edge setting!\n");
break;
case IRQ_TYPE_EDGE_RISING:
newvalue = S3C2410_EXTINT_RISEEDGE;
break;
case IRQ_TYPE_EDGE_FALLING:
newvalue = S3C2410_EXTINT_FALLEDGE;
break;
case IRQ_TYPE_EDGE_BOTH:
newvalue = S3C2410_EXTINT_BOTHEDGE;
break;
case IRQ_TYPE_LEVEL_LOW:
newvalue = S3C2410_EXTINT_LOWLEV;
break;
case IRQ_TYPE_LEVEL_HIGH:
newvalue = S3C2410_EXTINT_HILEV;
break;
default:
printk(KERN_ERR "No such irq type %d", type);
return -1;
}
shift = (offs / 2) * 4;
mask = 0x7 << shift;
ctrl = __raw_readl(reg);
ctrl &= ~mask;
ctrl |= newvalue << shift;
__raw_writel(ctrl, reg);
return 0;
}
static struct irq_chip s3c_irq_eint = {
.name = "s3c-eint",
.mask = s3c_irq_eint_mask,
.unmask = s3c_irq_eint_unmask,
.mask_ack = s3c_irq_eint_maskack,
.ack = s3c_irq_eint_ack,
.set_type = s3c_irq_eint_set_type,
};
/* s3c_irq_demux_eint
*
* This function demuxes the IRQ from the group0 external interrupts,
* from IRQ_EINT(0) to IRQ_EINT(27). It is designed to be inlined into
* the specific handlers s3c_irq_demux_eintX_Y.
*/
static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
{
u32 status = __raw_readl(S3C64XX_EINT0PEND);
u32 mask = __raw_readl(S3C64XX_EINT0MASK);
unsigned int irq;
status &= ~mask;
status >>= start;
status &= (1 << (end - start + 1)) - 1;
for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
if (status & 1)
generic_handle_irq(irq);
status >>= 1;
}
}
static void s3c_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_eint(0, 3);
}
static void s3c_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_eint(4, 11);
}
static void s3c_irq_demux_eint12_19(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_eint(12, 19);
}
static void s3c_irq_demux_eint20_27(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_eint(20, 27);
}
int __init s3c64xx_init_irq_eint(void)
{
int irq;
for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
set_irq_chip(irq, &s3c_irq_eint);
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
set_irq_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
set_irq_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
set_irq_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
set_irq_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
return 0;
}
arch_initcall(s3c64xx_init_irq_eint);
/* arch/arm/plat-s3c64xx/irq.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - Interrupt handling
*
* 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/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/hardware/vic.h>
#include <mach/map.h>
#include <plat/regs-timer.h>
#include <plat/cpu.h>
/* Timer interrupt handling */
static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq)
{
generic_handle_irq(sub_irq);
}
static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_timer(irq, IRQ_TIMER0);
}
static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_timer(irq, IRQ_TIMER1);
}
static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_timer(irq, IRQ_TIMER2);
}
static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_timer(irq, IRQ_TIMER3);
}
static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_timer(irq, IRQ_TIMER4);
}
/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
static void s3c_irq_timer_mask(unsigned int irq)
{
u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
reg &= 0x1f; /* mask out pending interrupts */
reg &= ~(1 << (irq - IRQ_TIMER0));
__raw_writel(reg, S3C64XX_TINT_CSTAT);
}
static void s3c_irq_timer_unmask(unsigned int irq)
{
u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
reg &= 0x1f; /* mask out pending interrupts */
reg |= 1 << (irq - IRQ_TIMER0);
__raw_writel(reg, S3C64XX_TINT_CSTAT);
}
static void s3c_irq_timer_ack(unsigned int irq)
{
u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
reg &= 0x1f;
reg |= (1 << 5) << (irq - IRQ_TIMER0);
__raw_writel(reg, S3C64XX_TINT_CSTAT);
}
static struct irq_chip s3c_irq_timer = {
.name = "s3c-timer",
.mask = s3c_irq_timer_mask,
.unmask = s3c_irq_timer_unmask,
.ack = s3c_irq_timer_ack,
};
struct uart_irq {
void __iomem *regs;
unsigned int base_irq;
unsigned int parent_irq;
};
/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
* are consecutive when looking up the interrupt in the demux routines.
*/
static struct uart_irq uart_irqs[] = {
[0] = {
.regs = S3C_VA_UART0,
.base_irq = IRQ_S3CUART_BASE0,
.parent_irq = IRQ_UART0,
},
[1] = {
.regs = S3C_VA_UART1,
.base_irq = IRQ_S3CUART_BASE1,
.parent_irq = IRQ_UART1,
},
[2] = {
.regs = S3C_VA_UART2,
.base_irq = IRQ_S3CUART_BASE2,
.parent_irq = IRQ_UART2,
},
[3] = {
.regs = S3C_VA_UART3,
.base_irq = IRQ_S3CUART_BASE3,
.parent_irq = IRQ_UART3,
},
};
static inline void __iomem *s3c_irq_uart_base(unsigned int irq)
{
struct uart_irq *uirq = get_irq_chip_data(irq);
return uirq->regs;
}
static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
{
return irq & 3;
}
/* UART interrupt registers, not worth adding to seperate include header */
#define S3C64XX_UINTP 0x30
#define S3C64XX_UINTSP 0x34
#define S3C64XX_UINTM 0x38
static void s3c_irq_uart_mask(unsigned int irq)
{
void __iomem *regs = s3c_irq_uart_base(irq);
unsigned int bit = s3c_irq_uart_bit(irq);
u32 reg;
reg = __raw_readl(regs + S3C64XX_UINTM);
reg |= (1 << bit);
__raw_writel(reg, regs + S3C64XX_UINTM);
}
static void s3c_irq_uart_maskack(unsigned int irq)
{
void __iomem *regs = s3c_irq_uart_base(irq);
unsigned int bit = s3c_irq_uart_bit(irq);
u32 reg;
reg = __raw_readl(regs + S3C64XX_UINTM);
reg |= (1 << bit);
__raw_writel(reg, regs + S3C64XX_UINTM);
__raw_writel(1 << bit, regs + S3C64XX_UINTP);
}
static void s3c_irq_uart_unmask(unsigned int irq)
{
void __iomem *regs = s3c_irq_uart_base(irq);
unsigned int bit = s3c_irq_uart_bit(irq);
u32 reg;
reg = __raw_readl(regs + S3C64XX_UINTM);
reg &= ~(1 << bit);
__raw_writel(reg, regs + S3C64XX_UINTM);
}
static void s3c_irq_uart_ack(unsigned int irq)
{
void __iomem *regs = s3c_irq_uart_base(irq);
unsigned int bit = s3c_irq_uart_bit(irq);
__raw_writel(1 << bit, regs + S3C64XX_UINTP);
}
static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
{
struct uart_irq *uirq = &uart_irqs[irq - IRQ_UART0];
u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
int base = uirq->base_irq;
if (pend & (1 << 0))
generic_handle_irq(base);
if (pend & (1 << 1))
generic_handle_irq(base + 1);
if (pend & (1 << 2))
generic_handle_irq(base + 2);
if (pend & (1 << 3))
generic_handle_irq(base + 3);
}
static struct irq_chip s3c_irq_uart = {
.name = "s3c-uart",
.mask = s3c_irq_uart_mask,
.unmask = s3c_irq_uart_unmask,
.mask_ack = s3c_irq_uart_maskack,
.ack = s3c_irq_uart_ack,
};
static void __init s3c64xx_uart_irq(struct uart_irq *uirq)
{
void *reg_base = uirq->regs;
unsigned int irq;
int offs;
/* mask all interrupts at the start. */
__raw_writel(0xf, reg_base + S3C64XX_UINTM);
for (offs = 0; offs < 3; offs++) {
irq = uirq->base_irq + offs;
set_irq_chip(irq, &s3c_irq_uart);
set_irq_chip_data(irq, uirq);
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
}
void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
{
int uart, irq;
printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
/* initialise the pair of VICs */
vic_init(S3C_VA_VIC0, S3C_VIC0_BASE, vic0_valid);
vic_init(S3C_VA_VIC1, S3C_VIC1_BASE, vic1_valid);
/* add the timer sub-irqs */
set_irq_chained_handler(IRQ_TIMER0_VIC, s3c_irq_demux_timer0);
set_irq_chained_handler(IRQ_TIMER1_VIC, s3c_irq_demux_timer1);
set_irq_chained_handler(IRQ_TIMER2_VIC, s3c_irq_demux_timer2);
set_irq_chained_handler(IRQ_TIMER3_VIC, s3c_irq_demux_timer3);
set_irq_chained_handler(IRQ_TIMER4_VIC, s3c_irq_demux_timer4);
for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) {
set_irq_chip(irq, &s3c_irq_timer);
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
for (uart = 0; uart < ARRAY_SIZE(uart_irqs); uart++)
s3c64xx_uart_irq(&uart_irqs[uart]);
}
This diff is collapsed.
/* linux/arch/arm/plat-s3c64xx/s3c6400-init.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C6400 - CPU initialisation (common with other S3C64XX chips)
*
* 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/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/s3c6400.h>
#include <plat/s3c6410.h>
/* uart registration process */
void __init s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no);
}
......@@ -447,7 +447,7 @@ config SERIAL_CLPS711X_CONSOLE
config SERIAL_SAMSUNG
tristate "Samsung SoC serial support"
depends on ARM && PLAT_S3C24XX
depends on ARM && PLAT_S3C
select SERIAL_CORE
help
Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
......@@ -508,7 +508,20 @@ config SERIAL_S3C2440
help
Serial port support for the Samsung S3C2440 and S3C2442 SoC
config SERIAL_S3C24A0
tristate "Samsung S3C24A0 Serial port support"
depends on SERIAL_SAMSUNG && CPU_S3C24A0
default y if CPU_S3C24A0
help
Serial port support for the Samsung S3C24A0 SoC
config SERIAL_S3C6400
tristate "Samsung S3C6400/S3C6410 Serial port support"
depends on SERIAL_SAMSUNG && (CPU_S3C600 || CPU_S3C6410)
default y
help
Serial port support for the Samsung S3C6400 and S3C6410
SoCs
config SERIAL_DZ
bool "DECstation DZ serial driver"
......
......@@ -41,6 +41,8 @@ obj-$(CONFIG_SERIAL_S3C2400) += s3c2400.o
obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o
obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
obj-$(CONFIG_SERIAL_MUX) += mux.o
obj-$(CONFIG_SERIAL_68328) += 68328serial.o
......
/* linux/drivers/serial/s3c24a0.c
*
* Driver for Samsung S3C24A0 SoC onboard UARTs.
*
* Based on drivers/serial/s3c2410.c
*
* Author: Sandeep Patil <sandeep.patil@azingo.com>
*
* Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics
* http://armlinux.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.
*/
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <mach/hardware.h>
#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include "samsung.h"
static int s3c24a0_serial_setsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
if (strcmp(clk->name, "uclk") == 0)
ucon |= S3C2410_UCON_UCLK;
else
ucon &= ~S3C2410_UCON_UCLK;
wr_regl(port, S3C2410_UCON, ucon);
return 0;
}
static int s3c24a0_serial_getsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
clk->divisor = 1;
clk->name = (ucon & S3C2410_UCON_UCLK) ? "uclk" : "pclk";
return 0;
}
static int s3c24a0_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg)
{
dbg("s3c24a0_serial_resetport: port=%p (%08lx), cfg=%p\n",
port, port->mapbase, cfg);
wr_regl(port, S3C2410_UCON, cfg->ucon);
wr_regl(port, S3C2410_ULCON, cfg->ulcon);
/* reset both fifos */
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
wr_regl(port, S3C2410_UFCON, cfg->ufcon);
return 0;
}
static struct s3c24xx_uart_info s3c24a0_uart_inf = {
.name = "Samsung S3C24A0 UART",
.type = PORT_S3C2410,
.fifosize = 16,
.rx_fifomask = S3C24A0_UFSTAT_RXMASK,
.rx_fifoshift = S3C24A0_UFSTAT_RXSHIFT,
.rx_fifofull = S3C24A0_UFSTAT_RXFULL,
.tx_fifofull = S3C24A0_UFSTAT_TXFULL,
.tx_fifomask = S3C24A0_UFSTAT_TXMASK,
.tx_fifoshift = S3C24A0_UFSTAT_TXSHIFT,
.get_clksrc = s3c24a0_serial_getsource,
.set_clksrc = s3c24a0_serial_setsource,
.reset_port = s3c24a0_serial_resetport,
};
static int s3c24a0_serial_probe(struct platform_device *dev)
{
return s3c24xx_serial_probe(dev, &s3c24a0_uart_inf);
}
static struct platform_driver s3c24a0_serial_drv = {
.probe = s3c24a0_serial_probe,
.remove = s3c24xx_serial_remove,
.driver = {
.name = "s3c24a0-uart",
.owner = THIS_MODULE,
},
};
s3c24xx_console_init(&s3c24a0_serial_drv, &s3c24a0_uart_inf);
static int __init s3c24a0_serial_init(void)
{
return s3c24xx_serial_init(&s3c24a0_serial_drv, &s3c24a0_uart_inf);
}
static void __exit s3c24a0_serial_exit(void)
{
platform_driver_unregister(&s3c24a0_serial_drv);
}
module_init(s3c24a0_serial_init);
module_exit(s3c24a0_serial_exit);
/* linux/drivers/serial/s3c6400.c
*
* Driver for Samsung S3C6400 and S3C6410 SoC onboard UARTs.
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.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.
*/
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <plat/regs-serial.h>
#include "samsung.h"
static int s3c6400_serial_setsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
if (strcmp(clk->name, "uclk0") == 0) {
ucon &= ~S3C6400_UCON_CLKMASK;
ucon |= S3C6400_UCON_UCLK0;
} else if (strcmp(clk->name, "uclk1") == 0)
ucon |= S3C6400_UCON_UCLK1;
else if (strcmp(clk->name, "pclk") == 0) {
/* See notes about transitioning from UCLK to PCLK */
ucon &= ~S3C6400_UCON_UCLK0;
} else {
printk(KERN_ERR "unknown clock source %s\n", clk->name);
return -EINVAL;
}
wr_regl(port, S3C2410_UCON, ucon);
return 0;
}
static int s3c6400_serial_getsource(struct uart_port *port,
struct s3c24xx_uart_clksrc *clk)
{
u32 ucon = rd_regl(port, S3C2410_UCON);
clk->divisor = 1;
switch (ucon & S3C6400_UCON_CLKMASK) {
case S3C6400_UCON_UCLK0:
clk->name = "uclk0";
break;
case S3C6400_UCON_UCLK1:
clk->name = "uclk1";
break;
case S3C6400_UCON_PCLK:
case S3C6400_UCON_PCLK2:
clk->name = "pclk";
break;
}
return 0;
}
static int s3c6400_serial_resetport(struct uart_port *port,
struct s3c2410_uartcfg *cfg)
{
unsigned long ucon = rd_regl(port, S3C2410_UCON);
dbg("s3c6400_serial_resetport: port=%p (%08lx), cfg=%p\n",
port, port->mapbase, cfg);
/* ensure we don't change the clock settings... */
ucon &= S3C6400_UCON_CLKMASK;
wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
wr_regl(port, S3C2410_ULCON, cfg->ulcon);
/* reset both fifos */
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
wr_regl(port, S3C2410_UFCON, cfg->ufcon);
return 0;
}
static struct s3c24xx_uart_info s3c6400_uart_inf = {
.name = "Samsung S3C6400 UART",
.type = PORT_S3C6400,
.fifosize = 64,
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
.tx_fifofull = S3C2440_UFSTAT_TXFULL,
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
.get_clksrc = s3c6400_serial_getsource,
.set_clksrc = s3c6400_serial_setsource,
.reset_port = s3c6400_serial_resetport,
};
/* device management */
static int s3c6400_serial_probe(struct platform_device *dev)
{
dbg("s3c6400_serial_probe: dev=%p\n", dev);
return s3c24xx_serial_probe(dev, &s3c6400_uart_inf);
}
static struct platform_driver s3c6400_serial_drv = {
.probe = s3c6400_serial_probe,
.remove = s3c24xx_serial_remove,
.driver = {
.name = "s3c6400-uart",
.owner = THIS_MODULE,
},
};
s3c24xx_console_init(&s3c6400_serial_drv, &s3c6400_uart_inf);
static int __init s3c6400_serial_init(void)
{
return s3c24xx_serial_init(&s3c6400_serial_drv, &s3c6400_uart_inf);
}
static void __exit s3c6400_serial_exit(void)
{
platform_driver_unregister(&s3c6400_serial_drv);
}
module_init(s3c6400_serial_init);
module_exit(s3c6400_serial_exit);
MODULE_DESCRIPTION("Samsung S3C6400,S3C6410 SoC Serial port driver");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:s3c6400-uart");
......@@ -47,9 +47,9 @@
#include <asm/irq.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include "samsung.h"
......@@ -61,17 +61,12 @@
/* we can support 3 uarts, but not always use them */
#ifdef CONFIG_CPU_S3C2400
#if defined(CONFIG_CPU_S3C2400) || defined(CONFIG_CPU_S3C24A0)
#define NR_PORTS (2)
#else
#define NR_PORTS (3)
#endif
/* port irq numbers */
#define TX_IRQ(port) ((port)->irq + 1)
#define RX_IRQ(port) ((port)->irq)
/* macros to change one thing to another */
#define tx_enabled(port) ((port)->unused[0])
......@@ -137,8 +132,10 @@ static void s3c24xx_serial_rx_disable(struct uart_port *port)
static void s3c24xx_serial_stop_tx(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
if (tx_enabled(port)) {
disable_irq(TX_IRQ(port));
disable_irq(ourport->tx_irq);
tx_enabled(port) = 0;
if (port->flags & UPF_CONS_FLOW)
s3c24xx_serial_rx_enable(port);
......@@ -147,11 +144,13 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
static void s3c24xx_serial_start_tx(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
if (!tx_enabled(port)) {
if (port->flags & UPF_CONS_FLOW)
s3c24xx_serial_rx_disable(port);
enable_irq(TX_IRQ(port));
enable_irq(ourport->tx_irq);
tx_enabled(port) = 1;
}
}
......@@ -159,9 +158,11 @@ static void s3c24xx_serial_start_tx(struct uart_port *port)
static void s3c24xx_serial_stop_rx(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
if (rx_enabled(port)) {
dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
disable_irq(RX_IRQ(port));
disable_irq(ourport->rx_irq);
rx_enabled(port) = 0;
}
}
......@@ -385,13 +386,13 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
struct s3c24xx_uart_port *ourport = to_ourport(port);
if (ourport->tx_claimed) {
free_irq(TX_IRQ(port), ourport);
free_irq(ourport->tx_irq, ourport);
tx_enabled(port) = 0;
ourport->tx_claimed = 0;
}
if (ourport->rx_claimed) {
free_irq(RX_IRQ(port), ourport);
free_irq(ourport->rx_irq, ourport);
ourport->rx_claimed = 0;
rx_enabled(port) = 0;
}
......@@ -408,12 +409,11 @@ static int s3c24xx_serial_startup(struct uart_port *port)
rx_enabled(port) = 1;
ret = request_irq(RX_IRQ(port),
s3c24xx_serial_rx_chars, 0,
ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,
s3c24xx_serial_portname(port), ourport);
if (ret != 0) {
printk(KERN_ERR "cannot get irq %d\n", RX_IRQ(port));
printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq);
return ret;
}
......@@ -423,12 +423,11 @@ static int s3c24xx_serial_startup(struct uart_port *port)
tx_enabled(port) = 1;
ret = request_irq(TX_IRQ(port),
s3c24xx_serial_tx_chars, 0,
ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0,
s3c24xx_serial_portname(port), ourport);
if (ret) {
printk(KERN_ERR "cannot get irq %d\n", TX_IRQ(port));
printk(KERN_ERR "cannot get irq %d\n", ourport->tx_irq);
goto err;
}
......@@ -756,6 +755,8 @@ static const char *s3c24xx_serial_type(struct uart_port *port)
return "S3C2440";
case PORT_S3C2412:
return "S3C2412";
case PORT_S3C6400:
return "S3C6400/10";
default:
return NULL;
}
......@@ -1034,18 +1035,26 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
dbg("resource %p (%lx..%lx)\n", res, res->start, res->end);
port->mapbase = res->start;
port->membase = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART);
port->mapbase = res->start;
port->membase = S3C_VA_UART + res->start - (S3C_PA_UART & 0xfff00000);
ret = platform_get_irq(platdev, 0);
if (ret < 0)
port->irq = 0;
else
else {
port->irq = ret;
ourport->rx_irq = ret;
ourport->tx_irq = ret + 1;
}
ret = platform_get_irq(platdev, 1);
if (ret > 0)
ourport->tx_irq = ret;
ourport->clk = clk_get(&platdev->dev, "uart");
dbg("port: map=%08x, mem=%08x, irq=%d, clock=%ld\n",
port->mapbase, port->membase, port->irq, port->uartclk);
dbg("port: map=%08x, mem=%08x, irq=%d (%d,%d), clock=%ld\n",
port->mapbase, port->membase, port->irq,
ourport->rx_irq, ourport->tx_irq, port->uartclk);
/* reset the fifos (and setup the uart) */
s3c24xx_serial_resetport(port, cfg);
......
......@@ -36,6 +36,9 @@ struct s3c24xx_uart_port {
unsigned int pm_level;
unsigned long baudclk_rate;
unsigned int rx_irq;
unsigned int tx_irq;
struct s3c24xx_uart_info *info;
struct s3c24xx_uart_clksrc *clksrc;
struct clk *clk;
......
......@@ -158,6 +158,8 @@
/* SH-SCI */
#define PORT_SCIFA 83
#define PORT_S3C6400 84
#ifdef __KERNEL__
#include <linux/compiler.h>
......
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