From 871480933a1c28f8a9fed4c4d34d06c439a7a422 Mon Sep 17 00:00:00 2001 From: Srikant Patnaik Date: Sun, 11 Jan 2015 12:28:04 +0530 Subject: Moved, renamed, and deleted files The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure. --- arch/arm/mach-s3c24xx/Kconfig | 538 ++++++++++++++ arch/arm/mach-s3c24xx/Makefile | 95 +++ arch/arm/mach-s3c24xx/Makefile.boot | 7 + arch/arm/mach-s3c24xx/bast-ide.c | 112 +++ arch/arm/mach-s3c24xx/bast-irq.c | 166 +++++ arch/arm/mach-s3c24xx/clock-s3c2412.c | 763 +++++++++++++++++++ arch/arm/mach-s3c24xx/clock-s3c2416.c | 172 +++++ arch/arm/mach-s3c24xx/clock-s3c2440.c | 194 +++++ arch/arm/mach-s3c24xx/clock-s3c2443.c | 215 ++++++ arch/arm/mach-s3c24xx/clock-s3c244x.c | 141 ++++ arch/arm/mach-s3c24xx/common-s3c2443.c | 670 +++++++++++++++++ arch/arm/mach-s3c24xx/common-smdk.c | 207 ++++++ arch/arm/mach-s3c24xx/common.h | 18 + arch/arm/mach-s3c24xx/dma-s3c2410.c | 186 +++++ arch/arm/mach-s3c24xx/dma-s3c2412.c | 180 +++++ arch/arm/mach-s3c24xx/dma-s3c2440.c | 197 +++++ arch/arm/mach-s3c24xx/dma-s3c2443.c | 174 +++++ arch/arm/mach-s3c24xx/h1940-bluetooth.c | 157 ++++ arch/arm/mach-s3c24xx/include/mach/anubis-cpld.h | 25 + arch/arm/mach-s3c24xx/include/mach/anubis-irq.h | 21 + arch/arm/mach-s3c24xx/include/mach/anubis-map.h | 38 + arch/arm/mach-s3c24xx/include/mach/bast-cpld.h | 53 ++ arch/arm/mach-s3c24xx/include/mach/bast-irq.h | 29 + arch/arm/mach-s3c24xx/include/mach/bast-map.h | 146 ++++ arch/arm/mach-s3c24xx/include/mach/bast-pmu.h | 40 + arch/arm/mach-s3c24xx/include/mach/debug-macro.S | 101 +++ arch/arm/mach-s3c24xx/include/mach/dma.h | 210 ++++++ arch/arm/mach-s3c24xx/include/mach/entry-macro.S | 70 ++ arch/arm/mach-s3c24xx/include/mach/fb.h | 1 + arch/arm/mach-s3c24xx/include/mach/gpio-fns.h | 1 + arch/arm/mach-s3c24xx/include/mach/gpio-nrs.h | 118 +++ arch/arm/mach-s3c24xx/include/mach/gpio-track.h | 33 + arch/arm/mach-s3c24xx/include/mach/gpio.h | 35 + arch/arm/mach-s3c24xx/include/mach/gta02.h | 84 +++ arch/arm/mach-s3c24xx/include/mach/h1940-latch.h | 43 ++ arch/arm/mach-s3c24xx/include/mach/h1940.h | 24 + arch/arm/mach-s3c24xx/include/mach/hardware.h | 42 ++ arch/arm/mach-s3c24xx/include/mach/idle.h | 24 + arch/arm/mach-s3c24xx/include/mach/io.h | 211 ++++++ arch/arm/mach-s3c24xx/include/mach/irqs.h | 202 +++++ arch/arm/mach-s3c24xx/include/mach/leds-gpio.h | 28 + arch/arm/mach-s3c24xx/include/mach/map.h | 165 ++++ arch/arm/mach-s3c24xx/include/mach/osiris-cpld.h | 30 + arch/arm/mach-s3c24xx/include/mach/osiris-map.h | 42 ++ arch/arm/mach-s3c24xx/include/mach/otom-map.h | 30 + arch/arm/mach-s3c24xx/include/mach/pm-core.h | 67 ++ arch/arm/mach-s3c24xx/include/mach/regs-clock.h | 166 +++++ arch/arm/mach-s3c24xx/include/mach/regs-dsc.h | 220 ++++++ arch/arm/mach-s3c24xx/include/mach/regs-gpio.h | 602 +++++++++++++++ arch/arm/mach-s3c24xx/include/mach/regs-gpioj.h | 70 ++ arch/arm/mach-s3c24xx/include/mach/regs-irq.h | 53 ++ arch/arm/mach-s3c24xx/include/mach/regs-lcd.h | 162 ++++ arch/arm/mach-s3c24xx/include/mach/regs-mem.h | 202 +++++ arch/arm/mach-s3c24xx/include/mach/regs-power.h | 40 + .../mach-s3c24xx/include/mach/regs-s3c2412-mem.h | 48 ++ arch/arm/mach-s3c24xx/include/mach/regs-s3c2412.h | 23 + .../mach-s3c24xx/include/mach/regs-s3c2416-mem.h | 30 + arch/arm/mach-s3c24xx/include/mach/regs-s3c2416.h | 24 + .../mach-s3c24xx/include/mach/regs-s3c2443-clock.h | 194 +++++ arch/arm/mach-s3c24xx/include/mach/regs-sdi.h | 127 ++++ arch/arm/mach-s3c24xx/include/mach/tick.h | 15 + arch/arm/mach-s3c24xx/include/mach/timex.h | 24 + arch/arm/mach-s3c24xx/include/mach/uncompress.h | 54 ++ arch/arm/mach-s3c24xx/include/mach/vr1000-cpld.h | 18 + arch/arm/mach-s3c24xx/include/mach/vr1000-irq.h | 26 + arch/arm/mach-s3c24xx/include/mach/vr1000-map.h | 110 +++ arch/arm/mach-s3c24xx/irq-s3c2412.c | 214 ++++++ arch/arm/mach-s3c24xx/irq-s3c2416.c | 250 +++++++ arch/arm/mach-s3c24xx/irq-s3c2440.c | 128 ++++ arch/arm/mach-s3c24xx/irq-s3c2443.c | 281 +++++++ arch/arm/mach-s3c24xx/irq-s3c244x.c | 142 ++++ arch/arm/mach-s3c24xx/mach-amlm5900.c | 247 ++++++ arch/arm/mach-s3c24xx/mach-anubis.c | 492 ++++++++++++ arch/arm/mach-s3c24xx/mach-at2440evb.c | 226 ++++++ arch/arm/mach-s3c24xx/mach-bast.c | 644 ++++++++++++++++ arch/arm/mach-s3c24xx/mach-gta02.c | 605 +++++++++++++++ arch/arm/mach-s3c24xx/mach-h1940.c | 757 +++++++++++++++++++ arch/arm/mach-s3c24xx/mach-jive.c | 666 +++++++++++++++++ arch/arm/mach-s3c24xx/mach-mini2440.c | 705 ++++++++++++++++++ arch/arm/mach-s3c24xx/mach-n30.c | 608 +++++++++++++++ arch/arm/mach-s3c24xx/mach-nexcoder.c | 162 ++++ arch/arm/mach-s3c24xx/mach-osiris-dvs.c | 194 +++++ arch/arm/mach-s3c24xx/mach-osiris.c | 440 +++++++++++ arch/arm/mach-s3c24xx/mach-otom.c | 127 ++++ arch/arm/mach-s3c24xx/mach-qt2410.c | 356 +++++++++ arch/arm/mach-s3c24xx/mach-rx1950.c | 826 +++++++++++++++++++++ arch/arm/mach-s3c24xx/mach-rx3715.c | 217 ++++++ arch/arm/mach-s3c24xx/mach-smdk2410.c | 122 +++ arch/arm/mach-s3c24xx/mach-smdk2413.c | 162 ++++ arch/arm/mach-s3c24xx/mach-smdk2416.c | 256 +++++++ arch/arm/mach-s3c24xx/mach-smdk2440.c | 187 +++++ arch/arm/mach-s3c24xx/mach-smdk2443.c | 149 ++++ arch/arm/mach-s3c24xx/mach-tct_hammer.c | 157 ++++ arch/arm/mach-s3c24xx/mach-vr1000.c | 385 ++++++++++ arch/arm/mach-s3c24xx/mach-vstms.c | 166 +++++ arch/arm/mach-s3c24xx/pm-h1940.S | 33 + arch/arm/mach-s3c24xx/pm-s3c2410.c | 180 +++++ arch/arm/mach-s3c24xx/pm-s3c2412.c | 124 ++++ arch/arm/mach-s3c24xx/pm-s3c2416.c | 83 +++ arch/arm/mach-s3c24xx/s3c2410.c | 207 ++++++ arch/arm/mach-s3c24xx/s3c2412.c | 252 +++++++ arch/arm/mach-s3c24xx/s3c2416.c | 149 ++++ arch/arm/mach-s3c24xx/s3c2440.c | 75 ++ arch/arm/mach-s3c24xx/s3c2442.c | 188 +++++ arch/arm/mach-s3c24xx/s3c2443.c | 117 +++ arch/arm/mach-s3c24xx/s3c244x.c | 211 ++++++ arch/arm/mach-s3c24xx/setup-i2c.c | 27 + arch/arm/mach-s3c24xx/setup-sdhci-gpio.c | 34 + arch/arm/mach-s3c24xx/setup-ts.c | 34 + arch/arm/mach-s3c24xx/simtec-audio.c | 79 ++ arch/arm/mach-s3c24xx/simtec-nor.c | 84 +++ arch/arm/mach-s3c24xx/simtec-pm.c | 66 ++ arch/arm/mach-s3c24xx/simtec-usb.c | 132 ++++ arch/arm/mach-s3c24xx/simtec.h | 21 + arch/arm/mach-s3c24xx/sleep-s3c2410.S | 68 ++ arch/arm/mach-s3c24xx/sleep-s3c2412.S | 68 ++ 116 files changed, 20416 insertions(+) create mode 100644 arch/arm/mach-s3c24xx/Kconfig create mode 100644 arch/arm/mach-s3c24xx/Makefile create mode 100644 arch/arm/mach-s3c24xx/Makefile.boot create mode 100644 arch/arm/mach-s3c24xx/bast-ide.c create mode 100644 arch/arm/mach-s3c24xx/bast-irq.c create mode 100644 arch/arm/mach-s3c24xx/clock-s3c2412.c create mode 100644 arch/arm/mach-s3c24xx/clock-s3c2416.c create mode 100644 arch/arm/mach-s3c24xx/clock-s3c2440.c create mode 100644 arch/arm/mach-s3c24xx/clock-s3c2443.c create mode 100644 arch/arm/mach-s3c24xx/clock-s3c244x.c create mode 100644 arch/arm/mach-s3c24xx/common-s3c2443.c create mode 100644 arch/arm/mach-s3c24xx/common-smdk.c create mode 100644 arch/arm/mach-s3c24xx/common.h create mode 100644 arch/arm/mach-s3c24xx/dma-s3c2410.c create mode 100644 arch/arm/mach-s3c24xx/dma-s3c2412.c create mode 100644 arch/arm/mach-s3c24xx/dma-s3c2440.c create mode 100644 arch/arm/mach-s3c24xx/dma-s3c2443.c create mode 100644 arch/arm/mach-s3c24xx/h1940-bluetooth.c create mode 100644 arch/arm/mach-s3c24xx/include/mach/anubis-cpld.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/anubis-irq.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/anubis-map.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/bast-cpld.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/bast-irq.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/bast-map.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/bast-pmu.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/debug-macro.S create mode 100644 arch/arm/mach-s3c24xx/include/mach/dma.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/entry-macro.S create mode 100644 arch/arm/mach-s3c24xx/include/mach/fb.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/gpio-fns.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/gpio-nrs.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/gpio-track.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/gpio.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/gta02.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/h1940-latch.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/h1940.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/hardware.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/idle.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/io.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/irqs.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/leds-gpio.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/map.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/osiris-cpld.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/osiris-map.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/otom-map.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/pm-core.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-clock.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-dsc.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-gpio.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-gpioj.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-irq.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-lcd.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-mem.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-power.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-s3c2412-mem.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-s3c2412.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-s3c2416-mem.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-s3c2416.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/regs-sdi.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/tick.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/timex.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/uncompress.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/vr1000-cpld.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/vr1000-irq.h create mode 100644 arch/arm/mach-s3c24xx/include/mach/vr1000-map.h create mode 100644 arch/arm/mach-s3c24xx/irq-s3c2412.c create mode 100644 arch/arm/mach-s3c24xx/irq-s3c2416.c create mode 100644 arch/arm/mach-s3c24xx/irq-s3c2440.c create mode 100644 arch/arm/mach-s3c24xx/irq-s3c2443.c create mode 100644 arch/arm/mach-s3c24xx/irq-s3c244x.c create mode 100644 arch/arm/mach-s3c24xx/mach-amlm5900.c create mode 100644 arch/arm/mach-s3c24xx/mach-anubis.c create mode 100644 arch/arm/mach-s3c24xx/mach-at2440evb.c create mode 100644 arch/arm/mach-s3c24xx/mach-bast.c create mode 100644 arch/arm/mach-s3c24xx/mach-gta02.c create mode 100644 arch/arm/mach-s3c24xx/mach-h1940.c create mode 100644 arch/arm/mach-s3c24xx/mach-jive.c create mode 100644 arch/arm/mach-s3c24xx/mach-mini2440.c create mode 100644 arch/arm/mach-s3c24xx/mach-n30.c create mode 100644 arch/arm/mach-s3c24xx/mach-nexcoder.c create mode 100644 arch/arm/mach-s3c24xx/mach-osiris-dvs.c create mode 100644 arch/arm/mach-s3c24xx/mach-osiris.c create mode 100644 arch/arm/mach-s3c24xx/mach-otom.c create mode 100644 arch/arm/mach-s3c24xx/mach-qt2410.c create mode 100644 arch/arm/mach-s3c24xx/mach-rx1950.c create mode 100644 arch/arm/mach-s3c24xx/mach-rx3715.c create mode 100644 arch/arm/mach-s3c24xx/mach-smdk2410.c create mode 100644 arch/arm/mach-s3c24xx/mach-smdk2413.c create mode 100644 arch/arm/mach-s3c24xx/mach-smdk2416.c create mode 100644 arch/arm/mach-s3c24xx/mach-smdk2440.c create mode 100644 arch/arm/mach-s3c24xx/mach-smdk2443.c create mode 100644 arch/arm/mach-s3c24xx/mach-tct_hammer.c create mode 100644 arch/arm/mach-s3c24xx/mach-vr1000.c create mode 100644 arch/arm/mach-s3c24xx/mach-vstms.c create mode 100644 arch/arm/mach-s3c24xx/pm-h1940.S create mode 100644 arch/arm/mach-s3c24xx/pm-s3c2410.c create mode 100644 arch/arm/mach-s3c24xx/pm-s3c2412.c create mode 100644 arch/arm/mach-s3c24xx/pm-s3c2416.c create mode 100644 arch/arm/mach-s3c24xx/s3c2410.c create mode 100644 arch/arm/mach-s3c24xx/s3c2412.c create mode 100644 arch/arm/mach-s3c24xx/s3c2416.c create mode 100644 arch/arm/mach-s3c24xx/s3c2440.c create mode 100644 arch/arm/mach-s3c24xx/s3c2442.c create mode 100644 arch/arm/mach-s3c24xx/s3c2443.c create mode 100644 arch/arm/mach-s3c24xx/s3c244x.c create mode 100644 arch/arm/mach-s3c24xx/setup-i2c.c create mode 100644 arch/arm/mach-s3c24xx/setup-sdhci-gpio.c create mode 100644 arch/arm/mach-s3c24xx/setup-ts.c create mode 100644 arch/arm/mach-s3c24xx/simtec-audio.c create mode 100644 arch/arm/mach-s3c24xx/simtec-nor.c create mode 100644 arch/arm/mach-s3c24xx/simtec-pm.c create mode 100644 arch/arm/mach-s3c24xx/simtec-usb.c create mode 100644 arch/arm/mach-s3c24xx/simtec.h create mode 100644 arch/arm/mach-s3c24xx/sleep-s3c2410.S create mode 100644 arch/arm/mach-s3c24xx/sleep-s3c2412.S (limited to 'arch/arm/mach-s3c24xx') diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig new file mode 100644 index 00000000..b34287ab --- /dev/null +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -0,0 +1,538 @@ +# arch/arm/mach-s3c24xx/Kconfig +# +# Copyright (c) 2012 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# Copyright 2007 Simtec Electronics +# +# Licensed under GPLv2 + +if ARCH_S3C24XX + +menu "SAMSUNG S3C24XX SoCs Support" + +comment "S3C24XX SoCs" + +config CPU_S3C2410 + bool "SAMSUNG S3C2410" + default y + select CPU_ARM920T + select S3C2410_CLOCK + select CPU_LLSERIAL_S3C2410 + select S3C2410_PM if PM + select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX + help + Support for S3C2410 and S3C2410A family from the S3C24XX line + of Samsung Mobile CPUs. + +config CPU_S3C2412 + bool "SAMSUNG S3C2412" + depends on ARCH_S3C24XX + select CPU_ARM926T + select CPU_LLSERIAL_S3C2440 + select S3C2412_PM if PM + select S3C2412_DMA if S3C24XX_DMA + help + Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line + +config CPU_S3C2416 + bool "SAMSUNG S3C2416/S3C2450" + depends on ARCH_S3C24XX + select CPU_ARM926T + select CPU_LLSERIAL_S3C2440 + select SAMSUNG_CLKSRC + select S3C2443_COMMON + select S3C2443_DMA if S3C24XX_DMA + select S3C2416_PM if PM + help + Support for the S3C2416 SoC from the S3C24XX line + +config CPU_S3C2440 + bool "SAMSUNG S3C2440" + select CPU_ARM920T + select CPU_LLSERIAL_S3C2440 + select S3C2410_CLOCK + select S3C2410_PM if PM + select S3C2440_DMA if S3C24XX_DMA + help + Support for S3C2440 Samsung Mobile CPU based systems. + +config CPU_S3C2442 + bool "SAMSUNG S3C2442" + select CPU_ARM920T + select CPU_LLSERIAL_S3C2440 + select S3C2410_CLOCK + select S3C2410_PM if PM + help + Support for S3C2442 Samsung Mobile CPU based systems. + +config CPU_S3C244X + def_bool y + depends on CPU_S3C2440 || CPU_S3C2442 + +config CPU_S3C2443 + bool "SAMSUNG S3C2443" + depends on ARCH_S3C24XX + select CPU_ARM920T + select CPU_LLSERIAL_S3C2440 + select SAMSUNG_CLKSRC + select S3C2443_COMMON + select S3C2443_DMA if S3C24XX_DMA + help + Support for the S3C2443 SoC from the S3C24XX line + +# common code + +config S3C24XX_SMDK + bool + help + Common machine code for SMDK2410 and SMDK2440 + +config S3C24XX_SIMTEC_AUDIO + bool + depends on (ARCH_BAST || MACH_VR1000 || MACH_OSIRIS || MACH_ANUBIS) + default y + help + Add audio devices for common Simtec S3C24XX boards + +config S3C24XX_SIMTEC_PM + bool + help + Common power management code for systems that are + compatible with the Simtec style of power management + +config S3C24XX_SIMTEC_USB + bool + help + USB management code for common Simtec S3C24XX boards + +config S3C24XX_SETUP_TS + bool + help + Compile in platform device definition for Samsung TouchScreen. + +config S3C2410_DMA + bool + depends on S3C24XX_DMA && (CPU_S3C2410 || CPU_S3C2442) + default y if CPU_S3C2410 || CPU_S3C2442 + help + DMA device selection for S3C2410 and compatible CPUs + +config S3C2410_PM + bool + help + Power Management code common to S3C2410 and better + +# cpu-specific sections + +if CPU_S3C2410 + +config S3C24XX_SIMTEC_NOR + bool + help + Internal node to specify machine has simtec NOR mapping + +config MACH_BAST_IDE + bool + select HAVE_PATA_PLATFORM + help + Internal node for machines with an BAST style IDE + interface + +comment "S3C2410 Boards" + +# +# The "S3C2410 Boards" list is ordered alphabetically by option text. +# (without ARCH_ or MACH_) +# + +config MACH_AML_M5900 + bool "AML M5900 Series" + select S3C24XX_SIMTEC_PM if PM + select S3C_DEV_USB_HOST + help + Say Y here if you are using the American Microsystems M5900 Series + + +config ARCH_BAST + bool "Simtec Electronics BAST (EB2410ITX)" + select S3C2410_IOTIMING if S3C2410_CPUFREQ + select S3C24XX_SIMTEC_PM if PM + select S3C24XX_SIMTEC_NOR + select S3C24XX_SIMTEC_USB + select MACH_BAST_IDE + select S3C24XX_DCLK + select ISA + select S3C_DEV_HWMON + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the Simtec Electronics EB2410ITX + development board (also known as BAST) + +config BAST_PC104_IRQ + bool "BAST PC104 IRQ support" + depends on ARCH_BAST + default y + help + Say Y here to enable the PC104 IRQ routing on the + Simtec BAST (EB2410ITX) + +config ARCH_H1940 + bool "IPAQ H1940" + select PM_H1940 if PM + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + select S3C24XX_SETUP_TS + help + Say Y here if you are using the HP IPAQ H1940 + +config H1940BT + tristate "Control the state of H1940 bluetooth chip" + depends on ARCH_H1940 + select RFKILL + help + This is a simple driver that is able to control + the state of built in bluetooth chip on h1940. + +config PM_H1940 + bool + help + Internal node for H1940 and related PM + +config MACH_N30 + bool "Acer N30 family" + select MACH_N35 + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you want suppt for the Acer N30, Acer N35, + Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs. + +config MACH_OTOM + bool "NexVision OTOM Board" + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the Nex Vision OTOM board + +config MACH_QT2410 + bool "QT2410" + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the Armzone QT2410 + +config ARCH_SMDK2410 + bool "SMDK2410/A9M2410" + select S3C24XX_SMDK + help + Say Y here if you are using the SMDK2410 or the derived module A9M2410 + + +config MACH_TCT_HAMMER + bool "TCT Hammer Board" + select S3C_DEV_USB_HOST + help + Say Y here if you are using the TinCanTools Hammer Board + + +config MACH_VR1000 + bool "Thorcom VR1000" + select S3C24XX_SIMTEC_PM if PM + select S3C24XX_DCLK + select S3C24XX_SIMTEC_NOR + select MACH_BAST_IDE + select S3C_DEV_USB_HOST + select S3C24XX_SIMTEC_USB + help + Say Y here if you are using the Thorcom VR1000 board. + +endif # CPU_S3C2410 + +config S3C2412_PM_SLEEP + bool + help + Internal config node to apply sleep for S3C2412 power management. + Can be selected by another SoCs such as S3C2416 with similar + sleep procedure. + +if CPU_S3C2412 + +config CPU_S3C2412_ONLY + bool + depends on ARCH_S3C24XX && !CPU_S3C2410 && \ + !CPU_S3C2416 && !CPU_S3C2440 && !CPU_S3C2442 && \ + !CPU_S3C2443 && CPU_S3C2412 + default y + +config S3C2412_DMA + bool + help + Internal config node for S3C2412 DMA support + +config S3C2412_PM + bool + help + Internal config node to apply S3C2412 power management + +comment "S3C2412 Boards" + +# +# The "S3C2412 Boards" list is ordered alphabetically by option text. +# (without ARCH_ or MACH_) +# + +config MACH_JIVE + bool "Logitech Jive" + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the Logitech Jive. + +config MACH_JIVE_SHOW_BOOTLOADER + bool "Allow access to bootloader partitions in MTD (EXPERIMENTAL)" + depends on MACH_JIVE && EXPERIMENTAL + +config MACH_S3C2413 + bool + help + Internal node for S3C2413 version of SMDK2413, so that + machine_is_s3c2413() will work when MACH_SMDK2413 is + selected + +config MACH_SMDK2412 + bool "SMDK2412" + select MACH_SMDK2413 + help + Say Y here if you are using an SMDK2412 + + Note, this shares support with SMDK2413, so will automatically + select MACH_SMDK2413. + +config MACH_SMDK2413 + bool "SMDK2413" + select MACH_S3C2413 + select S3C24XX_SMDK + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using an SMDK2413 + +config MACH_VSTMS + bool "VMSTMS" + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using an VSTMS board + +endif # CPU_S3C2412 + +if CPU_S3C2416 + +config S3C2416_PM + bool + select S3C2412_PM_SLEEP + help + Internal config node to apply S3C2416 power management + +config S3C2416_SETUP_SDHCI + bool + select S3C2416_SETUP_SDHCI_GPIO + help + Internal helper functions for S3C2416 based SDHCI systems + +config S3C2416_SETUP_SDHCI_GPIO + bool + help + Common setup code for SDHCI gpio. + +comment "S3C2416 Boards" + +config MACH_SMDK2416 + bool "SMDK2416" + select S3C24XX_SMDK + select S3C_DEV_FB + select S3C_DEV_HSMMC + select S3C_DEV_HSMMC1 + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + select S3C2416_SETUP_SDHCI + help + Say Y here if you are using an SMDK2416 + +endif # CPU_S3C2416 + +if CPU_S3C2440 + +config S3C2440_DMA + bool + help + Support for S3C2440 specific DMA code5A + +comment "S3C2440 Boards" + +# +# The "S3C2440 Boards" list is ordered alphabetically by option text. +# (without ARCH_ or MACH_) +# + +config MACH_ANUBIS + bool "Simtec Electronics ANUBIS" + select S3C24XX_DCLK + select S3C24XX_SIMTEC_PM if PM + select HAVE_PATA_PLATFORM + select S3C24XX_GPIO_EXTRA64 + select S3C2440_XTAL_12000000 + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Simtec Electronics ANUBIS + development system + +config MACH_AT2440EVB + bool "Avantech AT2440EVB development board" + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the AT2440EVB development board + +config MACH_MINI2440 + bool "MINI2440 development board" + select EEPROM_AT24 + select NEW_LEDS + select LEDS_CLASS + select LEDS_TRIGGER + select LEDS_TRIGGER_BACKLIGHT + select S3C_DEV_NAND + select S3C_DEV_USB_HOST + help + Say Y here to select support for the MINI2440. Is a 10cm x 10cm board + available via various sources. It can come with a 3.5" or 7" touch LCD. + +config MACH_NEXCODER_2440 + bool "NexVision NEXCODER 2440 Light Board" + select S3C2440_XTAL_12000000 + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board + +config MACH_OSIRIS + bool "Simtec IM2440D20 (OSIRIS) module" + select S3C24XX_DCLK + select S3C24XX_SIMTEC_PM if PM + select S3C24XX_GPIO_EXTRA128 + select S3C2440_XTAL_12000000 + select S3C2410_IOTIMING if S3C2440_CPUFREQ + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the Simtec IM2440D20 module, also + known as the Osiris. + +config MACH_OSIRIS_DVS + tristate "Simtec IM2440D20 (OSIRIS) Dynamic Voltage Scaling driver" + depends on MACH_OSIRIS + select TPS65010 + help + Say Y/M here if you want to have dynamic voltage scaling support + on the Simtec IM2440D20 (OSIRIS) module via the TPS65011. + + The DVS driver alters the voltage supplied to the ARM core + depending on the frequency it is running at. The driver itself + does not do any of the frequency alteration, which is left up + to the cpufreq driver. + +config MACH_RX3715 + bool "HP iPAQ rx3715" + select S3C2440_XTAL_16934400 + select PM_H1940 if PM + select S3C_DEV_NAND + help + Say Y here if you are using the HP iPAQ rx3715. + +config ARCH_S3C2440 + bool "SMDK2440" + select S3C2440_XTAL_16934400 + select S3C24XX_SMDK + select S3C_DEV_USB_HOST + select S3C_DEV_NAND + help + Say Y here if you are using the SMDK2440. + +config SMDK2440_CPU2440 + bool "SMDK2440 with S3C2440 CPU module" + default y if ARCH_S3C2440 + select S3C2440_XTAL_16934400 + +endif # CPU_S3C2440 + +if CPU_S3C2442 + +comment "S3C2442 Boards" + +# +# The "S3C2442 Boards" list is ordered alphabetically by option text. +# (without ARCH_ or MACH_) +# + +config MACH_NEO1973_GTA02 + bool "Openmoko GTA02 / Freerunner phone" + select MFD_PCF50633 + select PCF50633_GPIO + select I2C + select POWER_SUPPLY + select MACH_NEO1973 + select S3C2410_PWM + select S3C_DEV_USB_HOST + help + Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone + +config MACH_RX1950 + bool "HP iPAQ rx1950" + select S3C24XX_DCLK + select PM_H1940 if PM + select I2C + select S3C2410_PWM + select S3C_DEV_NAND + select S3C2410_IOTIMING if S3C2440_CPUFREQ + select S3C2440_XTAL_16934400 + help + Say Y here if you're using HP iPAQ rx1950 + +config SMDK2440_CPU2442 + bool "SMDM2440 with S3C2442 CPU module" + +endif # CPU_S3C2440 + +if CPU_S3C2443 || CPU_S3C2416 + +config S3C2443_COMMON + bool + help + Common code for the S3C2443 and similar processors, which includes + the S3C2416 and S3C2450. + +config S3C2443_DMA + bool + help + Internal config node for S3C2443 DMA support + +endif # CPU_S3C2443 || CPU_S3C2416 + +if CPU_S3C2443 + +comment "S3C2443 Boards" + +config MACH_SMDK2443 + bool "SMDK2443" + select S3C24XX_SMDK + select S3C_DEV_HSMMC1 + help + Say Y here if you are using an SMDK2443 + +endif # CPU_S3C2443 + +endmenu # SAMSUNG S3C24XX SoCs Support + +endif # ARCH_S3C24XX diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile new file mode 100644 index 00000000..3518fe81 --- /dev/null +++ b/arch/arm/mach-s3c24xx/Makefile @@ -0,0 +1,95 @@ +# arch/arm/mach-s3c24xx/Makefile +# +# Copyright (c) 2012 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# Copyright 2007 Simtec Electronics +# +# Licensed under GPLv2 + +obj-y := +obj-m := +obj-n := +obj- := + +# core + +obj-$(CONFIG_CPU_S3C2410) += s3c2410.o +obj-$(CONFIG_S3C2410_DMA) += dma-s3c2410.o +obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o + +obj-$(CONFIG_CPU_S3C2412) += s3c2412.o irq-s3c2412.o clock-s3c2412.o +obj-$(CONFIG_S3C2412_DMA) += dma-s3c2412.o +obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o +obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o + +obj-$(CONFIG_CPU_S3C2416) += s3c2416.o irq-s3c2416.o clock-s3c2416.o +obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o + +obj-$(CONFIG_CPU_S3C2440) += s3c2440.o irq-s3c2440.o clock-s3c2440.o +obj-$(CONFIG_CPU_S3C2442) += s3c2442.o +obj-$(CONFIG_CPU_S3C244X) += s3c244x.o irq-s3c244x.o clock-s3c244x.o +obj-$(CONFIG_S3C2440_DMA) += dma-s3c2440.o + +obj-$(CONFIG_CPU_S3C2443) += s3c2443.o irq-s3c2443.o clock-s3c2443.o + +# common code + +obj-$(CONFIG_S3C2443_COMMON) += common-s3c2443.o +obj-$(CONFIG_S3C2443_DMA) += dma-s3c2443.o + +# +# machine support +# following is ordered alphabetically by option text. +# + +obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o +obj-$(CONFIG_ARCH_BAST) += mach-bast.o +obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o +obj-$(CONFIG_ARCH_H1940) += mach-h1940.o +obj-$(CONFIG_H1940BT) += h1940-bluetooth.o +obj-$(CONFIG_PM_H1940) += pm-h1940.o +obj-$(CONFIG_MACH_N30) += mach-n30.o +obj-$(CONFIG_MACH_OTOM) += mach-otom.o +obj-$(CONFIG_MACH_QT2410) += mach-qt2410.o +obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o +obj-$(CONFIG_MACH_TCT_HAMMER) += mach-tct_hammer.o +obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o + +obj-$(CONFIG_MACH_JIVE) += mach-jive.o +obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o +obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o + +obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o + +obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o +obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o +obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o +obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o +obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o +obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o +obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o + +obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o +obj-$(CONFIG_MACH_RX1950) += mach-rx1950.o + +obj-$(CONFIG_MACH_SMDK2443) += mach-smdk2443.o + +# common bits of machine support + +obj-$(CONFIG_S3C24XX_SMDK) += common-smdk.o +obj-$(CONFIG_S3C24XX_SIMTEC_AUDIO) += simtec-audio.o +obj-$(CONFIG_S3C24XX_SIMTEC_NOR) += simtec-nor.o +obj-$(CONFIG_S3C24XX_SIMTEC_PM) += simtec-pm.o +obj-$(CONFIG_S3C24XX_SIMTEC_USB) += simtec-usb.o + +# machine additions + +obj-$(CONFIG_MACH_BAST_IDE) += bast-ide.o +obj-$(CONFIG_MACH_OSIRIS_DVS) += mach-osiris-dvs.o + +# device setup + +obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o +obj-$(CONFIG_ARCH_S3C24XX) += setup-i2c.o +obj-$(CONFIG_S3C24XX_SETUP_TS) += setup-ts.o diff --git a/arch/arm/mach-s3c24xx/Makefile.boot b/arch/arm/mach-s3c24xx/Makefile.boot new file mode 100644 index 00000000..4457605b --- /dev/null +++ b/arch/arm/mach-s3c24xx/Makefile.boot @@ -0,0 +1,7 @@ +ifeq ($(CONFIG_PM_H1940),y) + zreladdr-y += 0x30108000 + params_phys-y := 0x30100100 +else + zreladdr-y += 0x30008000 + params_phys-y := 0x30000100 +endif diff --git a/arch/arm/mach-s3c24xx/bast-ide.c b/arch/arm/mach-s3c24xx/bast-ide.c new file mode 100644 index 00000000..298ececf --- /dev/null +++ b/arch/arm/mach-s3c24xx/bast-ide.c @@ -0,0 +1,112 @@ +/* linux/arch/arm/mach-s3c2410/bast-ide.c + * + * Copyright 2007 Simtec Electronics + * http://www.simtec.co.uk/products/EB2410ITX/ + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * 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 +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +/* IDE ports */ + +static struct pata_platform_info bast_ide_platdata = { + .ioport_shift = 5, +}; + +#define IDE_CS S3C2410_CS5 + +static struct resource bast_ide0_resource[] = { + [0] = { + .start = IDE_CS + BAST_PA_IDEPRI, + .end = IDE_CS + BAST_PA_IDEPRI + (8 * 0x20) - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IDE_CS + BAST_PA_IDEPRIAUX + (6 * 0x20) , + .end = IDE_CS + BAST_PA_IDEPRIAUX + (7 * 0x20) - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_IDE0, + .end = IRQ_IDE0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bast_device_ide0 = { + .name = "pata_platform", + .id = 0, + .num_resources = ARRAY_SIZE(bast_ide0_resource), + .resource = bast_ide0_resource, + .dev = { + .platform_data = &bast_ide_platdata, + .coherent_dma_mask = ~0, + } + +}; + +static struct resource bast_ide1_resource[] = { + [0] = { + .start = IDE_CS + BAST_PA_IDESEC, + .end = IDE_CS + BAST_PA_IDESEC + (8 * 0x20) - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IDE_CS + BAST_PA_IDESECAUX + (6 * 0x20), + .end = IDE_CS + BAST_PA_IDESECAUX + (7 * 0x20) - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_IDE1, + .end = IRQ_IDE1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bast_device_ide1 = { + .name = "pata_platform", + .id = 1, + .num_resources = ARRAY_SIZE(bast_ide1_resource), + .resource = bast_ide1_resource, + .dev = { + .platform_data = &bast_ide_platdata, + .coherent_dma_mask = ~0, + } +}; + +static struct platform_device *bast_ide_devices[] __initdata = { + &bast_device_ide0, + &bast_device_ide1, +}; + +static __init int bast_ide_init(void) +{ + if (machine_is_bast() || machine_is_vr1000()) + return platform_add_devices(bast_ide_devices, + ARRAY_SIZE(bast_ide_devices)); + + return 0; +} + +fs_initcall(bast_ide_init); diff --git a/arch/arm/mach-s3c24xx/bast-irq.c b/arch/arm/mach-s3c24xx/bast-irq.c new file mode 100644 index 00000000..ac7b2ad5 --- /dev/null +++ b/arch/arm/mach-s3c24xx/bast-irq.c @@ -0,0 +1,166 @@ +/* linux/arch/arm/mach-s3c2410/bast-irq.c + * + * Copyright 2003-2005 Simtec Electronics + * Ben Dooks + * + * http://www.simtec.co.uk/products/EB2410ITX/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include +#include + +#include + +#if 0 +#include +#endif + +#define irqdbf(x...) +#define irqdbf2(x...) + + +/* handle PC104 ISA interrupts from the system CPLD */ + +/* table of ISA irq nos to the relevant mask... zero means + * the irq is not implemented +*/ +static unsigned char bast_pc104_irqmasks[] = { + 0, /* 0 */ + 0, /* 1 */ + 0, /* 2 */ + 1, /* 3 */ + 0, /* 4 */ + 2, /* 5 */ + 0, /* 6 */ + 4, /* 7 */ + 0, /* 8 */ + 0, /* 9 */ + 8, /* 10 */ + 0, /* 11 */ + 0, /* 12 */ + 0, /* 13 */ + 0, /* 14 */ + 0, /* 15 */ +}; + +static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 }; + +static void +bast_pc104_mask(struct irq_data *data) +{ + unsigned long temp; + + temp = __raw_readb(BAST_VA_PC104_IRQMASK); + temp &= ~bast_pc104_irqmasks[data->irq]; + __raw_writeb(temp, BAST_VA_PC104_IRQMASK); +} + +static void +bast_pc104_maskack(struct irq_data *data) +{ + struct irq_desc *desc = irq_desc + IRQ_ISA; + + bast_pc104_mask(data); + desc->irq_data.chip->irq_ack(&desc->irq_data); +} + +static void +bast_pc104_unmask(struct irq_data *data) +{ + unsigned long temp; + + temp = __raw_readb(BAST_VA_PC104_IRQMASK); + temp |= bast_pc104_irqmasks[data->irq]; + __raw_writeb(temp, BAST_VA_PC104_IRQMASK); +} + +static struct irq_chip bast_pc104_chip = { + .irq_mask = bast_pc104_mask, + .irq_unmask = bast_pc104_unmask, + .irq_ack = bast_pc104_maskack +}; + +static void +bast_irq_pc104_demux(unsigned int irq, + struct irq_desc *desc) +{ + unsigned int stat; + unsigned int irqno; + int i; + + stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf; + + if (unlikely(stat == 0)) { + /* ack if we get an irq with nothing (ie, startup) */ + + desc = irq_desc + IRQ_ISA; + desc->irq_data.chip->irq_ack(&desc->irq_data); + } else { + /* handle the IRQ */ + + for (i = 0; stat != 0; i++, stat >>= 1) { + if (stat & 1) { + irqno = bast_pc104_irqs[i]; + generic_handle_irq(irqno); + } + } + } +} + +static __init int bast_irq_init(void) +{ + unsigned int i; + + if (machine_is_bast()) { + printk(KERN_INFO "BAST PC104 IRQ routing, Copyright 2005 Simtec Electronics\n"); + + /* zap all the IRQs */ + + __raw_writeb(0x0, BAST_VA_PC104_IRQMASK); + + irq_set_chained_handler(IRQ_ISA, bast_irq_pc104_demux); + + /* register our IRQs */ + + for (i = 0; i < 4; i++) { + unsigned int irqno = bast_pc104_irqs[i]; + + irq_set_chip_and_handler(irqno, &bast_pc104_chip, + handle_level_irq); + set_irq_flags(irqno, IRQF_VALID); + } + } + + return 0; +} + +arch_initcall(bast_irq_init); diff --git a/arch/arm/mach-s3c24xx/clock-s3c2412.c b/arch/arm/mach-s3c24xx/clock-s3c2412.c new file mode 100644 index 00000000..d10b695a --- /dev/null +++ b/arch/arm/mach-s3c24xx/clock-s3c2412.c @@ -0,0 +1,763 @@ +/* linux/arch/arm/mach-s3c2412/clock.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * S3C2412,S3C2413 Clock control support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include + +/* We currently have to assume that the system is running + * from the XTPll input, and that all ***REFCLKs are being + * fed from it, as we cannot read the state of OM[4] from + * software. + * + * It would be possible for each board initialisation to + * set the correct muxing at initialisation +*/ + +static int s3c2412_clkcon_enable(struct clk *clk, int enable) +{ + unsigned int clocks = clk->ctrlbit; + unsigned long clkcon; + + clkcon = __raw_readl(S3C2410_CLKCON); + + if (enable) + clkcon |= clocks; + else + clkcon &= ~clocks; + + __raw_writel(clkcon, S3C2410_CLKCON); + + return 0; +} + +static int s3c2412_upll_enable(struct clk *clk, int enable) +{ + unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); + unsigned long orig = upllcon; + + if (!enable) + upllcon |= S3C2412_PLLCON_OFF; + else + upllcon &= ~S3C2412_PLLCON_OFF; + + __raw_writel(upllcon, S3C2410_UPLLCON); + + /* allow ~150uS for the PLL to settle and lock */ + + if (enable && (orig & S3C2412_PLLCON_OFF)) + udelay(150); + + return 0; +} + +/* clock selections */ + +static struct clk clk_erefclk = { + .name = "erefclk", +}; + +static struct clk clk_urefclk = { + .name = "urefclk", +}; + +static int s3c2412_setparent_usysclk(struct clk *clk, struct clk *parent) +{ + unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); + + if (parent == &clk_urefclk) + clksrc &= ~S3C2412_CLKSRC_USYSCLK_UPLL; + else if (parent == &clk_upll) + clksrc |= S3C2412_CLKSRC_USYSCLK_UPLL; + else + return -EINVAL; + + clk->parent = parent; + + __raw_writel(clksrc, S3C2412_CLKSRC); + return 0; +} + +static struct clk clk_usysclk = { + .name = "usysclk", + .parent = &clk_xtal, + .ops = &(struct clk_ops) { + .set_parent = s3c2412_setparent_usysclk, + }, +}; + +static struct clk clk_mrefclk = { + .name = "mrefclk", + .parent = &clk_xtal, +}; + +static struct clk clk_mdivclk = { + .name = "mdivclk", + .parent = &clk_xtal, +}; + +static int s3c2412_setparent_usbsrc(struct clk *clk, struct clk *parent) +{ + unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); + + if (parent == &clk_usysclk) + clksrc &= ~S3C2412_CLKSRC_USBCLK_HCLK; + else if (parent == &clk_h) + clksrc |= S3C2412_CLKSRC_USBCLK_HCLK; + else + return -EINVAL; + + clk->parent = parent; + + __raw_writel(clksrc, S3C2412_CLKSRC); + return 0; +} + +static unsigned long s3c2412_roundrate_usbsrc(struct clk *clk, + unsigned long rate) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + int div; + + if (rate > parent_rate) + return parent_rate; + + div = parent_rate / rate; + if (div > 2) + div = 2; + + return parent_rate / div; +} + +static unsigned long s3c2412_getrate_usbsrc(struct clk *clk) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + unsigned long div = __raw_readl(S3C2410_CLKDIVN); + + return parent_rate / ((div & S3C2412_CLKDIVN_USB48DIV) ? 2 : 1); +} + +static int s3c2412_setrate_usbsrc(struct clk *clk, unsigned long rate) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN); + + rate = s3c2412_roundrate_usbsrc(clk, rate); + + if ((parent_rate / rate) == 2) + clkdivn |= S3C2412_CLKDIVN_USB48DIV; + else + clkdivn &= ~S3C2412_CLKDIVN_USB48DIV; + + __raw_writel(clkdivn, S3C2410_CLKDIVN); + return 0; +} + +static struct clk clk_usbsrc = { + .name = "usbsrc", + .ops = &(struct clk_ops) { + .get_rate = s3c2412_getrate_usbsrc, + .set_rate = s3c2412_setrate_usbsrc, + .round_rate = s3c2412_roundrate_usbsrc, + .set_parent = s3c2412_setparent_usbsrc, + }, +}; + +static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent) +{ + unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); + + if (parent == &clk_mdivclk) + clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL; + else if (parent == &clk_mpll) + clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL; + else + return -EINVAL; + + clk->parent = parent; + + __raw_writel(clksrc, S3C2412_CLKSRC); + return 0; +} + +static struct clk clk_msysclk = { + .name = "msysclk", + .ops = &(struct clk_ops) { + .set_parent = s3c2412_setparent_msysclk, + }, +}; + +static int s3c2412_setparent_armclk(struct clk *clk, struct clk *parent) +{ + unsigned long flags; + unsigned long clkdiv; + unsigned long dvs; + + /* Note, we current equate fclk andf msysclk for S3C2412 */ + + if (parent == &clk_msysclk || parent == &clk_f) + dvs = 0; + else if (parent == &clk_h) + dvs = S3C2412_CLKDIVN_DVSEN; + else + return -EINVAL; + + clk->parent = parent; + + /* update this under irq lockdown, clkdivn is not protected + * by the clock system. */ + + local_irq_save(flags); + + clkdiv = __raw_readl(S3C2410_CLKDIVN); + clkdiv &= ~S3C2412_CLKDIVN_DVSEN; + clkdiv |= dvs; + __raw_writel(clkdiv, S3C2410_CLKDIVN); + + local_irq_restore(flags); + + return 0; +} + +static struct clk clk_armclk = { + .name = "armclk", + .parent = &clk_msysclk, + .ops = &(struct clk_ops) { + .set_parent = s3c2412_setparent_armclk, + }, +}; + +/* these next clocks have an divider immediately after them, + * so we can register them with their divider and leave out the + * intermediate clock stage +*/ +static unsigned long s3c2412_roundrate_clksrc(struct clk *clk, + unsigned long rate) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + int div; + + if (rate > parent_rate) + return parent_rate; + + /* note, we remove the +/- 1 calculations as they cancel out */ + + div = (rate / parent_rate); + + if (div < 1) + div = 1; + else if (div > 16) + div = 16; + + return parent_rate / div; +} + +static int s3c2412_setparent_uart(struct clk *clk, struct clk *parent) +{ + unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); + + if (parent == &clk_erefclk) + clksrc &= ~S3C2412_CLKSRC_UARTCLK_MPLL; + else if (parent == &clk_mpll) + clksrc |= S3C2412_CLKSRC_UARTCLK_MPLL; + else + return -EINVAL; + + clk->parent = parent; + + __raw_writel(clksrc, S3C2412_CLKSRC); + return 0; +} + +static unsigned long s3c2412_getrate_uart(struct clk *clk) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + unsigned long div = __raw_readl(S3C2410_CLKDIVN); + + div &= S3C2412_CLKDIVN_UARTDIV_MASK; + div >>= S3C2412_CLKDIVN_UARTDIV_SHIFT; + + return parent_rate / (div + 1); +} + +static int s3c2412_setrate_uart(struct clk *clk, unsigned long rate) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN); + + rate = s3c2412_roundrate_clksrc(clk, rate); + + clkdivn &= ~S3C2412_CLKDIVN_UARTDIV_MASK; + clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_UARTDIV_SHIFT; + + __raw_writel(clkdivn, S3C2410_CLKDIVN); + return 0; +} + +static struct clk clk_uart = { + .name = "uartclk", + .ops = &(struct clk_ops) { + .get_rate = s3c2412_getrate_uart, + .set_rate = s3c2412_setrate_uart, + .set_parent = s3c2412_setparent_uart, + .round_rate = s3c2412_roundrate_clksrc, + }, +}; + +static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent) +{ + unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); + + if (parent == &clk_erefclk) + clksrc &= ~S3C2412_CLKSRC_I2SCLK_MPLL; + else if (parent == &clk_mpll) + clksrc |= S3C2412_CLKSRC_I2SCLK_MPLL; + else + return -EINVAL; + + clk->parent = parent; + + __raw_writel(clksrc, S3C2412_CLKSRC); + return 0; +} + +static unsigned long s3c2412_getrate_i2s(struct clk *clk) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + unsigned long div = __raw_readl(S3C2410_CLKDIVN); + + div &= S3C2412_CLKDIVN_I2SDIV_MASK; + div >>= S3C2412_CLKDIVN_I2SDIV_SHIFT; + + return parent_rate / (div + 1); +} + +static int s3c2412_setrate_i2s(struct clk *clk, unsigned long rate) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN); + + rate = s3c2412_roundrate_clksrc(clk, rate); + + clkdivn &= ~S3C2412_CLKDIVN_I2SDIV_MASK; + clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_I2SDIV_SHIFT; + + __raw_writel(clkdivn, S3C2410_CLKDIVN); + return 0; +} + +static struct clk clk_i2s = { + .name = "i2sclk", + .ops = &(struct clk_ops) { + .get_rate = s3c2412_getrate_i2s, + .set_rate = s3c2412_setrate_i2s, + .set_parent = s3c2412_setparent_i2s, + .round_rate = s3c2412_roundrate_clksrc, + }, +}; + +static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent) +{ + unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); + + if (parent == &clk_usysclk) + clksrc &= ~S3C2412_CLKSRC_CAMCLK_HCLK; + else if (parent == &clk_h) + clksrc |= S3C2412_CLKSRC_CAMCLK_HCLK; + else + return -EINVAL; + + clk->parent = parent; + + __raw_writel(clksrc, S3C2412_CLKSRC); + return 0; +} +static unsigned long s3c2412_getrate_cam(struct clk *clk) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + unsigned long div = __raw_readl(S3C2410_CLKDIVN); + + div &= S3C2412_CLKDIVN_CAMDIV_MASK; + div >>= S3C2412_CLKDIVN_CAMDIV_SHIFT; + + return parent_rate / (div + 1); +} + +static int s3c2412_setrate_cam(struct clk *clk, unsigned long rate) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN); + + rate = s3c2412_roundrate_clksrc(clk, rate); + + clkdivn &= ~S3C2412_CLKDIVN_CAMDIV_MASK; + clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_CAMDIV_SHIFT; + + __raw_writel(clkdivn, S3C2410_CLKDIVN); + return 0; +} + +static struct clk clk_cam = { + .name = "camif-upll", /* same as 2440 name */ + .ops = &(struct clk_ops) { + .get_rate = s3c2412_getrate_cam, + .set_rate = s3c2412_setrate_cam, + .set_parent = s3c2412_setparent_cam, + .round_rate = s3c2412_roundrate_clksrc, + }, +}; + +/* standard clock definitions */ + +static struct clk init_clocks_disable[] = { + { + .name = "nand", + .parent = &clk_h, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_NAND, + }, { + .name = "sdi", + .parent = &clk_p, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_SDI, + }, { + .name = "adc", + .parent = &clk_p, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_ADC, + }, { + .name = "i2c", + .parent = &clk_p, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_IIC, + }, { + .name = "iis", + .parent = &clk_p, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_IIS, + }, { + .name = "spi", + .parent = &clk_p, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_SPI, + } +}; + +static struct clk init_clocks[] = { + { + .name = "dma", + .parent = &clk_h, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_DMA0, + }, { + .name = "dma", + .parent = &clk_h, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_DMA1, + }, { + .name = "dma", + .parent = &clk_h, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_DMA2, + }, { + .name = "dma", + .parent = &clk_h, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_DMA3, + }, { + .name = "lcd", + .parent = &clk_h, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_LCDC, + }, { + .name = "gpio", + .parent = &clk_p, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_GPIO, + }, { + .name = "usb-host", + .parent = &clk_h, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_USBH, + }, { + .name = "usb-device", + .parent = &clk_h, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_USBD, + }, { + .name = "timers", + .parent = &clk_p, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_PWMT, + }, { + .name = "uart", + .devname = "s3c2412-uart.0", + .parent = &clk_p, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_UART0, + }, { + .name = "uart", + .devname = "s3c2412-uart.1", + .parent = &clk_p, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_UART1, + }, { + .name = "uart", + .devname = "s3c2412-uart.2", + .parent = &clk_p, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_UART2, + }, { + .name = "rtc", + .parent = &clk_p, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_RTC, + }, { + .name = "watchdog", + .parent = &clk_p, + .ctrlbit = 0, + }, { + .name = "usb-bus-gadget", + .parent = &clk_usb_bus, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_USB_DEV48, + }, { + .name = "usb-bus-host", + .parent = &clk_usb_bus, + .enable = s3c2412_clkcon_enable, + .ctrlbit = S3C2412_CLKCON_USB_HOST48, + } +}; + +/* clocks to add where we need to check their parentage */ + +struct clk_init { + struct clk *clk; + unsigned int bit; + struct clk *src_0; + struct clk *src_1; +}; + +static struct clk_init clks_src[] __initdata = { + { + .clk = &clk_usysclk, + .bit = S3C2412_CLKSRC_USBCLK_HCLK, + .src_0 = &clk_urefclk, + .src_1 = &clk_upll, + }, { + .clk = &clk_i2s, + .bit = S3C2412_CLKSRC_I2SCLK_MPLL, + .src_0 = &clk_erefclk, + .src_1 = &clk_mpll, + }, { + .clk = &clk_cam, + .bit = S3C2412_CLKSRC_CAMCLK_HCLK, + .src_0 = &clk_usysclk, + .src_1 = &clk_h, + }, { + .clk = &clk_msysclk, + .bit = S3C2412_CLKSRC_MSYSCLK_MPLL, + .src_0 = &clk_mdivclk, + .src_1 = &clk_mpll, + }, { + .clk = &clk_uart, + .bit = S3C2412_CLKSRC_UARTCLK_MPLL, + .src_0 = &clk_erefclk, + .src_1 = &clk_mpll, + }, { + .clk = &clk_usbsrc, + .bit = S3C2412_CLKSRC_USBCLK_HCLK, + .src_0 = &clk_usysclk, + .src_1 = &clk_h, + /* here we assume OM[4] select xtal */ + }, { + .clk = &clk_erefclk, + .bit = S3C2412_CLKSRC_EREFCLK_EXTCLK, + .src_0 = &clk_xtal, + .src_1 = &clk_ext, + }, { + .clk = &clk_urefclk, + .bit = S3C2412_CLKSRC_UREFCLK_EXTCLK, + .src_0 = &clk_xtal, + .src_1 = &clk_ext, + }, +}; + +/* s3c2412_clk_initparents + * + * Initialise the parents for the clocks that we get at start-time +*/ + +static void __init s3c2412_clk_initparents(void) +{ + unsigned long clksrc = __raw_readl(S3C2412_CLKSRC); + struct clk_init *cip = clks_src; + struct clk *src; + int ptr; + int ret; + + for (ptr = 0; ptr < ARRAY_SIZE(clks_src); ptr++, cip++) { + ret = s3c24xx_register_clock(cip->clk); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + cip->clk->name, ret); + } + + src = (clksrc & cip->bit) ? cip->src_1 : cip->src_0; + + printk(KERN_INFO "%s: parent %s\n", cip->clk->name, src->name); + clk_set_parent(cip->clk, src); + } +} + +/* clocks to add straight away */ + +static struct clk *clks[] __initdata = { + &clk_ext, + &clk_usb_bus, + &clk_mrefclk, + &clk_armclk, +}; + +static struct clk_lookup s3c2412_clk_lookup[] = { + CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk), + CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), + CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_usysclk), +}; + +int __init s3c2412_baseclk_add(void) +{ + unsigned long clkcon = __raw_readl(S3C2410_CLKCON); + unsigned int dvs; + struct clk *clkp; + int ret; + int ptr; + + clk_upll.enable = s3c2412_upll_enable; + clk_usb_bus.parent = &clk_usbsrc; + clk_usb_bus.rate = 0x0; + + clk_f.parent = &clk_msysclk; + + s3c2412_clk_initparents(); + + for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) { + clkp = clks[ptr]; + + ret = s3c24xx_register_clock(clkp); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + } + + /* set the dvs state according to what we got at boot time */ + + dvs = __raw_readl(S3C2410_CLKDIVN) & S3C2412_CLKDIVN_DVSEN; + + if (dvs) + clk_armclk.parent = &clk_h; + + printk(KERN_INFO "S3C2412: DVS is %s\n", dvs ? "on" : "off"); + + /* ensure usb bus clock is within correct rate of 48MHz */ + + if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) { + printk(KERN_INFO "Warning: USB bus clock not at 48MHz\n"); + + /* for the moment, let's use the UPLL, and see if we can + * get 48MHz */ + + clk_set_parent(&clk_usysclk, &clk_upll); + clk_set_parent(&clk_usbsrc, &clk_usysclk); + clk_set_rate(&clk_usbsrc, 48*1000*1000); + } + + printk("S3C2412: upll %s, %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n", + (__raw_readl(S3C2410_UPLLCON) & S3C2412_PLLCON_OFF) ? "off":"on", + print_mhz(clk_get_rate(&clk_upll)), + print_mhz(clk_get_rate(&clk_usb_bus))); + + /* register clocks from clock array */ + + clkp = init_clocks; + for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { + /* ensure that we note the clock state */ + + clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0; + + ret = s3c24xx_register_clock(clkp); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + } + + /* We must be careful disabling the clocks we are not intending to + * be using at boot time, as subsystems such as the LCD which do + * their own DMA requests to the bus can cause the system to lockup + * if they where in the middle of requesting bus access. + * + * Disabling the LCD clock if the LCD is active is very dangerous, + * and therefore the bootloader should be careful to not enable + * the LCD clock if it is not needed. + */ + + /* install (and disable) the clocks we do not need immediately */ + + 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); + } + + s3c2412_clkcon_enable(clkp, 0); + } + + clkdev_add_table(s3c2412_clk_lookup, ARRAY_SIZE(s3c2412_clk_lookup)); + s3c_pwmclk_init(); + return 0; +} diff --git a/arch/arm/mach-s3c24xx/clock-s3c2416.c b/arch/arm/mach-s3c24xx/clock-s3c2416.c new file mode 100644 index 00000000..dbc9ab4a --- /dev/null +++ b/arch/arm/mach-s3c24xx/clock-s3c2416.c @@ -0,0 +1,172 @@ +/* linux/arch/arm/mach-s3c2416/clock.c + * + * Copyright (c) 2010 Simtec Electronics + * Copyright (c) 2010 Ben Dooks + * + * S3C2416 Clock control support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +/* armdiv + * + * this clock is sourced from msysclk and can have a number of + * divider values applied to it to then be fed into armclk. + * The real clock definition is done in s3c2443-clock.c, + * only the armdiv divisor table must be defined here. +*/ + +static unsigned int armdiv[8] = { + [0] = 1, + [1] = 2, + [2] = 3, + [3] = 4, + [5] = 6, + [7] = 8, +}; + +static struct clksrc_clk hsspi_eplldiv = { + .clk = { + .name = "hsspi-eplldiv", + .parent = &clk_esysclk.clk, + .ctrlbit = (1 << 14), + .enable = s3c2443_clkcon_enable_s, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 24 }, +}; + +static struct clk *hsspi_sources[] = { + [0] = &hsspi_eplldiv.clk, + [1] = NULL, /* to fix */ +}; + +static struct clksrc_clk hsspi_mux = { + .clk = { + .name = "hsspi-if", + }, + .sources = &(struct clksrc_sources) { + .sources = hsspi_sources, + .nr_sources = ARRAY_SIZE(hsspi_sources), + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 18 }, +}; + +static struct clksrc_clk hsmmc_div[] = { + [0] = { + .clk = { + .name = "hsmmc-div", + .devname = "s3c-sdhci.0", + .parent = &clk_esysclk.clk, + }, + .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 }, + }, + [1] = { + .clk = { + .name = "hsmmc-div", + .devname = "s3c-sdhci.1", + .parent = &clk_esysclk.clk, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 }, + }, +}; + +static struct clksrc_clk hsmmc_mux0 = { + .clk = { + .name = "hsmmc-if", + .devname = "s3c-sdhci.0", + .ctrlbit = (1 << 6), + .enable = s3c2443_clkcon_enable_s, + }, + .sources = &(struct clksrc_sources) { + .nr_sources = 2, + .sources = (struct clk * []) { + [0] = &hsmmc_div[0].clk, + [1] = NULL, /* to fix */ + }, + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 }, +}; + +static struct clksrc_clk hsmmc_mux1 = { + .clk = { + .name = "hsmmc-if", + .devname = "s3c-sdhci.1", + .ctrlbit = (1 << 12), + .enable = s3c2443_clkcon_enable_s, + }, + .sources = &(struct clksrc_sources) { + .nr_sources = 2, + .sources = (struct clk * []) { + [0] = &hsmmc_div[1].clk, + [1] = NULL, /* to fix */ + }, + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 }, +}; + +static struct clk hsmmc0_clk = { + .name = "hsmmc", + .devname = "s3c-sdhci.0", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2416_HCLKCON_HSMMC0, +}; + +static struct clksrc_clk *clksrcs[] __initdata = { + &hsspi_eplldiv, + &hsspi_mux, + &hsmmc_div[0], + &hsmmc_div[1], + &hsmmc_mux0, + &hsmmc_mux1, +}; + +static struct clk_lookup s3c2416_clk_lookup[] = { + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk), +}; + +void __init s3c2416_init_clocks(int xtal) +{ + u32 epllcon = __raw_readl(S3C2443_EPLLCON); + u32 epllcon1 = __raw_readl(S3C2443_EPLLCON+4); + int ptr; + + /* s3c2416 EPLL compatible with s3c64xx */ + clk_epll.rate = s3c_get_pll6553x(xtal, epllcon, epllcon1); + + clk_epll.parent = &clk_epllref.clk; + + s3c2443_common_init_clocks(xtal, s3c2416_get_pll, + armdiv, ARRAY_SIZE(armdiv), + S3C2416_CLKDIV0_ARMDIV_MASK); + + for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) + s3c_register_clksrc(clksrcs[ptr], 1); + + s3c24xx_register_clock(&hsmmc0_clk); + clkdev_add_table(s3c2416_clk_lookup, ARRAY_SIZE(s3c2416_clk_lookup)); + + s3c_pwmclk_init(); + +} diff --git a/arch/arm/mach-s3c24xx/clock-s3c2440.c b/arch/arm/mach-s3c24xx/clock-s3c2440.c new file mode 100644 index 00000000..414364eb --- /dev/null +++ b/arch/arm/mach-s3c24xx/clock-s3c2440.c @@ -0,0 +1,194 @@ +/* linux/arch/arm/mach-s3c2440/clock.c + * + * Copyright (c) 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C2440 Clock support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +/* S3C2440 extended clock support */ + +static unsigned long s3c2440_camif_upll_round(struct clk *clk, + unsigned long rate) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + int div; + + if (rate > parent_rate) + return parent_rate; + + /* note, we remove the +/- 1 calculations for the divisor */ + + div = (parent_rate / rate) / 2; + + if (div < 1) + div = 1; + else if (div > 16) + div = 16; + + return parent_rate / (div * 2); +} + +static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); + + rate = s3c2440_camif_upll_round(clk, rate); + + camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK); + + if (rate != parent_rate) { + camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL; + camdivn |= (((parent_rate / rate) / 2) - 1); + } + + __raw_writel(camdivn, S3C2440_CAMDIVN); + + return 0; +} + +/* Extra S3C2440 clocks */ + +static struct clk s3c2440_clk_cam = { + .name = "camif", + .enable = s3c2410_clkcon_enable, + .ctrlbit = S3C2440_CLKCON_CAMERA, +}; + +static struct clk s3c2440_clk_cam_upll = { + .name = "camif-upll", + .ops = &(struct clk_ops) { + .set_rate = s3c2440_camif_upll_setrate, + .round_rate = s3c2440_camif_upll_round, + }, +}; + +static struct clk s3c2440_clk_ac97 = { + .name = "ac97", + .enable = s3c2410_clkcon_enable, + .ctrlbit = S3C2440_CLKCON_CAMERA, +}; + +static unsigned long s3c2440_fclk_n_getrate(struct clk *clk) +{ + unsigned long ucon0, ucon1, ucon2, divisor; + + /* the fun of calculating the uart divisors on the s3c2440 */ + ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON); + ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON); + ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON); + + ucon0 &= S3C2440_UCON0_DIVMASK; + ucon1 &= S3C2440_UCON1_DIVMASK; + ucon2 &= S3C2440_UCON2_DIVMASK; + + if (ucon0 != 0) + divisor = (ucon0 >> S3C2440_UCON_DIVSHIFT) + 6; + else if (ucon1 != 0) + divisor = (ucon1 >> S3C2440_UCON_DIVSHIFT) + 21; + else if (ucon2 != 0) + divisor = (ucon2 >> S3C2440_UCON_DIVSHIFT) + 36; + else + /* manual calims 44, seems to be 9 */ + divisor = 9; + + return clk_get_rate(clk->parent) / divisor; +} + +static struct clk s3c2440_clk_fclk_n = { + .name = "fclk_n", + .parent = &clk_f, + .ops = &(struct clk_ops) { + .get_rate = s3c2440_fclk_n_getrate, + }, +}; + +static struct clk_lookup s3c2440_clk_lookup[] = { + CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk), + CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), + CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n), +}; + +static int s3c2440_clk_add(struct device *dev, struct subsys_interface *sif) +{ + struct clk *clock_upll; + struct clk *clock_h; + struct clk *clock_p; + + clock_p = clk_get(NULL, "pclk"); + clock_h = clk_get(NULL, "hclk"); + clock_upll = clk_get(NULL, "upll"); + + if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) { + printk(KERN_ERR "S3C2440: Failed to get parent clocks\n"); + return -EINVAL; + } + + s3c2440_clk_cam.parent = clock_h; + s3c2440_clk_ac97.parent = clock_p; + s3c2440_clk_cam_upll.parent = clock_upll; + s3c24xx_register_clock(&s3c2440_clk_fclk_n); + + s3c24xx_register_clock(&s3c2440_clk_ac97); + s3c24xx_register_clock(&s3c2440_clk_cam); + s3c24xx_register_clock(&s3c2440_clk_cam_upll); + clkdev_add_table(s3c2440_clk_lookup, ARRAY_SIZE(s3c2440_clk_lookup)); + + clk_disable(&s3c2440_clk_ac97); + clk_disable(&s3c2440_clk_cam); + + return 0; +} + +static struct subsys_interface s3c2440_clk_interface = { + .name = "s3c2440_clk", + .subsys = &s3c2440_subsys, + .add_dev = s3c2440_clk_add, +}; + +static __init int s3c24xx_clk_init(void) +{ + return subsys_interface_register(&s3c2440_clk_interface); +} + +arch_initcall(s3c24xx_clk_init); diff --git a/arch/arm/mach-s3c24xx/clock-s3c2443.c b/arch/arm/mach-s3c24xx/clock-s3c2443.c new file mode 100644 index 00000000..efb3ac35 --- /dev/null +++ b/arch/arm/mach-s3c24xx/clock-s3c2443.c @@ -0,0 +1,215 @@ +/* linux/arch/arm/mach-s3c2443/clock.c + * + * Copyright (c) 2007, 2010 Simtec Electronics + * Ben Dooks + * + * S3C2443 Clock control support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include + +#include +#include +#include +#include + +/* We currently have to assume that the system is running + * from the XTPll input, and that all ***REFCLKs are being + * fed from it, as we cannot read the state of OM[4] from + * software. + * + * It would be possible for each board initialisation to + * set the correct muxing at initialisation +*/ + +/* clock selections */ + +/* armdiv + * + * this clock is sourced from msysclk and can have a number of + * divider values applied to it to then be fed into armclk. + * The real clock definition is done in s3c2443-clock.c, + * only the armdiv divisor table must be defined here. +*/ + +static unsigned int armdiv[16] = { + [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1, + [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2, + [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 3, + [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 4, + [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 6, + [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 8, + [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 12, + [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16, +}; + +/* hsspi + * + * high-speed spi clock, sourced from esysclk +*/ + +static struct clksrc_clk clk_hsspi = { + .clk = { + .name = "hsspi-if", + .parent = &clk_esysclk.clk, + .ctrlbit = S3C2443_SCLKCON_HSSPICLK, + .enable = s3c2443_clkcon_enable_s, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 }, +}; + + +/* clk_hsmcc_div + * + * this clock is sourced from epll, and is fed through a divider, + * to a mux controlled by sclkcon where either it or a extclk can + * be fed to the hsmmc block +*/ + +static struct clksrc_clk clk_hsmmc_div = { + .clk = { + .name = "hsmmc-div", + .devname = "s3c-sdhci.1", + .parent = &clk_esysclk.clk, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 }, +}; + +static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent) +{ + unsigned long clksrc = __raw_readl(S3C2443_SCLKCON); + + clksrc &= ~(S3C2443_SCLKCON_HSMMCCLK_EXT | + S3C2443_SCLKCON_HSMMCCLK_EPLL); + + if (parent == &clk_epll) + clksrc |= S3C2443_SCLKCON_HSMMCCLK_EPLL; + else if (parent == &clk_ext) + clksrc |= S3C2443_SCLKCON_HSMMCCLK_EXT; + else + return -EINVAL; + + if (clk->usage > 0) { + __raw_writel(clksrc, S3C2443_SCLKCON); + } + + clk->parent = parent; + return 0; +} + +static int s3c2443_enable_hsmmc(struct clk *clk, int enable) +{ + return s3c2443_setparent_hsmmc(clk, clk->parent); +} + +static struct clk clk_hsmmc = { + .name = "hsmmc-if", + .devname = "s3c-sdhci.1", + .parent = &clk_hsmmc_div.clk, + .enable = s3c2443_enable_hsmmc, + .ops = &(struct clk_ops) { + .set_parent = s3c2443_setparent_hsmmc, + }, +}; + +/* standard clock definitions */ + +static struct clk init_clocks_off[] = { + { + .name = "sdi", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_SDI, + }, { + .name = "spi", + .devname = "s3c2410-spi.0", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_SPI0, + }, { + .name = "spi", + .devname = "s3c2410-spi.1", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_SPI1, + } +}; + +/* clocks to add straight away */ + +static struct clksrc_clk *clksrcs[] __initdata = { + &clk_hsspi, + &clk_hsmmc_div, +}; + +static struct clk *clks[] __initdata = { + &clk_hsmmc, +}; + +void __init s3c2443_init_clocks(int xtal) +{ + unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); + int ptr; + + clk_epll.rate = s3c2443_get_epll(epllcon, xtal); + clk_epll.parent = &clk_epllref.clk; + + s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, + armdiv, ARRAY_SIZE(armdiv), + S3C2443_CLKDIV0_ARMDIV_MASK); + + s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); + + for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) + s3c_register_clksrc(clksrcs[ptr], 1); + + /* We must be careful disabling the clocks we are not intending to + * be using at boot time, as subsystems such as the LCD which do + * their own DMA requests to the bus can cause the system to lockup + * if they where in the middle of requesting bus access. + * + * Disabling the LCD clock if the LCD is active is very dangerous, + * and therefore the bootloader should be careful to not enable + * the LCD clock if it is not needed. + */ + + /* install (and disable) the clocks we do not need immediately */ + + s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + + s3c_pwmclk_init(); +} diff --git a/arch/arm/mach-s3c24xx/clock-s3c244x.c b/arch/arm/mach-s3c24xx/clock-s3c244x.c new file mode 100644 index 00000000..6d9b688c --- /dev/null +++ b/arch/arm/mach-s3c24xx/clock-s3c244x.c @@ -0,0 +1,141 @@ +/* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c + * + * Copyright (c) 2004-2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C2440/S3C2442 Common clock support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent) +{ + unsigned long camdivn; + unsigned long dvs; + + if (parent == &clk_f) + dvs = 0; + else if (parent == &clk_h) + dvs = S3C2440_CAMDIVN_DVSEN; + else + return -EINVAL; + + clk->parent = parent; + + camdivn = __raw_readl(S3C2440_CAMDIVN); + camdivn &= ~S3C2440_CAMDIVN_DVSEN; + camdivn |= dvs; + __raw_writel(camdivn, S3C2440_CAMDIVN); + + return 0; +} + +static struct clk clk_arm = { + .name = "armclk", + .id = -1, + .ops = &(struct clk_ops) { + .set_parent = s3c2440_setparent_armclk, + }, +}; + +static int s3c244x_clk_add(struct device *dev, struct subsys_interface *sif) +{ + unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN); + unsigned long clkdivn; + struct clk *clock_upll; + int ret; + + printk("S3C244X: Clock Support, DVS %s\n", + (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off"); + + clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f; + + ret = s3c24xx_register_clock(&clk_arm); + if (ret < 0) { + printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret); + return ret; + } + + clock_upll = clk_get(NULL, "upll"); + if (IS_ERR(clock_upll)) { + printk(KERN_ERR "S3C244X: Failed to get upll clock\n"); + return -ENOENT; + } + + /* check rate of UPLL, and if it is near 96MHz, then change + * to using half the UPLL rate for the system */ + + if (clk_get_rate(clock_upll) > (94 * MHZ)) { + clk_usb_bus.rate = clk_get_rate(clock_upll) / 2; + + spin_lock(&clocks_lock); + + clkdivn = __raw_readl(S3C2410_CLKDIVN); + clkdivn |= S3C2440_CLKDIVN_UCLK; + __raw_writel(clkdivn, S3C2410_CLKDIVN); + + spin_unlock(&clocks_lock); + } + + return 0; +} + +static struct subsys_interface s3c2440_clk_interface = { + .name = "s3c2440_clk", + .subsys = &s3c2440_subsys, + .add_dev = s3c244x_clk_add, +}; + +static int s3c2440_clk_init(void) +{ + return subsys_interface_register(&s3c2440_clk_interface); +} + +arch_initcall(s3c2440_clk_init); + +static struct subsys_interface s3c2442_clk_interface = { + .name = "s3c2442_clk", + .subsys = &s3c2442_subsys, + .add_dev = s3c244x_clk_add, +}; + +static int s3c2442_clk_init(void) +{ + return subsys_interface_register(&s3c2442_clk_interface); +} + +arch_initcall(s3c2442_clk_init); diff --git a/arch/arm/mach-s3c24xx/common-s3c2443.c b/arch/arm/mach-s3c24xx/common-s3c2443.c new file mode 100644 index 00000000..46043158 --- /dev/null +++ b/arch/arm/mach-s3c24xx/common-s3c2443.c @@ -0,0 +1,670 @@ +/* + * Common code for SoCs starting with the S3C2443 + * + * Copyright (c) 2007, 2010 Simtec Electronics + * Ben Dooks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include + +#include +#include +#include + +#include + + +static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable) +{ + u32 ctrlbit = clk->ctrlbit; + u32 con = __raw_readl(reg); + + if (enable) + con |= ctrlbit; + else + con &= ~ctrlbit; + + __raw_writel(con, reg); + return 0; +} + +int s3c2443_clkcon_enable_h(struct clk *clk, int enable) +{ + return s3c2443_gate(S3C2443_HCLKCON, clk, enable); +} + +int s3c2443_clkcon_enable_p(struct clk *clk, int enable) +{ + return s3c2443_gate(S3C2443_PCLKCON, clk, enable); +} + +int s3c2443_clkcon_enable_s(struct clk *clk, int enable) +{ + return s3c2443_gate(S3C2443_SCLKCON, clk, enable); +} + +/* mpllref is a direct descendant of clk_xtal by default, but it is not + * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as + * such directly equating the two source clocks is impossible. + */ +static struct clk clk_mpllref = { + .name = "mpllref", + .parent = &clk_xtal, +}; + +static struct clk *clk_epllref_sources[] = { + [0] = &clk_mpllref, + [1] = &clk_mpllref, + [2] = &clk_xtal, + [3] = &clk_ext, +}; + +struct clksrc_clk clk_epllref = { + .clk = { + .name = "epllref", + }, + .sources = &(struct clksrc_sources) { + .sources = clk_epllref_sources, + .nr_sources = ARRAY_SIZE(clk_epllref_sources), + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 }, +}; + +/* esysclk + * + * this is sourced from either the EPLL or the EPLLref clock +*/ + +static struct clk *clk_sysclk_sources[] = { + [0] = &clk_epllref.clk, + [1] = &clk_epll, +}; + +struct clksrc_clk clk_esysclk = { + .clk = { + .name = "esysclk", + .parent = &clk_epll, + }, + .sources = &(struct clksrc_sources) { + .sources = clk_sysclk_sources, + .nr_sources = ARRAY_SIZE(clk_sysclk_sources), + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 }, +}; + +static unsigned long s3c2443_getrate_mdivclk(struct clk *clk) +{ + unsigned long parent_rate = clk_get_rate(clk->parent); + unsigned long div = __raw_readl(S3C2443_CLKDIV0); + + div &= S3C2443_CLKDIV0_EXTDIV_MASK; + div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */ + + return parent_rate / (div + 1); +} + +static struct clk clk_mdivclk = { + .name = "mdivclk", + .parent = &clk_mpllref, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_getrate_mdivclk, + }, +}; + +static struct clk *clk_msysclk_sources[] = { + [0] = &clk_mpllref, + [1] = &clk_mpll, + [2] = &clk_mdivclk, + [3] = &clk_mpllref, +}; + +struct clksrc_clk clk_msysclk = { + .clk = { + .name = "msysclk", + .parent = &clk_xtal, + }, + .sources = &(struct clksrc_sources) { + .sources = clk_msysclk_sources, + .nr_sources = ARRAY_SIZE(clk_msysclk_sources), + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 }, +}; + +/* prediv + * + * this divides the msysclk down to pass to h/p/etc. + */ + +static unsigned long s3c2443_prediv_getrate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); + + clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK; + clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT; + + return rate / (clkdiv0 + 1); +} + +static struct clk clk_prediv = { + .name = "prediv", + .parent = &clk_msysclk.clk, + .ops = &(struct clk_ops) { + .get_rate = s3c2443_prediv_getrate, + }, +}; + +/* hclk divider + * + * divides the prediv and provides the hclk. + */ + +static unsigned long s3c2443_hclkdiv_getrate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); + + clkdiv0 &= S3C2443_CLKDIV0_HCLKDIV_MASK; + + return rate / (clkdiv0 + 1); +} + +static struct clk_ops clk_h_ops = { + .get_rate = s3c2443_hclkdiv_getrate, +}; + +/* pclk divider + * + * divides the hclk and provides the pclk. + */ + +static unsigned long s3c2443_pclkdiv_getrate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0); + + clkdiv0 = ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 1 : 0); + + return rate / (clkdiv0 + 1); +} + +static struct clk_ops clk_p_ops = { + .get_rate = s3c2443_pclkdiv_getrate, +}; + +/* armdiv + * + * this clock is sourced from msysclk and can have a number of + * divider values applied to it to then be fed into armclk. +*/ + +static unsigned int *armdiv; +static int nr_armdiv; +static int armdivmask; + +static unsigned long s3c2443_armclk_roundrate(struct clk *clk, + unsigned long rate) +{ + unsigned long parent = clk_get_rate(clk->parent); + unsigned long calc; + unsigned best = 256; /* bigger than any value */ + unsigned div; + int ptr; + + if (!nr_armdiv) + return -EINVAL; + + for (ptr = 0; ptr < nr_armdiv; ptr++) { + div = armdiv[ptr]; + if (div) { + /* cpufreq provides 266mhz as 266666000 not 266666666 */ + calc = (parent / div / 1000) * 1000; + if (calc <= rate && div < best) + best = div; + } + } + + return parent / best; +} + +static unsigned long s3c2443_armclk_getrate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + unsigned long clkcon0; + int val; + + if (!nr_armdiv || !armdivmask) + return -EINVAL; + + clkcon0 = __raw_readl(S3C2443_CLKDIV0); + clkcon0 &= armdivmask; + val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT; + + return rate / armdiv[val]; +} + +static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate) +{ + unsigned long parent = clk_get_rate(clk->parent); + unsigned long calc; + unsigned div; + unsigned best = 256; /* bigger than any value */ + int ptr; + int val = -1; + + if (!nr_armdiv || !armdivmask) + return -EINVAL; + + for (ptr = 0; ptr < nr_armdiv; ptr++) { + div = armdiv[ptr]; + if (div) { + /* cpufreq provides 266mhz as 266666000 not 266666666 */ + calc = (parent / div / 1000) * 1000; + if (calc <= rate && div < best) { + best = div; + val = ptr; + } + } + } + + if (val >= 0) { + unsigned long clkcon0; + + clkcon0 = __raw_readl(S3C2443_CLKDIV0); + clkcon0 &= ~armdivmask; + clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT; + __raw_writel(clkcon0, S3C2443_CLKDIV0); + } + + return (val == -1) ? -EINVAL : 0; +} + +static struct clk clk_armdiv = { + .name = "armdiv", + .parent = &clk_msysclk.clk, + .ops = &(struct clk_ops) { + .round_rate = s3c2443_armclk_roundrate, + .get_rate = s3c2443_armclk_getrate, + .set_rate = s3c2443_armclk_setrate, + }, +}; + +/* armclk + * + * this is the clock fed into the ARM core itself, from armdiv or from hclk. + */ + +static struct clk *clk_arm_sources[] = { + [0] = &clk_armdiv, + [1] = &clk_h, +}; + +static struct clksrc_clk clk_arm = { + .clk = { + .name = "armclk", + }, + .sources = &(struct clksrc_sources) { + .sources = clk_arm_sources, + .nr_sources = ARRAY_SIZE(clk_arm_sources), + }, + .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 }, +}; + +/* usbhost + * + * usb host bus-clock, usually 48MHz to provide USB bus clock timing +*/ + +static struct clksrc_clk clk_usb_bus_host = { + .clk = { + .name = "usb-bus-host-parent", + .parent = &clk_esysclk.clk, + .ctrlbit = S3C2443_SCLKCON_USBHOST, + .enable = s3c2443_clkcon_enable_s, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 }, +}; + +/* common clksrc clocks */ + +static struct clksrc_clk clksrc_clks[] = { + { + /* camera interface bus-clock, divided down from esysclk */ + .clk = { + .name = "camif-upll", /* same as 2440 name */ + .parent = &clk_esysclk.clk, + .ctrlbit = S3C2443_SCLKCON_CAMCLK, + .enable = s3c2443_clkcon_enable_s, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 }, + }, { + .clk = { + .name = "display-if", + .parent = &clk_esysclk.clk, + .ctrlbit = S3C2443_SCLKCON_DISPCLK, + .enable = s3c2443_clkcon_enable_s, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 }, + }, +}; + +static struct clksrc_clk clk_esys_uart = { + /* ART baud-rate clock sourced from esysclk via a divisor */ + .clk = { + .name = "uartclk", + .parent = &clk_esysclk.clk, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 }, +}; + +static struct clk clk_i2s_ext = { + .name = "i2s-ext", +}; + +/* i2s_eplldiv + * + * This clock is the output from the I2S divisor of ESYSCLK, and is separate + * from the mux that comes after it (cannot merge into one single clock) +*/ + +static struct clksrc_clk clk_i2s_eplldiv = { + .clk = { + .name = "i2s-eplldiv", + .parent = &clk_esysclk.clk, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, }, +}; + +/* i2s-ref + * + * i2s bus reference clock, selectable from external, esysclk or epllref + * + * Note, this used to be two clocks, but was compressed into one. +*/ + +static struct clk *clk_i2s_srclist[] = { + [0] = &clk_i2s_eplldiv.clk, + [1] = &clk_i2s_ext, + [2] = &clk_epllref.clk, + [3] = &clk_epllref.clk, +}; + +static struct clksrc_clk clk_i2s = { + .clk = { + .name = "i2s-if", + .ctrlbit = S3C2443_SCLKCON_I2SCLK, + .enable = s3c2443_clkcon_enable_s, + + }, + .sources = &(struct clksrc_sources) { + .sources = clk_i2s_srclist, + .nr_sources = ARRAY_SIZE(clk_i2s_srclist), + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 }, +}; + +static struct clk init_clocks_off[] = { + { + .name = "iis", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_IIS, + }, { + .name = "hsspi", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_HSSPI, + }, { + .name = "adc", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_ADC, + }, { + .name = "i2c", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_IIC, + } +}; + +static struct clk init_clocks[] = { + { + .name = "dma", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_DMA0, + }, { + .name = "dma", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_DMA1, + }, { + .name = "dma", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_DMA2, + }, { + .name = "dma", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_DMA3, + }, { + .name = "dma", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_DMA4, + }, { + .name = "dma", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_DMA5, + }, { + .name = "gpio", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_GPIO, + }, { + .name = "usb-host", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_USBH, + }, { + .name = "usb-device", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_USBD, + }, { + .name = "lcd", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_LCDC, + + }, { + .name = "timers", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_PWMT, + }, { + .name = "cfc", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_CFC, + }, { + .name = "ssmc", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_SSMC, + }, { + .name = "uart", + .devname = "s3c2440-uart.0", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_UART0, + }, { + .name = "uart", + .devname = "s3c2440-uart.1", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_UART1, + }, { + .name = "uart", + .devname = "s3c2440-uart.2", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_UART2, + }, { + .name = "uart", + .devname = "s3c2440-uart.3", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_UART3, + }, { + .name = "rtc", + .parent = &clk_p, + .enable = s3c2443_clkcon_enable_p, + .ctrlbit = S3C2443_PCLKCON_RTC, + }, { + .name = "watchdog", + .parent = &clk_p, + .ctrlbit = S3C2443_PCLKCON_WDT, + }, { + .name = "ac97", + .parent = &clk_p, + .ctrlbit = S3C2443_PCLKCON_AC97, + }, { + .name = "nand", + .parent = &clk_h, + }, { + .name = "usb-bus-host", + .parent = &clk_usb_bus_host.clk, + } +}; + +static struct clk hsmmc1_clk = { + .name = "hsmmc", + .devname = "s3c-sdhci.1", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_HSMMC, +}; + +/* EPLLCON compatible enough to get on/off information */ + +void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll) +{ + unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); + unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON); + struct clk *xtal_clk; + unsigned long xtal; + unsigned long pll; + int ptr; + + xtal_clk = clk_get(NULL, "xtal"); + xtal = clk_get_rate(xtal_clk); + clk_put(xtal_clk); + + pll = get_mpll(mpllcon, xtal); + clk_msysclk.clk.rate = pll; + clk_mpll.rate = pll; + + printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n", + (mpllcon & S3C2443_PLLCON_OFF) ? "off" : "on", + print_mhz(pll), print_mhz(clk_get_rate(&clk_armdiv)), + print_mhz(clk_get_rate(&clk_h)), + print_mhz(clk_get_rate(&clk_p))); + + for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++) + s3c_set_clksrc(&clksrc_clks[ptr], true); + + /* ensure usb bus clock is within correct rate of 48MHz */ + + if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) { + printk(KERN_INFO "Warning: USB host bus not at 48MHz\n"); + clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000); + } + + printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n", + (epllcon & S3C2443_PLLCON_OFF) ? "off" : "on", + print_mhz(clk_get_rate(&clk_epll)), + print_mhz(clk_get_rate(&clk_usb_bus))); +} + +static struct clk *clks[] __initdata = { + &clk_prediv, + &clk_mpllref, + &clk_mdivclk, + &clk_ext, + &clk_epll, + &clk_usb_bus, + &clk_armdiv, + &hsmmc1_clk, +}; + +static struct clksrc_clk *clksrcs[] __initdata = { + &clk_i2s_eplldiv, + &clk_i2s, + &clk_usb_bus_host, + &clk_epllref, + &clk_esysclk, + &clk_msysclk, + &clk_arm, +}; + +static struct clk_lookup s3c2443_clk_lookup[] = { + CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk), + CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), + CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk), +}; + +void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, + unsigned int *divs, int nr_divs, + int divmask) +{ + int ptr; + + armdiv = divs; + nr_armdiv = nr_divs; + armdivmask = divmask; + + /* s3c2443 parents h clock from prediv */ + clk_h.parent = &clk_prediv; + clk_h.ops = &clk_h_ops; + + /* and p clock from h clock */ + clk_p.parent = &clk_h; + clk_p.ops = &clk_p_ops; + + clk_usb_bus.parent = &clk_usb_bus_host.clk; + clk_epll.parent = &clk_epllref.clk; + + s3c24xx_register_baseclocks(xtal); + s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); + + for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) + s3c_register_clksrc(clksrcs[ptr], 1); + + s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks)); + s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); + + /* See s3c2443/etc notes on disabling clocks at init time */ + s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup)); + + s3c2443_common_setup_clocks(get_mpll); +} diff --git a/arch/arm/mach-s3c24xx/common-smdk.c b/arch/arm/mach-s3c24xx/common-smdk.c new file mode 100644 index 00000000..084604be --- /dev/null +++ b/arch/arm/mach-s3c24xx/common-smdk.c @@ -0,0 +1,207 @@ +/* linux/arch/arm/plat-s3c24xx/common-smdk.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * Common code for SMDK2410 and SMDK2440 boards + * + * http://www.fluff.org/ben/smdk2440/ + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +/* LED devices */ + +static struct s3c24xx_led_platdata smdk_pdata_led4 = { + .gpio = S3C2410_GPF(4), + .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, + .name = "led4", + .def_trigger = "timer", +}; + +static struct s3c24xx_led_platdata smdk_pdata_led5 = { + .gpio = S3C2410_GPF(5), + .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, + .name = "led5", + .def_trigger = "nand-disk", +}; + +static struct s3c24xx_led_platdata smdk_pdata_led6 = { + .gpio = S3C2410_GPF(6), + .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, + .name = "led6", +}; + +static struct s3c24xx_led_platdata smdk_pdata_led7 = { + .gpio = S3C2410_GPF(7), + .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE, + .name = "led7", +}; + +static struct platform_device smdk_led4 = { + .name = "s3c24xx_led", + .id = 0, + .dev = { + .platform_data = &smdk_pdata_led4, + }, +}; + +static struct platform_device smdk_led5 = { + .name = "s3c24xx_led", + .id = 1, + .dev = { + .platform_data = &smdk_pdata_led5, + }, +}; + +static struct platform_device smdk_led6 = { + .name = "s3c24xx_led", + .id = 2, + .dev = { + .platform_data = &smdk_pdata_led6, + }, +}; + +static struct platform_device smdk_led7 = { + .name = "s3c24xx_led", + .id = 3, + .dev = { + .platform_data = &smdk_pdata_led7, + }, +}; + +/* NAND parititon from 2.4.18-swl5 */ + +static struct mtd_partition smdk_default_nand_part[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_16K, + .offset = 0, + }, + [1] = { + .name = "S3C2410 flash partition 1", + .offset = 0, + .size = SZ_2M, + }, + [2] = { + .name = "S3C2410 flash partition 2", + .offset = SZ_4M, + .size = SZ_4M, + }, + [3] = { + .name = "S3C2410 flash partition 3", + .offset = SZ_8M, + .size = SZ_2M, + }, + [4] = { + .name = "S3C2410 flash partition 4", + .offset = SZ_1M * 10, + .size = SZ_4M, + }, + [5] = { + .name = "S3C2410 flash partition 5", + .offset = SZ_1M * 14, + .size = SZ_1M * 10, + }, + [6] = { + .name = "S3C2410 flash partition 6", + .offset = SZ_1M * 24, + .size = SZ_1M * 24, + }, + [7] = { + .name = "S3C2410 flash partition 7", + .offset = SZ_1M * 48, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct s3c2410_nand_set smdk_nand_sets[] = { + [0] = { + .name = "NAND", + .nr_chips = 1, + .nr_partitions = ARRAY_SIZE(smdk_default_nand_part), + .partitions = smdk_default_nand_part, + }, +}; + +/* choose a set of timings which should suit most 512Mbit + * chips and beyond. +*/ + +static struct s3c2410_platform_nand smdk_nand_info = { + .tacls = 20, + .twrph0 = 60, + .twrph1 = 20, + .nr_sets = ARRAY_SIZE(smdk_nand_sets), + .sets = smdk_nand_sets, +}; + +/* devices we initialise */ + +static struct platform_device __initdata *smdk_devs[] = { + &s3c_device_nand, + &smdk_led4, + &smdk_led5, + &smdk_led6, + &smdk_led7, +}; + +void __init smdk_machine_init(void) +{ + /* Configure the LEDs (even if we have no LED support)*/ + + s3c_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT); + s3c_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT); + + s3c2410_gpio_setpin(S3C2410_GPF(4), 1); + s3c2410_gpio_setpin(S3C2410_GPF(5), 1); + s3c2410_gpio_setpin(S3C2410_GPF(6), 1); + s3c2410_gpio_setpin(S3C2410_GPF(7), 1); + + if (machine_is_smdk2443()) + smdk_nand_info.twrph0 = 50; + + s3c_nand_set_platdata(&smdk_nand_info); + + platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs)); + + s3c_pm_init(); +} diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h new file mode 100644 index 00000000..c2f596e7 --- /dev/null +++ b/arch/arm/mach-s3c24xx/common.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Common Header for S3C24XX SoCs + * + * 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 __ARCH_ARM_MACH_S3C24XX_COMMON_H +#define __ARCH_ARM_MACH_S3C24XX_COMMON_H __FILE__ + +void s3c2410_restart(char mode, const char *cmd); +void s3c244x_restart(char mode, const char *cmd); + +#endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */ diff --git a/arch/arm/mach-s3c24xx/dma-s3c2410.c b/arch/arm/mach-s3c24xx/dma-s3c2410.c new file mode 100644 index 00000000..4803338c --- /dev/null +++ b/arch/arm/mach-s3c24xx/dma-s3c2410.c @@ -0,0 +1,186 @@ +/* linux/arch/arm/mach-s3c2410/dma.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * S3C2410 DMA selection + * + * 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 +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = { + [DMACH_XD0] = { + .name = "xdreq0", + .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID, + }, + [DMACH_XD1] = { + .name = "xdreq1", + .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID, + }, + [DMACH_SDI] = { + .name = "sdi", + .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID, + .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID, + }, + [DMACH_SPI0] = { + .name = "spi0", + .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID, + }, + [DMACH_SPI1] = { + .name = "spi1", + .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID, + }, + [DMACH_UART0] = { + .name = "uart0", + .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID, + }, + [DMACH_UART1] = { + .name = "uart1", + .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID, + }, + [DMACH_UART2] = { + .name = "uart2", + .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID, + }, + [DMACH_TIMER] = { + .name = "timer", + .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID, + .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID, + }, + [DMACH_I2S_IN] = { + .name = "i2s-sdi", + .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID, + }, + [DMACH_I2S_OUT] = { + .name = "i2s-sdo", + .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID, + }, + [DMACH_USB_EP1] = { + .name = "usb-ep1", + .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID, + }, + [DMACH_USB_EP2] = { + .name = "usb-ep2", + .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID, + }, + [DMACH_USB_EP3] = { + .name = "usb-ep3", + .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID, + }, + [DMACH_USB_EP4] = { + .name = "usb-ep4", + .channels[3] =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID, + }, +}; + +static void s3c2410_dma_select(struct s3c2410_dma_chan *chan, + struct s3c24xx_dma_map *map) +{ + chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID; +} + +static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = { + .select = s3c2410_dma_select, + .dcon_mask = 7 << 24, + .map = s3c2410_dma_mappings, + .map_size = ARRAY_SIZE(s3c2410_dma_mappings), +}; + +static struct s3c24xx_dma_order __initdata s3c2410_dma_order = { + .channels = { + [DMACH_SDI] = { + .list = { + [0] = 3 | DMA_CH_VALID, + [1] = 2 | DMA_CH_VALID, + [2] = 0 | DMA_CH_VALID, + }, + }, + [DMACH_I2S_IN] = { + .list = { + [0] = 1 | DMA_CH_VALID, + [1] = 2 | DMA_CH_VALID, + }, + }, + }, +}; + +static int __init s3c2410_dma_add(struct device *dev, + struct subsys_interface *sif) +{ + s3c2410_dma_init(); + s3c24xx_dma_order_set(&s3c2410_dma_order); + return s3c24xx_dma_init_map(&s3c2410_dma_sel); +} + +#if defined(CONFIG_CPU_S3C2410) +static struct subsys_interface s3c2410_dma_interface = { + .name = "s3c2410_dma", + .subsys = &s3c2410_subsys, + .add_dev = s3c2410_dma_add, +}; + +static int __init s3c2410_dma_drvinit(void) +{ + return subsys_interface_register(&s3c2410_dma_interface); +} + +arch_initcall(s3c2410_dma_drvinit); + +static struct subsys_interface s3c2410a_dma_interface = { + .name = "s3c2410a_dma", + .subsys = &s3c2410a_subsys, + .add_dev = s3c2410_dma_add, +}; + +static int __init s3c2410a_dma_drvinit(void) +{ + return subsys_interface_register(&s3c2410a_dma_interface); +} + +arch_initcall(s3c2410a_dma_drvinit); +#endif + +#if defined(CONFIG_CPU_S3C2442) +/* S3C2442 DMA contains the same selection table as the S3C2410 */ +static struct subsys_interface s3c2442_dma_interface = { + .name = "s3c2442_dma", + .subsys = &s3c2442_subsys, + .add_dev = s3c2410_dma_add, +}; + +static int __init s3c2442_dma_drvinit(void) +{ + return subsys_interface_register(&s3c2442_dma_interface); +} + +arch_initcall(s3c2442_dma_drvinit); +#endif + diff --git a/arch/arm/mach-s3c24xx/dma-s3c2412.c b/arch/arm/mach-s3c24xx/dma-s3c2412.c new file mode 100644 index 00000000..38472ac9 --- /dev/null +++ b/arch/arm/mach-s3c24xx/dma-s3c2412.c @@ -0,0 +1,180 @@ +/* linux/arch/arm/mach-s3c2412/dma.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * S3C2412 DMA selection + * + * 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 +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID } + +static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = { + [DMACH_XD0] = { + .name = "xdreq0", + .channels = MAP(S3C2412_DMAREQSEL_XDREQ0), + .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ0), + }, + [DMACH_XD1] = { + .name = "xdreq1", + .channels = MAP(S3C2412_DMAREQSEL_XDREQ1), + .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ1), + }, + [DMACH_SDI] = { + .name = "sdi", + .channels = MAP(S3C2412_DMAREQSEL_SDI), + .channels_rx = MAP(S3C2412_DMAREQSEL_SDI), + }, + [DMACH_SPI0] = { + .name = "spi0", + .channels = MAP(S3C2412_DMAREQSEL_SPI0TX), + .channels_rx = MAP(S3C2412_DMAREQSEL_SPI0RX), + }, + [DMACH_SPI1] = { + .name = "spi1", + .channels = MAP(S3C2412_DMAREQSEL_SPI1TX), + .channels_rx = MAP(S3C2412_DMAREQSEL_SPI1RX), + }, + [DMACH_UART0] = { + .name = "uart0", + .channels = MAP(S3C2412_DMAREQSEL_UART0_0), + .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_0), + }, + [DMACH_UART1] = { + .name = "uart1", + .channels = MAP(S3C2412_DMAREQSEL_UART1_0), + .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_0), + }, + [DMACH_UART2] = { + .name = "uart2", + .channels = MAP(S3C2412_DMAREQSEL_UART2_0), + .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_0), + }, + [DMACH_UART0_SRC2] = { + .name = "uart0", + .channels = MAP(S3C2412_DMAREQSEL_UART0_1), + .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_1), + }, + [DMACH_UART1_SRC2] = { + .name = "uart1", + .channels = MAP(S3C2412_DMAREQSEL_UART1_1), + .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_1), + }, + [DMACH_UART2_SRC2] = { + .name = "uart2", + .channels = MAP(S3C2412_DMAREQSEL_UART2_1), + .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_1), + }, + [DMACH_TIMER] = { + .name = "timer", + .channels = MAP(S3C2412_DMAREQSEL_TIMER), + .channels_rx = MAP(S3C2412_DMAREQSEL_TIMER), + }, + [DMACH_I2S_IN] = { + .name = "i2s-sdi", + .channels = MAP(S3C2412_DMAREQSEL_I2SRX), + .channels_rx = MAP(S3C2412_DMAREQSEL_I2SRX), + }, + [DMACH_I2S_OUT] = { + .name = "i2s-sdo", + .channels = MAP(S3C2412_DMAREQSEL_I2STX), + .channels_rx = MAP(S3C2412_DMAREQSEL_I2STX), + }, + [DMACH_USB_EP1] = { + .name = "usb-ep1", + .channels = MAP(S3C2412_DMAREQSEL_USBEP1), + .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP1), + }, + [DMACH_USB_EP2] = { + .name = "usb-ep2", + .channels = MAP(S3C2412_DMAREQSEL_USBEP2), + .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP2), + }, + [DMACH_USB_EP3] = { + .name = "usb-ep3", + .channels = MAP(S3C2412_DMAREQSEL_USBEP3), + .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP3), + }, + [DMACH_USB_EP4] = { + .name = "usb-ep4", + .channels = MAP(S3C2412_DMAREQSEL_USBEP4), + .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP4), + }, +}; + +static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan, + struct s3c24xx_dma_map *map, + enum dma_data_direction dir) +{ + unsigned long chsel; + + if (dir == DMA_FROM_DEVICE) + chsel = map->channels_rx[0]; + else + chsel = map->channels[0]; + + chsel &= ~DMA_CH_VALID; + chsel |= S3C2412_DMAREQSEL_HW; + + writel(chsel, chan->regs + S3C2412_DMA_DMAREQSEL); +} + +static void s3c2412_dma_select(struct s3c2410_dma_chan *chan, + struct s3c24xx_dma_map *map) +{ + s3c2412_dma_direction(chan, map, chan->source); +} + +static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = { + .select = s3c2412_dma_select, + .direction = s3c2412_dma_direction, + .dcon_mask = 0, + .map = s3c2412_dma_mappings, + .map_size = ARRAY_SIZE(s3c2412_dma_mappings), +}; + +static int __init s3c2412_dma_add(struct device *dev, + struct subsys_interface *sif) +{ + s3c2410_dma_init(); + return s3c24xx_dma_init_map(&s3c2412_dma_sel); +} + +static struct subsys_interface s3c2412_dma_interface = { + .name = "s3c2412_dma", + .subsys = &s3c2412_subsys, + .add_dev = s3c2412_dma_add, +}; + +static int __init s3c2412_dma_init(void) +{ + return subsys_interface_register(&s3c2412_dma_interface); +} + +arch_initcall(s3c2412_dma_init); diff --git a/arch/arm/mach-s3c24xx/dma-s3c2440.c b/arch/arm/mach-s3c24xx/dma-s3c2440.c new file mode 100644 index 00000000..5f0a0c8e --- /dev/null +++ b/arch/arm/mach-s3c24xx/dma-s3c2440.c @@ -0,0 +1,197 @@ +/* linux/arch/arm/mach-s3c2440/dma.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * S3C2440 DMA selection + * + * 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 +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = { + [DMACH_XD0] = { + .name = "xdreq0", + .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID, + }, + [DMACH_XD1] = { + .name = "xdreq1", + .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID, + }, + [DMACH_SDI] = { + .name = "sdi", + .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID, + .channels[1] = S3C2440_DCON_CH1_SDI | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID, + .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID, + }, + [DMACH_SPI0] = { + .name = "spi0", + .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID, + }, + [DMACH_SPI1] = { + .name = "spi1", + .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID, + }, + [DMACH_UART0] = { + .name = "uart0", + .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID, + }, + [DMACH_UART1] = { + .name = "uart1", + .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID, + }, + [DMACH_UART2] = { + .name = "uart2", + .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID, + }, + [DMACH_TIMER] = { + .name = "timer", + .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID, + .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID, + }, + [DMACH_I2S_IN] = { + .name = "i2s-sdi", + .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID, + }, + [DMACH_I2S_OUT] = { + .name = "i2s-sdo", + .channels[0] = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID, + }, + [DMACH_PCM_IN] = { + .name = "pcm-in", + .channels[0] = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID, + .channels[2] = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID, + }, + [DMACH_PCM_OUT] = { + .name = "pcm-out", + .channels[1] = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID, + .channels[3] = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID, + }, + [DMACH_MIC_IN] = { + .name = "mic-in", + .channels[2] = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID, + .channels[3] = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID, + }, + [DMACH_USB_EP1] = { + .name = "usb-ep1", + .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID, + }, + [DMACH_USB_EP2] = { + .name = "usb-ep2", + .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID, + }, + [DMACH_USB_EP3] = { + .name = "usb-ep3", + .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID, + }, + [DMACH_USB_EP4] = { + .name = "usb-ep4", + .channels[3] = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID, + }, +}; + +static void s3c2440_dma_select(struct s3c2410_dma_chan *chan, + struct s3c24xx_dma_map *map) +{ + chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID; +} + +static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = { + .select = s3c2440_dma_select, + .dcon_mask = 7 << 24, + .map = s3c2440_dma_mappings, + .map_size = ARRAY_SIZE(s3c2440_dma_mappings), +}; + +static struct s3c24xx_dma_order __initdata s3c2440_dma_order = { + .channels = { + [DMACH_SDI] = { + .list = { + [0] = 3 | DMA_CH_VALID, + [1] = 2 | DMA_CH_VALID, + [2] = 1 | DMA_CH_VALID, + [3] = 0 | DMA_CH_VALID, + }, + }, + [DMACH_I2S_IN] = { + .list = { + [0] = 1 | DMA_CH_VALID, + [1] = 2 | DMA_CH_VALID, + }, + }, + [DMACH_I2S_OUT] = { + .list = { + [0] = 2 | DMA_CH_VALID, + [1] = 1 | DMA_CH_VALID, + }, + }, + [DMACH_PCM_IN] = { + .list = { + [0] = 2 | DMA_CH_VALID, + [1] = 1 | DMA_CH_VALID, + }, + }, + [DMACH_PCM_OUT] = { + .list = { + [0] = 1 | DMA_CH_VALID, + [1] = 3 | DMA_CH_VALID, + }, + }, + [DMACH_MIC_IN] = { + .list = { + [0] = 3 | DMA_CH_VALID, + [1] = 2 | DMA_CH_VALID, + }, + }, + }, +}; + +static int __init s3c2440_dma_add(struct device *dev, + struct subsys_interface *sif) +{ + s3c2410_dma_init(); + s3c24xx_dma_order_set(&s3c2440_dma_order); + return s3c24xx_dma_init_map(&s3c2440_dma_sel); +} + +static struct subsys_interface s3c2440_dma_interface = { + .name = "s3c2440_dma", + .subsys = &s3c2440_subsys, + .add_dev = s3c2440_dma_add, +}; + +static int __init s3c2440_dma_init(void) +{ + return subsys_interface_register(&s3c2440_dma_interface); +} + +arch_initcall(s3c2440_dma_init); + diff --git a/arch/arm/mach-s3c24xx/dma-s3c2443.c b/arch/arm/mach-s3c24xx/dma-s3c2443.c new file mode 100644 index 00000000..e227c472 --- /dev/null +++ b/arch/arm/mach-s3c24xx/dma-s3c2443.c @@ -0,0 +1,174 @@ +/* linux/arch/arm/mach-s3c2443/dma.c + * + * Copyright (c) 2007 Simtec Electronics + * Ben Dooks + * + * S3C2443 DMA selection + * + * 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 +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAP(x) { \ + [0] = (x) | DMA_CH_VALID, \ + [1] = (x) | DMA_CH_VALID, \ + [2] = (x) | DMA_CH_VALID, \ + [3] = (x) | DMA_CH_VALID, \ + [4] = (x) | DMA_CH_VALID, \ + [5] = (x) | DMA_CH_VALID, \ + } + +static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = { + [DMACH_XD0] = { + .name = "xdreq0", + .channels = MAP(S3C2443_DMAREQSEL_XDREQ0), + }, + [DMACH_XD1] = { + .name = "xdreq1", + .channels = MAP(S3C2443_DMAREQSEL_XDREQ1), + }, + [DMACH_SDI] = { /* only on S3C2443 */ + .name = "sdi", + .channels = MAP(S3C2443_DMAREQSEL_SDI), + }, + [DMACH_SPI0] = { + .name = "spi0", + .channels = MAP(S3C2443_DMAREQSEL_SPI0TX), + }, + [DMACH_SPI1] = { /* only on S3C2443/S3C2450 */ + .name = "spi1", + .channels = MAP(S3C2443_DMAREQSEL_SPI1TX), + }, + [DMACH_UART0] = { + .name = "uart0", + .channels = MAP(S3C2443_DMAREQSEL_UART0_0), + }, + [DMACH_UART1] = { + .name = "uart1", + .channels = MAP(S3C2443_DMAREQSEL_UART1_0), + }, + [DMACH_UART2] = { + .name = "uart2", + .channels = MAP(S3C2443_DMAREQSEL_UART2_0), + }, + [DMACH_UART3] = { + .name = "uart3", + .channels = MAP(S3C2443_DMAREQSEL_UART3_0), + }, + [DMACH_UART0_SRC2] = { + .name = "uart0", + .channels = MAP(S3C2443_DMAREQSEL_UART0_1), + }, + [DMACH_UART1_SRC2] = { + .name = "uart1", + .channels = MAP(S3C2443_DMAREQSEL_UART1_1), + }, + [DMACH_UART2_SRC2] = { + .name = "uart2", + .channels = MAP(S3C2443_DMAREQSEL_UART2_1), + }, + [DMACH_UART3_SRC2] = { + .name = "uart3", + .channels = MAP(S3C2443_DMAREQSEL_UART3_1), + }, + [DMACH_TIMER] = { + .name = "timer", + .channels = MAP(S3C2443_DMAREQSEL_TIMER), + }, + [DMACH_I2S_IN] = { + .name = "i2s-sdi", + .channels = MAP(S3C2443_DMAREQSEL_I2SRX), + }, + [DMACH_I2S_OUT] = { + .name = "i2s-sdo", + .channels = MAP(S3C2443_DMAREQSEL_I2STX), + }, + [DMACH_PCM_IN] = { + .name = "pcm-in", + .channels = MAP(S3C2443_DMAREQSEL_PCMIN), + }, + [DMACH_PCM_OUT] = { + .name = "pcm-out", + .channels = MAP(S3C2443_DMAREQSEL_PCMOUT), + }, + [DMACH_MIC_IN] = { + .name = "mic-in", + .channels = MAP(S3C2443_DMAREQSEL_MICIN), + }, +}; + +static void s3c2443_dma_select(struct s3c2410_dma_chan *chan, + struct s3c24xx_dma_map *map) +{ + writel(map->channels[0] | S3C2443_DMAREQSEL_HW, + chan->regs + S3C2443_DMA_DMAREQSEL); +} + +static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = { + .select = s3c2443_dma_select, + .dcon_mask = 0, + .map = s3c2443_dma_mappings, + .map_size = ARRAY_SIZE(s3c2443_dma_mappings), +}; + +static int __init s3c2443_dma_add(struct device *dev, + struct subsys_interface *sif) +{ + s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100); + return s3c24xx_dma_init_map(&s3c2443_dma_sel); +} + +#ifdef CONFIG_CPU_S3C2416 +/* S3C2416 DMA contains the same selection table as the S3C2443 */ +static struct subsys_interface s3c2416_dma_interface = { + .name = "s3c2416_dma", + .subsys = &s3c2416_subsys, + .add_dev = s3c2443_dma_add, +}; + +static int __init s3c2416_dma_init(void) +{ + return subsys_interface_register(&s3c2416_dma_interface); +} + +arch_initcall(s3c2416_dma_init); +#endif + +#ifdef CONFIG_CPU_S3C2443 +static struct subsys_interface s3c2443_dma_interface = { + .name = "s3c2443_dma", + .subsys = &s3c2443_subsys, + .add_dev = s3c2443_dma_add, +}; + +static int __init s3c2443_dma_init(void) +{ + return subsys_interface_register(&s3c2443_dma_interface); +} + +arch_initcall(s3c2443_dma_init); +#endif diff --git a/arch/arm/mach-s3c24xx/h1940-bluetooth.c b/arch/arm/mach-s3c24xx/h1940-bluetooth.c new file mode 100644 index 00000000..a5eeb62c --- /dev/null +++ b/arch/arm/mach-s3c24xx/h1940-bluetooth.c @@ -0,0 +1,157 @@ +/* + * arch/arm/mach-s3c2410/h1940-bluetooth.c + * Copyright (c) Arnaud Patard + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + * + * S3C2410 bluetooth "driver" + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define DRV_NAME "h1940-bt" + +/* Bluetooth control */ +static void h1940bt_enable(int on) +{ + if (on) { + /* Power on the chip */ + gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 1); + /* Reset the chip */ + mdelay(10); + + gpio_set_value(S3C2410_GPH(1), 1); + mdelay(10); + gpio_set_value(S3C2410_GPH(1), 0); + + h1940_led_blink_set(-EINVAL, GPIO_LED_BLINK, NULL, NULL); + } + else { + gpio_set_value(S3C2410_GPH(1), 1); + mdelay(10); + gpio_set_value(S3C2410_GPH(1), 0); + mdelay(10); + gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 0); + + h1940_led_blink_set(-EINVAL, GPIO_LED_NO_BLINK_LOW, NULL, NULL); + } +} + +static int h1940bt_set_block(void *data, bool blocked) +{ + h1940bt_enable(!blocked); + return 0; +} + +static const struct rfkill_ops h1940bt_rfkill_ops = { + .set_block = h1940bt_set_block, +}; + +static int __devinit h1940bt_probe(struct platform_device *pdev) +{ + struct rfkill *rfk; + int ret = 0; + + ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev)); + if (ret) { + dev_err(&pdev->dev, "could not get GPH1\n"); + return ret; + } + + ret = gpio_request(H1940_LATCH_BLUETOOTH_POWER, dev_name(&pdev->dev)); + if (ret) { + gpio_free(S3C2410_GPH(1)); + dev_err(&pdev->dev, "could not get BT_POWER\n"); + return ret; + } + + /* Configures BT serial port GPIOs */ + s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0); + s3c_gpio_setpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT); + s3c_gpio_setpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0); + s3c_gpio_setpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE); + s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0); + s3c_gpio_setpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE); + + rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH, + &h1940bt_rfkill_ops, NULL); + if (!rfk) { + ret = -ENOMEM; + goto err_rfk_alloc; + } + + ret = rfkill_register(rfk); + if (ret) + goto err_rfkill; + + platform_set_drvdata(pdev, rfk); + + return 0; + +err_rfkill: + rfkill_destroy(rfk); +err_rfk_alloc: + return ret; +} + +static int h1940bt_remove(struct platform_device *pdev) +{ + struct rfkill *rfk = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + gpio_free(S3C2410_GPH(1)); + + if (rfk) { + rfkill_unregister(rfk); + rfkill_destroy(rfk); + } + rfk = NULL; + + h1940bt_enable(0); + + return 0; +} + + +static struct platform_driver h1940bt_driver = { + .driver = { + .name = DRV_NAME, + }, + .probe = h1940bt_probe, + .remove = h1940bt_remove, +}; + + +static int __init h1940bt_init(void) +{ + return platform_driver_register(&h1940bt_driver); +} + +static void __exit h1940bt_exit(void) +{ + platform_driver_unregister(&h1940bt_driver); +} + +module_init(h1940bt_init); +module_exit(h1940bt_exit); + +MODULE_AUTHOR("Arnaud Patard "); +MODULE_DESCRIPTION("Driver for the iPAQ H1940 bluetooth chip"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-s3c24xx/include/mach/anubis-cpld.h b/arch/arm/mach-s3c24xx/include/mach/anubis-cpld.h new file mode 100644 index 00000000..1b614d5a --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/anubis-cpld.h @@ -0,0 +1,25 @@ +/* arch/arm/mach-s3c2410/include/mach/anubis-cpld.h + * + * Copyright (c) 2005 Simtec Electronics + * http://www.simtec.co.uk/products/ + * Ben Dooks + * + * ANUBIS - CPLD control constants + * + * 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_ANUBISCPLD_H +#define __ASM_ARCH_ANUBISCPLD_H + +/* CTRL2 - NAND WP control, IDE Reset assert/check */ + +#define ANUBIS_CTRL1_NANDSEL (0x3) + +/* IDREG - revision */ + +#define ANUBIS_IDREG_REVMASK (0x7) + +#endif /* __ASM_ARCH_ANUBISCPLD_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/anubis-irq.h b/arch/arm/mach-s3c24xx/include/mach/anubis-irq.h new file mode 100644 index 00000000..a2a32813 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/anubis-irq.h @@ -0,0 +1,21 @@ +/* arch/arm/mach-s3c2410/include/mach/anubis-irq.h + * + * Copyright (c) 2005 Simtec Electronics + * http://www.simtec.co.uk/products/ + * Ben Dooks + * + * ANUBIS - IRQ Number 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_ANUBISIRQ_H +#define __ASM_ARCH_ANUBISIRQ_H + +#define IRQ_IDE0 IRQ_EINT2 +#define IRQ_IDE1 IRQ_EINT3 +#define IRQ_ASIX IRQ_EINT1 + +#endif /* __ASM_ARCH_ANUBISIRQ_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/anubis-map.h b/arch/arm/mach-s3c24xx/include/mach/anubis-map.h new file mode 100644 index 00000000..c9deb3a5 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/anubis-map.h @@ -0,0 +1,38 @@ +/* arch/arm/mach-s3c2410/include/mach/anubis-map.h + * + * Copyright (c) 2005 Simtec Electronics + * http://www.simtec.co.uk/products/ + * Ben Dooks + * + * ANUBIS - 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. +*/ + +/* needs arch/map.h including with this */ + +#ifndef __ASM_ARCH_ANUBISMAP_H +#define __ASM_ARCH_ANUBISMAP_H + +/* start peripherals off after the S3C2410 */ + +#define ANUBIS_IOADDR(x) (S3C2410_ADDR((x) + 0x01800000)) + +#define ANUBIS_PA_CPLD (S3C2410_CS1 | (1<<26)) + +/* we put the CPLD registers next, to get them out of the way */ + +#define ANUBIS_VA_CTRL1 ANUBIS_IOADDR(0x00000000) /* 0x01800000 */ +#define ANUBIS_PA_CTRL1 (ANUBIS_PA_CPLD) + +#define ANUBIS_VA_IDREG ANUBIS_IOADDR(0x00300000) /* 0x01B00000 */ +#define ANUBIS_PA_IDREG (ANUBIS_PA_CPLD + (3<<23)) + +#define ANUBIS_IDEPRI ANUBIS_IOADDR(0x01000000) +#define ANUBIS_IDEPRIAUX ANUBIS_IOADDR(0x01100000) +#define ANUBIS_IDESEC ANUBIS_IOADDR(0x01200000) +#define ANUBIS_IDESECAUX ANUBIS_IOADDR(0x01300000) + +#endif /* __ASM_ARCH_ANUBISMAP_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/bast-cpld.h b/arch/arm/mach-s3c24xx/include/mach/bast-cpld.h new file mode 100644 index 00000000..bee2a7a9 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/bast-cpld.h @@ -0,0 +1,53 @@ +/* arch/arm/mach-s3c2410/include/mach/bast-cpld.h + * + * Copyright (c) 2003-2004 Simtec Electronics + * Ben Dooks + * + * BAST - CPLD control constants + * + * 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_BASTCPLD_H +#define __ASM_ARCH_BASTCPLD_H + +/* CTRL1 - Audio LR routing */ + +#define BAST_CPLD_CTRL1_LRCOFF (0x00) +#define BAST_CPLD_CTRL1_LRCADC (0x01) +#define BAST_CPLD_CTRL1_LRCDAC (0x02) +#define BAST_CPLD_CTRL1_LRCARM (0x03) +#define BAST_CPLD_CTRL1_LRMASK (0x03) + +/* CTRL2 - NAND WP control, IDE Reset assert/check */ + +#define BAST_CPLD_CTRL2_WNAND (0x04) +#define BAST_CPLD_CTLR2_IDERST (0x08) + +/* CTRL3 - rom write control, CPLD identity */ + +#define BAST_CPLD_CTRL3_IDMASK (0x0e) +#define BAST_CPLD_CTRL3_ROMWEN (0x01) + +/* CTRL4 - 8bit LCD interface control/status */ + +#define BAST_CPLD_CTRL4_LLAT (0x01) +#define BAST_CPLD_CTRL4_LCDRW (0x02) +#define BAST_CPLD_CTRL4_LCDCMD (0x04) +#define BAST_CPLD_CTRL4_LCDE2 (0x01) + +/* CTRL5 - DMA routing */ + +#define BAST_CPLD_DMA0_PRIIDE (0<<0) +#define BAST_CPLD_DMA0_SECIDE (1<<0) +#define BAST_CPLD_DMA0_ISA15 (2<<0) +#define BAST_CPLD_DMA0_ISA36 (3<<0) + +#define BAST_CPLD_DMA1_PRIIDE (0<<2) +#define BAST_CPLD_DMA1_SECIDE (1<<2) +#define BAST_CPLD_DMA1_ISA15 (2<<2) +#define BAST_CPLD_DMA1_ISA36 (3<<2) + +#endif /* __ASM_ARCH_BASTCPLD_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/bast-irq.h b/arch/arm/mach-s3c24xx/include/mach/bast-irq.h new file mode 100644 index 00000000..cac428c4 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/bast-irq.h @@ -0,0 +1,29 @@ +/* arch/arm/mach-s3c2410/include/mach/bast-irq.h + * + * Copyright (c) 2003-2004 Simtec Electronics + * Ben Dooks + * + * Machine BAST - IRQ Number 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_BASTIRQ_H +#define __ASM_ARCH_BASTIRQ_H + +/* irq numbers to onboard peripherals */ + +#define IRQ_USBOC IRQ_EINT18 +#define IRQ_IDE0 IRQ_EINT16 +#define IRQ_IDE1 IRQ_EINT17 +#define IRQ_PCSERIAL1 IRQ_EINT15 +#define IRQ_PCSERIAL2 IRQ_EINT14 +#define IRQ_PCPARALLEL IRQ_EINT13 +#define IRQ_ASIX IRQ_EINT11 +#define IRQ_DM9000 IRQ_EINT10 +#define IRQ_ISA IRQ_EINT9 +#define IRQ_SMALERT IRQ_EINT8 + +#endif /* __ASM_ARCH_BASTIRQ_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/bast-map.h b/arch/arm/mach-s3c24xx/include/mach/bast-map.h new file mode 100644 index 00000000..6e7dc9d0 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/bast-map.h @@ -0,0 +1,146 @@ +/* arch/arm/mach-s3c2410/include/mach/bast-map.h + * + * Copyright (c) 2003-2004 Simtec Electronics + * Ben Dooks + * + * Machine BAST - 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. +*/ + +/* needs arch/map.h including with this */ + +/* ok, we've used up to 0x13000000, now we need to find space for the + * peripherals that live in the nGCS[x] areas, which are quite numerous + * in their space. We also have the board's CPLD to find register space + * for. + */ + +#ifndef __ASM_ARCH_BASTMAP_H +#define __ASM_ARCH_BASTMAP_H + +#define BAST_IOADDR(x) (S3C2410_ADDR((x) + 0x01300000)) + +/* we put the CPLD registers next, to get them out of the way */ + +#define BAST_VA_CTRL1 BAST_IOADDR(0x00000000) /* 0x01300000 */ +#define BAST_PA_CTRL1 (S3C2410_CS5 | 0x7800000) + +#define BAST_VA_CTRL2 BAST_IOADDR(0x00100000) /* 0x01400000 */ +#define BAST_PA_CTRL2 (S3C2410_CS1 | 0x6000000) + +#define BAST_VA_CTRL3 BAST_IOADDR(0x00200000) /* 0x01500000 */ +#define BAST_PA_CTRL3 (S3C2410_CS1 | 0x6800000) + +#define BAST_VA_CTRL4 BAST_IOADDR(0x00300000) /* 0x01600000 */ +#define BAST_PA_CTRL4 (S3C2410_CS1 | 0x7000000) + +/* next, we have the PC104 ISA interrupt registers */ + +#define BAST_PA_PC104_IRQREQ (S3C2410_CS5 | 0x6000000) /* 0x01700000 */ +#define BAST_VA_PC104_IRQREQ BAST_IOADDR(0x00400000) + +#define BAST_PA_PC104_IRQRAW (S3C2410_CS5 | 0x6800000) /* 0x01800000 */ +#define BAST_VA_PC104_IRQRAW BAST_IOADDR(0x00500000) + +#define BAST_PA_PC104_IRQMASK (S3C2410_CS5 | 0x7000000) /* 0x01900000 */ +#define BAST_VA_PC104_IRQMASK BAST_IOADDR(0x00600000) + +#define BAST_PA_LCD_RCMD1 (0x8800000) +#define BAST_VA_LCD_RCMD1 BAST_IOADDR(0x00700000) + +#define BAST_PA_LCD_WCMD1 (0x8000000) +#define BAST_VA_LCD_WCMD1 BAST_IOADDR(0x00800000) + +#define BAST_PA_LCD_RDATA1 (0x9800000) +#define BAST_VA_LCD_RDATA1 BAST_IOADDR(0x00900000) + +#define BAST_PA_LCD_WDATA1 (0x9000000) +#define BAST_VA_LCD_WDATA1 BAST_IOADDR(0x00A00000) + +#define BAST_PA_LCD_RCMD2 (0xA800000) +#define BAST_VA_LCD_RCMD2 BAST_IOADDR(0x00B00000) + +#define BAST_PA_LCD_WCMD2 (0xA000000) +#define BAST_VA_LCD_WCMD2 BAST_IOADDR(0x00C00000) + +#define BAST_PA_LCD_RDATA2 (0xB800000) +#define BAST_VA_LCD_RDATA2 BAST_IOADDR(0x00D00000) + +#define BAST_PA_LCD_WDATA2 (0xB000000) +#define BAST_VA_LCD_WDATA2 BAST_IOADDR(0x00E00000) + + +/* 0xE0000000 contains the IO space that is split by speed and + * wether the access is for 8 or 16bit IO... this ensures that + * the correct access is made + * + * 0x10000000 of space, partitioned as so: + * + * 0x00000000 to 0x04000000 8bit, slow + * 0x04000000 to 0x08000000 16bit, slow + * 0x08000000 to 0x0C000000 16bit, net + * 0x0C000000 to 0x10000000 16bit, fast + * + * each of these spaces has the following in: + * + * 0x00000000 to 0x01000000 16MB ISA IO space + * 0x01000000 to 0x02000000 16MB ISA memory space + * 0x02000000 to 0x02100000 1MB IDE primary channel + * 0x02100000 to 0x02200000 1MB IDE primary channel aux + * 0x02200000 to 0x02400000 1MB IDE secondary channel + * 0x02300000 to 0x02400000 1MB IDE secondary channel aux + * 0x02400000 to 0x02500000 1MB ASIX ethernet controller + * 0x02500000 to 0x02600000 1MB Davicom DM9000 ethernet controller + * 0x02600000 to 0x02700000 1MB PC SuperIO controller + * + * the phyiscal layout of the zones are: + * nGCS2 - 8bit, slow + * nGCS3 - 16bit, slow + * nGCS4 - 16bit, net + * nGCS5 - 16bit, fast + */ + +#define BAST_VA_MULTISPACE (0xE0000000) + +#define BAST_VA_ISAIO (BAST_VA_MULTISPACE + 0x00000000) +#define BAST_VA_ISAMEM (BAST_VA_MULTISPACE + 0x01000000) +#define BAST_VA_IDEPRI (BAST_VA_MULTISPACE + 0x02000000) +#define BAST_VA_IDEPRIAUX (BAST_VA_MULTISPACE + 0x02100000) +#define BAST_VA_IDESEC (BAST_VA_MULTISPACE + 0x02200000) +#define BAST_VA_IDESECAUX (BAST_VA_MULTISPACE + 0x02300000) +#define BAST_VA_ASIXNET (BAST_VA_MULTISPACE + 0x02400000) +#define BAST_VA_DM9000 (BAST_VA_MULTISPACE + 0x02500000) +#define BAST_VA_SUPERIO (BAST_VA_MULTISPACE + 0x02600000) + +#define BAST_VA_MULTISPACE (0xE0000000) + +#define BAST_VAM_CS2 (0x00000000) +#define BAST_VAM_CS3 (0x04000000) +#define BAST_VAM_CS4 (0x08000000) +#define BAST_VAM_CS5 (0x0C000000) + +/* physical offset addresses for the peripherals */ + +#define BAST_PA_ISAIO (0x00000000) +#define BAST_PA_ASIXNET (0x01000000) +#define BAST_PA_SUPERIO (0x01800000) +#define BAST_PA_IDEPRI (0x02000000) +#define BAST_PA_IDEPRIAUX (0x02800000) +#define BAST_PA_IDESEC (0x03000000) +#define BAST_PA_IDESECAUX (0x03800000) +#define BAST_PA_ISAMEM (0x04000000) +#define BAST_PA_DM9000 (0x05000000) + +/* some configurations for the peripherals */ + +#define BAST_PCSIO (BAST_VA_SUPERIO + BAST_VAM_CS2) +/* */ + +#define BAST_ASIXNET_CS BAST_VAM_CS5 +#define BAST_IDE_CS BAST_VAM_CS5 +#define BAST_DM9000_CS BAST_VAM_CS4 + +#endif /* __ASM_ARCH_BASTMAP_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/bast-pmu.h b/arch/arm/mach-s3c24xx/include/mach/bast-pmu.h new file mode 100644 index 00000000..4c38b39b --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/bast-pmu.h @@ -0,0 +1,40 @@ +/* arch/arm/mach-s3c2410/include/mach/bast-pmu.h + * + * Copyright (c) 2003-2004 Simtec Electronics + * Ben Dooks + * Vincent Sanders + * + * Machine BAST - Power Management chip + * + * 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_BASTPMU_H +#define __ASM_ARCH_BASTPMU_H "08_OCT_2004" + +#define BASTPMU_REG_IDENT (0x00) +#define BASTPMU_REG_VERSION (0x01) +#define BASTPMU_REG_DDCCTRL (0x02) +#define BASTPMU_REG_POWER (0x03) +#define BASTPMU_REG_RESET (0x04) +#define BASTPMU_REG_GWO (0x05) +#define BASTPMU_REG_WOL (0x06) +#define BASTPMU_REG_WOR (0x07) +#define BASTPMU_REG_UID (0x09) + +#define BASTPMU_EEPROM (0xC0) + +#define BASTPMU_EEP_UID (BASTPMU_EEPROM + 0) +#define BASTPMU_EEP_WOL (BASTPMU_EEPROM + 8) +#define BASTPMU_EEP_WOR (BASTPMU_EEPROM + 9) + +#define BASTPMU_IDENT_0 0x53 +#define BASTPMU_IDENT_1 0x42 +#define BASTPMU_IDENT_2 0x50 +#define BASTPMU_IDENT_3 0x4d + +#define BASTPMU_RESET_GUARD (0x55) + +#endif /* __ASM_ARCH_BASTPMU_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/debug-macro.S b/arch/arm/mach-s3c24xx/include/mach/debug-macro.S new file mode 100644 index 00000000..4135de87 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/debug-macro.S @@ -0,0 +1,101 @@ +/* arch/arm/mach-s3c2410/include/mach/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Copyright (C) 2005 Simtec Electronics + * + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * 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 +#include +#include + +#define S3C2410_UART1_OFF (0x4000) +#define SHIFT_2440TXF (14-9) + + .macro addruart, rp, rv, tmp + ldr \rp, = S3C24XX_PA_UART + ldr \rv, = S3C24XX_VA_UART +#if CONFIG_DEBUG_S3C_UART != 0 + add \rp, \rp, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART) + add \rv, \rv, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART) +#endif + .endm + + .macro fifo_full_s3c24xx rd, rx + @ check for arm920 vs arm926. currently assume all arm926 + @ devices have an 64 byte FIFO identical to the s3c2440 + mrc p15, 0, \rd, c0, c0 + and \rd, \rd, #0xff0 + teq \rd, #0x260 + beq 1004f + mrc p15, 0, \rd, c1, c0 + tst \rd, #1 + addeq \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART) + addne \rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART) + bic \rd, \rd, #0xff000 + ldr \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ] + and \rd, \rd, #0x00ff0000 + teq \rd, #0x00440000 @ is it 2440? +1004: + ldr \rd, [ \rx, # S3C2410_UFSTAT ] + moveq \rd, \rd, lsr #SHIFT_2440TXF + tst \rd, #S3C2410_UFSTAT_TXFULL + .endm + + .macro fifo_full_s3c2410 rd, rx + ldr \rd, [ \rx, # S3C2410_UFSTAT ] + tst \rd, #S3C2410_UFSTAT_TXFULL + .endm + +/* fifo level reading */ + + .macro fifo_level_s3c24xx rd, rx + @ check for arm920 vs arm926. currently assume all arm926 + @ devices have an 64 byte FIFO identical to the s3c2440 + mrc p15, 0, \rd, c0, c0 + and \rd, \rd, #0xff0 + teq \rd, #0x260 + beq 10000f + mrc p15, 0, \rd, c1, c0 + tst \rd, #1 + addeq \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART) + addne \rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART) + bic \rd, \rd, #0xff000 + ldr \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ] + and \rd, \rd, #0x00ff0000 + teq \rd, #0x00440000 @ is it 2440? + +10000: + ldr \rd, [ \rx, # S3C2410_UFSTAT ] + andne \rd, \rd, #S3C2410_UFSTAT_TXMASK + andeq \rd, \rd, #S3C2440_UFSTAT_TXMASK + .endm + + .macro fifo_level_s3c2410 rd, rx + ldr \rd, [ \rx, # S3C2410_UFSTAT ] + and \rd, \rd, #S3C2410_UFSTAT_TXMASK + .endm + +/* Select the correct implementation depending on the configuration. The + * S3C2440 will get selected by default, as these are the most widely + * used variants of these +*/ + +#if defined(CONFIG_CPU_LLSERIAL_S3C2410_ONLY) +#define fifo_full fifo_full_s3c2410 +#define fifo_level fifo_level_s3c2410 +#elif !defined(CONFIG_CPU_LLSERIAL_S3C2440_ONLY) +#define fifo_full fifo_full_s3c24xx +#define fifo_level fifo_level_s3c24xx +#endif + +/* include the reset of the code which will do the work */ + +#include diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h new file mode 100644 index 00000000..acbdfecd --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/dma.h @@ -0,0 +1,210 @@ +/* arch/arm/mach-s3c2410/include/mach/dma.h + * + * Copyright (C) 2003-2006 Simtec Electronics + * Ben Dooks + * + * Samsung S3C24XX DMA 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. +*/ + +#ifndef __ASM_ARCH_DMA_H +#define __ASM_ARCH_DMA_H __FILE__ + +#include + +#define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */ + +/* We use `virtual` dma channels to hide the fact we have only a limited + * number of DMA channels, and not of all of them (dependent on the device) + * can be attached to any DMA source. We therefore let the DMA core handle + * the allocation of hardware channels to clients. +*/ + +enum dma_ch { + DMACH_XD0, + DMACH_XD1, + DMACH_SDI, + DMACH_SPI0, + DMACH_SPI1, + DMACH_UART0, + DMACH_UART1, + DMACH_UART2, + DMACH_TIMER, + DMACH_I2S_IN, + DMACH_I2S_OUT, + DMACH_PCM_IN, + DMACH_PCM_OUT, + DMACH_MIC_IN, + DMACH_USB_EP1, + DMACH_USB_EP2, + DMACH_USB_EP3, + DMACH_USB_EP4, + DMACH_UART0_SRC2, /* s3c2412 second uart sources */ + DMACH_UART1_SRC2, + DMACH_UART2_SRC2, + DMACH_UART3, /* s3c2443 has extra uart */ + DMACH_UART3_SRC2, + DMACH_MAX, /* the end entry */ +}; + +static inline bool samsung_dma_has_circular(void) +{ + return false; +} + +static inline bool samsung_dma_is_dmadev(void) +{ + return false; +} + +#include + +#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */ + +/* we have 4 dma channels */ +#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416) +#define S3C_DMA_CHANNELS (4) +#else +#define S3C_DMA_CHANNELS (6) +#endif + +/* types */ + +enum s3c2410_dma_state { + S3C2410_DMA_IDLE, + S3C2410_DMA_RUNNING, + S3C2410_DMA_PAUSED +}; + +/* enum s3c2410_dma_loadst + * + * This represents the state of the DMA engine, wrt to the loaded / running + * transfers. Since we don't have any way of knowing exactly the state of + * the DMA transfers, we need to know the state to make decisions on wether + * we can + * + * S3C2410_DMA_NONE + * + * There are no buffers loaded (the channel should be inactive) + * + * S3C2410_DMA_1LOADED + * + * There is one buffer loaded, however it has not been confirmed to be + * loaded by the DMA engine. This may be because the channel is not + * yet running, or the DMA driver decided that it was too costly to + * sit and wait for it to happen. + * + * S3C2410_DMA_1RUNNING + * + * The buffer has been confirmed running, and not finisged + * + * S3C2410_DMA_1LOADED_1RUNNING + * + * There is a buffer waiting to be loaded by the DMA engine, and one + * currently running. +*/ + +enum s3c2410_dma_loadst { + S3C2410_DMALOAD_NONE, + S3C2410_DMALOAD_1LOADED, + S3C2410_DMALOAD_1RUNNING, + S3C2410_DMALOAD_1LOADED_1RUNNING, +}; + + +/* flags */ + +#define S3C2410_DMAF_SLOW (1<<0) /* slow, so don't worry about + * waiting for reloads */ +#define S3C2410_DMAF_AUTOSTART (1<<1) /* auto-start if buffer queued */ + +#define S3C2410_DMAF_CIRCULAR (1 << 2) /* no circular dma support */ + +/* dma buffer */ + +struct s3c2410_dma_buf; + +/* s3c2410_dma_buf + * + * internally used buffer structure to describe a queued or running + * buffer. +*/ + +struct s3c2410_dma_buf { + struct s3c2410_dma_buf *next; + int magic; /* magic */ + int size; /* buffer size in bytes */ + dma_addr_t data; /* start of DMA data */ + dma_addr_t ptr; /* where the DMA got to [1] */ + void *id; /* client's id */ +}; + +/* [1] is this updated for both recv/send modes? */ + +struct s3c2410_dma_stats { + unsigned long loads; + unsigned long timeout_longest; + unsigned long timeout_shortest; + unsigned long timeout_avg; + unsigned long timeout_failed; +}; + +struct s3c2410_dma_map; + +/* struct s3c2410_dma_chan + * + * full state information for each DMA channel +*/ + +struct s3c2410_dma_chan { + /* channel state flags and information */ + unsigned char number; /* number of this dma channel */ + unsigned char in_use; /* channel allocated */ + unsigned char irq_claimed; /* irq claimed for channel */ + unsigned char irq_enabled; /* irq enabled for channel */ + unsigned char xfer_unit; /* size of an transfer */ + + /* channel state */ + + enum s3c2410_dma_state state; + enum s3c2410_dma_loadst load_state; + struct s3c2410_dma_client *client; + + /* channel configuration */ + enum dma_data_direction source; + enum dma_ch req_ch; + unsigned long dev_addr; + unsigned long load_timeout; + unsigned int flags; /* channel flags */ + + struct s3c24xx_dma_map *map; /* channel hw maps */ + + /* channel's hardware position and configuration */ + void __iomem *regs; /* channels registers */ + void __iomem *addr_reg; /* data address register */ + unsigned int irq; /* channel irq */ + unsigned long dcon; /* default value of DCON */ + + /* driver handles */ + s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */ + s3c2410_dma_opfn_t op_fn; /* channel op callback */ + + /* stats gathering */ + struct s3c2410_dma_stats *stats; + struct s3c2410_dma_stats stats_store; + + /* buffer list and information */ + struct s3c2410_dma_buf *curr; /* current dma buffer */ + struct s3c2410_dma_buf *next; /* next buffer to load */ + struct s3c2410_dma_buf *end; /* end of queue */ + + /* system device */ + struct device dev; +}; + +typedef unsigned long dma_device_t; + +#endif /* __ASM_ARCH_DMA_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/entry-macro.S b/arch/arm/mach-s3c24xx/include/mach/entry-macro.S new file mode 100644 index 00000000..7615a147 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/entry-macro.S @@ -0,0 +1,70 @@ +/* + * arch/arm/mach-s3c2410/include/mach/entry-macro.S + * + * Low-level IRQ helper macros for S3C2410-based platforms + * + * 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. +*/ + +/* We have a problem that the INTOFFSET register does not always + * show one interrupt. Occasionally we get two interrupts through + * the prioritiser, and this causes the INTOFFSET register to show + * what looks like the logical-or of the two interrupt numbers. + * + * Thanks to Klaus, Shannon, et al for helping to debug this problem +*/ + +#define INTPND (0x10) +#define INTOFFSET (0x14) + +#include +#include + + .macro get_irqnr_preamble, base, tmp + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + mov \base, #S3C24XX_VA_IRQ + + @@ try the interrupt offset register, since it is there + + ldr \irqstat, [ \base, #INTPND ] + teq \irqstat, #0 + beq 1002f + ldr \irqnr, [ \base, #INTOFFSET ] + mov \tmp, #1 + tst \irqstat, \tmp, lsl \irqnr + bne 1001f + + @@ the number specified is not a valid irq, so try + @@ and work it out for ourselves + + mov \irqnr, #0 @@ start here + + @@ work out which irq (if any) we got + + movs \tmp, \irqstat, lsl#16 + addeq \irqnr, \irqnr, #16 + moveq \irqstat, \irqstat, lsr#16 + tst \irqstat, #0xff + addeq \irqnr, \irqnr, #8 + moveq \irqstat, \irqstat, lsr#8 + tst \irqstat, #0xf + addeq \irqnr, \irqnr, #4 + moveq \irqstat, \irqstat, lsr#4 + tst \irqstat, #0x3 + addeq \irqnr, \irqnr, #2 + moveq \irqstat, \irqstat, lsr#2 + tst \irqstat, #0x1 + addeq \irqnr, \irqnr, #1 + + @@ we have the value +1001: + adds \irqnr, \irqnr, #IRQ_EINT0 +1002: + @@ exit here, Z flag unset if IRQ + + .endm diff --git a/arch/arm/mach-s3c24xx/include/mach/fb.h b/arch/arm/mach-s3c24xx/include/mach/fb.h new file mode 100644 index 00000000..a957bc8e --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/fb.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/mach-s3c24xx/include/mach/gpio-fns.h b/arch/arm/mach-s3c24xx/include/mach/gpio-fns.h new file mode 100644 index 00000000..c53ad34c --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/gpio-fns.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/mach-s3c24xx/include/mach/gpio-nrs.h b/arch/arm/mach-s3c24xx/include/mach/gpio-nrs.h new file mode 100644 index 00000000..019ea860 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/gpio-nrs.h @@ -0,0 +1,118 @@ +/* arch/arm/mach-s3c2410/include/mach/gpio-nrs.h + * + * Copyright (c) 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C2410 - GPIO bank numbering + * + * 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 __MACH_GPIONRS_H +#define __MACH_GPIONRS_H + +#define S3C2410_GPIONO(bank,offset) ((bank) + (offset)) + +#define S3C2410_GPIO_BANKG (32*6) +#define S3C2410_GPIO_BANKH (32*7) + +/* GPIO sizes for various SoCs: + * + * 2442 + * 2410 2412 2440 2443 2416 + * ---- ---- ---- ---- ---- + * A 23 22 25 16 25 + * B 11 11 11 11 9 + * C 16 15 16 16 16 + * D 16 16 16 16 16 + * E 16 16 16 16 16 + * F 8 8 8 8 8 + * G 16 16 16 16 8 + * H 11 11 9 15 15 + * J -- -- 13 16 -- + * K -- -- -- -- 16 + * L -- -- -- 15 7 + * M -- -- -- 2 2 + */ + +/* GPIO bank sizes */ +#define S3C2410_GPIO_A_NR (32) +#define S3C2410_GPIO_B_NR (32) +#define S3C2410_GPIO_C_NR (32) +#define S3C2410_GPIO_D_NR (32) +#define S3C2410_GPIO_E_NR (32) +#define S3C2410_GPIO_F_NR (32) +#define S3C2410_GPIO_G_NR (32) +#define S3C2410_GPIO_H_NR (32) +#define S3C2410_GPIO_J_NR (32) /* technically 16. */ +#define S3C2410_GPIO_K_NR (32) /* technically 16. */ +#define S3C2410_GPIO_L_NR (32) /* technically 15. */ +#define S3C2410_GPIO_M_NR (32) /* technically 2. */ + +#if CONFIG_S3C_GPIO_SPACE != 0 +#error CONFIG_S3C_GPIO_SPACE cannot be nonzero at the moment +#endif + +#define S3C2410_GPIO_NEXT(__gpio) \ + ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 0) + +#ifndef __ASSEMBLY__ + +enum s3c_gpio_number { + S3C2410_GPIO_A_START = 0, + S3C2410_GPIO_B_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_A), + S3C2410_GPIO_C_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_B), + S3C2410_GPIO_D_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_C), + S3C2410_GPIO_E_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_D), + S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E), + S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F), + S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G), + S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H), + S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J), + S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K), + S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L), +}; + +#endif /* __ASSEMBLY__ */ + +/* S3C2410 GPIO number definitions. */ + +#define S3C2410_GPA(_nr) (S3C2410_GPIO_A_START + (_nr)) +#define S3C2410_GPB(_nr) (S3C2410_GPIO_B_START + (_nr)) +#define S3C2410_GPC(_nr) (S3C2410_GPIO_C_START + (_nr)) +#define S3C2410_GPD(_nr) (S3C2410_GPIO_D_START + (_nr)) +#define S3C2410_GPE(_nr) (S3C2410_GPIO_E_START + (_nr)) +#define S3C2410_GPF(_nr) (S3C2410_GPIO_F_START + (_nr)) +#define S3C2410_GPG(_nr) (S3C2410_GPIO_G_START + (_nr)) +#define S3C2410_GPH(_nr) (S3C2410_GPIO_H_START + (_nr)) +#define S3C2410_GPJ(_nr) (S3C2410_GPIO_J_START + (_nr)) +#define S3C2410_GPK(_nr) (S3C2410_GPIO_K_START + (_nr)) +#define S3C2410_GPL(_nr) (S3C2410_GPIO_L_START + (_nr)) +#define S3C2410_GPM(_nr) (S3C2410_GPIO_M_START + (_nr)) + +/* compatibility until drivers can be modified */ + +#define S3C2410_GPA0 S3C2410_GPA(0) +#define S3C2410_GPA1 S3C2410_GPA(1) +#define S3C2410_GPA3 S3C2410_GPA(3) +#define S3C2410_GPA7 S3C2410_GPA(7) + +#define S3C2410_GPE0 S3C2410_GPE(0) +#define S3C2410_GPE1 S3C2410_GPE(1) +#define S3C2410_GPE2 S3C2410_GPE(2) +#define S3C2410_GPE3 S3C2410_GPE(3) +#define S3C2410_GPE4 S3C2410_GPE(4) +#define S3C2410_GPE5 S3C2410_GPE(5) +#define S3C2410_GPE6 S3C2410_GPE(6) +#define S3C2410_GPE7 S3C2410_GPE(7) +#define S3C2410_GPE8 S3C2410_GPE(8) +#define S3C2410_GPE9 S3C2410_GPE(9) +#define S3C2410_GPE10 S3C2410_GPE(10) + +#define S3C2410_GPH10 S3C2410_GPH(10) + +#endif /* __MACH_GPIONRS_H */ + diff --git a/arch/arm/mach-s3c24xx/include/mach/gpio-track.h b/arch/arm/mach-s3c24xx/include/mach/gpio-track.h new file mode 100644 index 00000000..c410a078 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/gpio-track.h @@ -0,0 +1,33 @@ +/* arch/arm/mach-s3c24100/include/mach/gpio-core.h + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C2410 - GPIO core 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. +*/ + +#ifndef __ASM_ARCH_GPIO_CORE_H +#define __ASM_ARCH_GPIO_CORE_H __FILE__ + +#include + +extern struct samsung_gpio_chip s3c24xx_gpios[]; + +static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int pin) +{ + struct samsung_gpio_chip *chip; + + if (pin > S3C_GPIO_END) + return NULL; + + chip = &s3c24xx_gpios[pin/32]; + return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL; +} + +#endif /* __ASM_ARCH_GPIO_CORE_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/gpio.h b/arch/arm/mach-s3c24xx/include/mach/gpio.h new file mode 100644 index 00000000..6fac70f3 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/gpio.h @@ -0,0 +1,35 @@ +/* arch/arm/mach-s3c2410/include/mach/gpio.h + * + * Copyright (c) 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C2410 - 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. +*/ + +/* some boards require extra gpio capacity to support external + * devices that need GPIO. + */ + +#ifdef CONFIG_CPU_S3C244X +#define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA) +#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416) +#define ARCH_NR_GPIOS (32 * 12 + CONFIG_S3C24XX_GPIO_EXTRA) +#else +#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA) +#endif + +#include +#include + +#ifdef CONFIG_CPU_S3C244X +#define S3C_GPIO_END (S3C2410_GPJ(0) + 32) +#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416) +#define S3C_GPIO_END (S3C2410_GPM(0) + 32) +#else +#define S3C_GPIO_END (S3C2410_GPH(0) + 32) +#endif diff --git a/arch/arm/mach-s3c24xx/include/mach/gta02.h b/arch/arm/mach-s3c24xx/include/mach/gta02.h new file mode 100644 index 00000000..3a56a229 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/gta02.h @@ -0,0 +1,84 @@ +#ifndef _GTA02_H +#define _GTA02_H + +#include + +/* Different hardware revisions, passed in ATAG_REVISION by u-boot */ +#define GTA02v1_SYSTEM_REV 0x00000310 +#define GTA02v2_SYSTEM_REV 0x00000320 +#define GTA02v3_SYSTEM_REV 0x00000330 +#define GTA02v4_SYSTEM_REV 0x00000340 +#define GTA02v5_SYSTEM_REV 0x00000350 +/* since A7 is basically same as A6, we use A6 PCB ID */ +#define GTA02v6_SYSTEM_REV 0x00000360 + +#define GTA02_GPIO_n3DL_GSM S3C2410_GPA(13) /* v1 + v2 + v3 only */ + +#define GTA02_GPIO_PWR_LED1 S3C2410_GPB(0) +#define GTA02_GPIO_PWR_LED2 S3C2410_GPB(1) +#define GTA02_GPIO_AUX_LED S3C2410_GPB(2) +#define GTA02_GPIO_VIBRATOR_ON S3C2410_GPB(3) +#define GTA02_GPIO_MODEM_RST S3C2410_GPB(5) +#define GTA02_GPIO_BT_EN S3C2410_GPB(6) +#define GTA02_GPIO_MODEM_ON S3C2410_GPB(7) +#define GTA02_GPIO_EXTINT8 S3C2410_GPB(8) +#define GTA02_GPIO_USB_PULLUP S3C2410_GPB(9) + +#define GTA02_GPIO_PIO5 S3C2410_GPC(5) /* v3 + v4 only */ + +#define GTA02v3_GPIO_nG1_CS S3C2410_GPD(12) /* v3 + v4 only */ +#define GTA02v3_GPIO_nG2_CS S3C2410_GPD(13) /* v3 + v4 only */ +#define GTA02v5_GPIO_HDQ S3C2410_GPD(14) /* v5 + */ + +#define GTA02_GPIO_nG1_INT S3C2410_GPF(0) +#define GTA02_GPIO_IO1 S3C2410_GPF(1) +#define GTA02_GPIO_PIO_2 S3C2410_GPF(2) /* v2 + v3 + v4 only */ +#define GTA02_GPIO_JACK_INSERT S3C2410_GPF(4) +#define GTA02_GPIO_WLAN_GPIO1 S3C2410_GPF(5) /* v2 + v3 + v4 only */ +#define GTA02_GPIO_AUX_KEY S3C2410_GPF(6) +#define GTA02_GPIO_HOLD_KEY S3C2410_GPF(7) + +#define GTA02_GPIO_3D_IRQ S3C2410_GPG(4) +#define GTA02v2_GPIO_nG2_INT S3C2410_GPG(8) /* v2 + v3 + v4 only */ +#define GTA02v3_GPIO_nUSB_OC S3C2410_GPG(9) /* v3 + v4 only */ +#define GTA02v3_GPIO_nUSB_FLT S3C2410_GPG(10) /* v3 + v4 only */ +#define GTA02v3_GPIO_nGSM_OC S3C2410_GPG(11) /* v3 + v4 only */ + +#define GTA02_GPIO_AMP_SHUT S3C2410_GPJ(1) /* v2 + v3 + v4 only */ +#define GTA02v1_GPIO_WLAN_GPIO10 S3C2410_GPJ(2) +#define GTA02_GPIO_HP_IN S3C2410_GPJ(2) /* v2 + v3 + v4 only */ +#define GTA02_GPIO_INT0 S3C2410_GPJ(3) /* v2 + v3 + v4 only */ +#define GTA02_GPIO_nGSM_EN S3C2410_GPJ(4) +#define GTA02_GPIO_3D_RESET S3C2410_GPJ(5) +#define GTA02_GPIO_nDL_GSM S3C2410_GPJ(6) /* v4 + v5 only */ +#define GTA02_GPIO_WLAN_GPIO0 S3C2410_GPJ(7) +#define GTA02v1_GPIO_BAT_ID S3C2410_GPJ(8) +#define GTA02_GPIO_KEEPACT S3C2410_GPJ(8) +#define GTA02v1_GPIO_HP_IN S3C2410_GPJ(10) +#define GTA02_CHIP_PWD S3C2410_GPJ(11) /* v2 + v3 + v4 only */ +#define GTA02_GPIO_nWLAN_RESET S3C2410_GPJ(12) /* v2 + v3 + v4 only */ + +#define GTA02_IRQ_GSENSOR_1 IRQ_EINT0 +#define GTA02_IRQ_MODEM IRQ_EINT1 +#define GTA02_IRQ_PIO_2 IRQ_EINT2 /* v2 + v3 + v4 only */ +#define GTA02_IRQ_nJACK_INSERT IRQ_EINT4 +#define GTA02_IRQ_WLAN_GPIO1 IRQ_EINT5 +#define GTA02_IRQ_AUX IRQ_EINT6 +#define GTA02_IRQ_nHOLD IRQ_EINT7 +#define GTA02_IRQ_PCF50633 IRQ_EINT9 +#define GTA02_IRQ_3D IRQ_EINT12 +#define GTA02_IRQ_GSENSOR_2 IRQ_EINT16 /* v2 + v3 + v4 only */ +#define GTA02v3_IRQ_nUSB_OC IRQ_EINT17 /* v3 + v4 only */ +#define GTA02v3_IRQ_nUSB_FLT IRQ_EINT18 /* v3 + v4 only */ +#define GTA02v3_IRQ_nGSM_OC IRQ_EINT19 /* v3 + v4 only */ + +/* returns 00 000 on GTA02 A5 and earlier, A6 returns 01 001 */ +#define GTA02_PCB_ID1_0 S3C2410_GPC(13) +#define GTA02_PCB_ID1_1 S3C2410_GPC(15) +#define GTA02_PCB_ID1_2 S3C2410_GPD(0) +#define GTA02_PCB_ID2_0 S3C2410_GPD(3) +#define GTA02_PCB_ID2_1 S3C2410_GPD(4) + +int gta02_get_pcb_revision(void); + +#endif /* _GTA02_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/h1940-latch.h b/arch/arm/mach-s3c24xx/include/mach/h1940-latch.h new file mode 100644 index 00000000..fc897d3a --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/h1940-latch.h @@ -0,0 +1,43 @@ +/* arch/arm/mach-s3c2410/include/mach/h1940-latch.h + * + * Copyright (c) 2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * iPAQ H1940 series - latch 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_H1940_LATCH_H +#define __ASM_ARCH_H1940_LATCH_H + +#include + +#define H1940_LATCH_GPIO(x) (S3C_GPIO_END + (x)) + +/* SD layer latch */ + +#define H1940_LATCH_LCD_P0 H1940_LATCH_GPIO(0) +#define H1940_LATCH_LCD_P1 H1940_LATCH_GPIO(1) +#define H1940_LATCH_LCD_P2 H1940_LATCH_GPIO(2) +#define H1940_LATCH_LCD_P3 H1940_LATCH_GPIO(3) +#define H1940_LATCH_MAX1698_nSHUTDOWN H1940_LATCH_GPIO(4) +#define H1940_LATCH_LED_RED H1940_LATCH_GPIO(5) +#define H1940_LATCH_SDQ7 H1940_LATCH_GPIO(6) +#define H1940_LATCH_USB_DP H1940_LATCH_GPIO(7) + +/* CPU layer latch */ + +#define H1940_LATCH_UDA_POWER H1940_LATCH_GPIO(8) +#define H1940_LATCH_AUDIO_POWER H1940_LATCH_GPIO(9) +#define H1940_LATCH_SM803_ENABLE H1940_LATCH_GPIO(10) +#define H1940_LATCH_LCD_P4 H1940_LATCH_GPIO(11) +#define H1940_LATCH_SD_POWER H1940_LATCH_GPIO(12) +#define H1940_LATCH_BLUETOOTH_POWER H1940_LATCH_GPIO(13) +#define H1940_LATCH_LED_GREEN H1940_LATCH_GPIO(14) +#define H1940_LATCH_LED_FLASH H1940_LATCH_GPIO(15) + +#endif /* __ASM_ARCH_H1940_LATCH_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/h1940.h b/arch/arm/mach-s3c24xx/include/mach/h1940.h new file mode 100644 index 00000000..2aa683c8 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/h1940.h @@ -0,0 +1,24 @@ +/* arch/arm/mach-s3c2410/include/mach/h1940.h + * + * Copyright 2006 Ben Dooks + * + * H1940 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_H1940_H +#define __ASM_ARCH_H1940_H + +#define H1940_SUSPEND_CHECKSUM (0x30003ff8) +#define H1940_SUSPEND_RESUMEAT (0x30081000) +#define H1940_SUSPEND_CHECK (0x30080000) + +extern void h1940_pm_return(void); +extern int h1940_led_blink_set(unsigned gpio, int state, + unsigned long *delay_on, unsigned long *delay_off); + + +#endif /* __ASM_ARCH_H1940_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/hardware.h b/arch/arm/mach-s3c24xx/include/mach/hardware.h new file mode 100644 index 00000000..aef5631e --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/hardware.h @@ -0,0 +1,42 @@ +/* arch/arm/mach-s3c2410/include/mach/hardware.h + * + * Copyright (c) 2003 Simtec Electronics + * Ben Dooks + * + * S3C2410 - hardware + * + * 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_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#ifndef __ASSEMBLY__ + +extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg); + +#ifdef CONFIG_CPU_S3C2440 + +extern int s3c2440_set_dsc(unsigned int pin, unsigned int value); + +#endif /* CONFIG_CPU_S3C2440 */ + +#ifdef CONFIG_CPU_S3C2412 + +extern int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state); + +#endif /* CONFIG_CPU_S3C2412 */ + +#endif /* __ASSEMBLY__ */ + +#include +#include + +/* machine specific hardware definitions should go after this */ + +/* currently here until moved into config (todo) */ +#define CONFIG_NO_MULTIWORD_IO + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/idle.h b/arch/arm/mach-s3c24xx/include/mach/idle.h new file mode 100644 index 00000000..e9ddd706 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/idle.h @@ -0,0 +1,24 @@ +/* arch/arm/mach-s3c2410/include/mach/idle.h + * + * Copyright (c) 2004 Simtec Electronics + * 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. + * + * S3C2410 CPU Idle controls +*/ + +#ifndef __ASM_ARCH_IDLE_H +#define __ASM_ARCH_IDLE_H __FILE__ + +/* This allows the over-ride of the default idle code, in case there + * is any other things to be done over idle (like DVS) +*/ + +extern void (*s3c24xx_idle)(void); + +extern void s3c24xx_default_idle(void); + +#endif /* __ASM_ARCH_IDLE_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/io.h b/arch/arm/mach-s3c24xx/include/mach/io.h new file mode 100644 index 00000000..5dd1db4e --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/io.h @@ -0,0 +1,211 @@ +/* + * arch/arm/mach-s3c2410/include/mach/io.h + * from arch/arm/mach-rpc/include/mach/io.h + * + * Copyright (C) 1997 Russell King + * (C) 2003 Simtec Electronics +*/ + +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#include + +#define IO_SPACE_LIMIT 0xffffffff + +/* + * We use two different types of addressing - PC style addresses, and ARM + * addresses. PC style accesses the PC hardware with the normal PC IO + * addresses, eg 0x3f8 for serial#1. ARM addresses are above A28 + * and are translated to the start of IO. Note that all addresses are + * not shifted left! + */ + +#define __PORT_PCIO(x) ((x) < (1<<28)) + +#define PCIO_BASE (S3C24XX_VA_ISA_WORD) +#define PCIO_BASE_b (S3C24XX_VA_ISA_BYTE) +#define PCIO_BASE_w (S3C24XX_VA_ISA_WORD) +#define PCIO_BASE_l (S3C24XX_VA_ISA_WORD) +/* + * Dynamic IO functions - let the compiler + * optimize the expressions + */ + +#define DECLARE_DYN_OUT(sz,fnsuffix,instr) \ +static inline void __out##fnsuffix (unsigned int val, unsigned int port) \ +{ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "cmp %2, #(1<<28)\n\t" \ + "mov %0, %2\n\t" \ + "addcc %0, %0, %3\n\t" \ + "str" instr " %1, [%0, #0 ] @ out" #fnsuffix \ + : "=&r" (temp) \ + : "r" (val), "r" (port), "Ir" (PCIO_BASE_##fnsuffix) \ + : "cc"); \ +} + + +#define DECLARE_DYN_IN(sz,fnsuffix,instr) \ +static inline unsigned sz __in##fnsuffix (unsigned int port) \ +{ \ + unsigned long temp, value; \ + __asm__ __volatile__( \ + "cmp %2, #(1<<28)\n\t" \ + "mov %0, %2\n\t" \ + "addcc %0, %0, %3\n\t" \ + "ldr" instr " %1, [%0, #0 ] @ in" #fnsuffix \ + : "=&r" (temp), "=r" (value) \ + : "r" (port), "Ir" (PCIO_BASE_##fnsuffix) \ + : "cc"); \ + return (unsigned sz)value; \ +} + +static inline void __iomem *__ioaddr (unsigned long port) +{ + return __PORT_PCIO(port) ? (PCIO_BASE + port) : (void __iomem *)port; +} + +#define DECLARE_IO(sz,fnsuffix,instr) \ + DECLARE_DYN_IN(sz,fnsuffix,instr) \ + DECLARE_DYN_OUT(sz,fnsuffix,instr) + +DECLARE_IO(char,b,"b") +DECLARE_IO(short,w,"h") +DECLARE_IO(int,l,"") + +#undef DECLARE_IO +#undef DECLARE_DYN_IN + +/* + * Constant address IO functions + * + * These have to be macros for the 'J' constraint to work - + * +/-4096 immediate operand. + */ +#define __outbc(value,port) \ +({ \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "strb %0, [%1, %2] @ outbc" \ + : : "r" (value), "r" (PCIO_BASE), "Jr" ((port))); \ + else \ + __asm__ __volatile__( \ + "strb %0, [%1, #0] @ outbc" \ + : : "r" (value), "r" ((port))); \ +}) + +#define __inbc(port) \ +({ \ + unsigned char result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldrb %0, [%1, %2] @ inbc" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port))); \ + else \ + __asm__ __volatile__( \ + "ldrb %0, [%1, #0] @ inbc" \ + : "=r" (result) : "r" ((port))); \ + result; \ +}) + +#define __outwc(value,port) \ +({ \ + unsigned long v = value; \ + if (__PORT_PCIO((port))) { \ + if ((port) < 256 && (port) > -256) \ + __asm__ __volatile__( \ + "strh %0, [%1, %2] @ outwc" \ + : : "r" (v), "r" (PCIO_BASE), "Jr" ((port))); \ + else if ((port) > 0) \ + __asm__ __volatile__( \ + "strh %0, [%1, %2] @ outwc" \ + : : "r" (v), \ + "r" (PCIO_BASE + ((port) & ~0xff)), \ + "Jr" (((port) & 0xff))); \ + else \ + __asm__ __volatile__( \ + "strh %0, [%1, #0] @ outwc" \ + : : "r" (v), \ + "r" (PCIO_BASE + (port))); \ + } else \ + __asm__ __volatile__( \ + "strh %0, [%1, #0] @ outwc" \ + : : "r" (v), "r" ((port))); \ +}) + +#define __inwc(port) \ +({ \ + unsigned short result; \ + if (__PORT_PCIO((port))) { \ + if ((port) < 256 && (port) > -256 ) \ + __asm__ __volatile__( \ + "ldrh %0, [%1, %2] @ inwc" \ + : "=r" (result) \ + : "r" (PCIO_BASE), \ + "Jr" ((port))); \ + else if ((port) > 0) \ + __asm__ __volatile__( \ + "ldrh %0, [%1, %2] @ inwc" \ + : "=r" (result) \ + : "r" (PCIO_BASE + ((port) & ~0xff)), \ + "Jr" (((port) & 0xff))); \ + else \ + __asm__ __volatile__( \ + "ldrh %0, [%1, #0] @ inwc" \ + : "=r" (result) \ + : "r" (PCIO_BASE + ((port)))); \ + } else \ + __asm__ __volatile__( \ + "ldrh %0, [%1, #0] @ inwc" \ + : "=r" (result) : "r" ((port))); \ + result; \ +}) + +#define __outlc(value,port) \ +({ \ + unsigned long v = value; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "str %0, [%1, %2] @ outlc" \ + : : "r" (v), "r" (PCIO_BASE), "Jr" ((port))); \ + else \ + __asm__ __volatile__( \ + "str %0, [%1, #0] @ outlc" \ + : : "r" (v), "r" ((port))); \ +}) + +#define __inlc(port) \ +({ \ + unsigned long result; \ + if (__PORT_PCIO((port))) \ + __asm__ __volatile__( \ + "ldr %0, [%1, %2] @ inlc" \ + : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port))); \ + else \ + __asm__ __volatile__( \ + "ldr %0, [%1, #0] @ inlc" \ + : "=r" (result) : "r" ((port))); \ + result; \ +}) + +#define __ioaddrc(port) ((__PORT_PCIO(port) ? PCIO_BASE + (port) : (void __iomem *)(port))) + +#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p)) +#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p)) +#define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p)) +#define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p)) +#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p)) +#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p)) +#define __ioaddr(p) (__builtin_constant_p((p)) ? __ioaddr(p) : __ioaddrc(p)) + +#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l) +#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l) +#define insl(p,d,l) __raw_readsl(__ioaddr(p),d,l) + +#define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l) +#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l) +#define outsl(p,d,l) __raw_writesl(__ioaddr(p),d,l) + +#endif diff --git a/arch/arm/mach-s3c24xx/include/mach/irqs.h b/arch/arm/mach-s3c24xx/include/mach/irqs.h new file mode 100644 index 00000000..e53b2177 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/irqs.h @@ -0,0 +1,202 @@ +/* arch/arm/mach-s3c2410/include/mach/irqs.h + * + * Copyright (c) 2003-2005 Simtec Electronics + * Ben Dooks + * + * 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_IRQS_H +#define __ASM_ARCH_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.... + */ + +#define S3C2410_CPUIRQ_OFFSET (16) + +#define S3C2410_IRQ(x) ((x) + S3C2410_CPUIRQ_OFFSET) + +/* main cpu interrupts */ +#define IRQ_EINT0 S3C2410_IRQ(0) /* 16 */ +#define IRQ_EINT1 S3C2410_IRQ(1) +#define IRQ_EINT2 S3C2410_IRQ(2) +#define IRQ_EINT3 S3C2410_IRQ(3) +#define IRQ_EINT4t7 S3C2410_IRQ(4) /* 20 */ +#define IRQ_EINT8t23 S3C2410_IRQ(5) +#define IRQ_RESERVED6 S3C2410_IRQ(6) /* for s3c2410 */ +#define IRQ_CAM S3C2410_IRQ(6) /* for s3c2440,s3c2443 */ +#define IRQ_BATT_FLT S3C2410_IRQ(7) +#define IRQ_TICK S3C2410_IRQ(8) /* 24 */ +#define IRQ_WDT S3C2410_IRQ(9) /* WDT/AC97 for s3c2443 */ +#define IRQ_TIMER0 S3C2410_IRQ(10) +#define IRQ_TIMER1 S3C2410_IRQ(11) +#define IRQ_TIMER2 S3C2410_IRQ(12) +#define IRQ_TIMER3 S3C2410_IRQ(13) +#define IRQ_TIMER4 S3C2410_IRQ(14) +#define IRQ_UART2 S3C2410_IRQ(15) +#define IRQ_LCD S3C2410_IRQ(16) /* 32 */ +#define IRQ_DMA0 S3C2410_IRQ(17) /* IRQ_DMA for s3c2443 */ +#define IRQ_DMA1 S3C2410_IRQ(18) +#define IRQ_DMA2 S3C2410_IRQ(19) +#define IRQ_DMA3 S3C2410_IRQ(20) +#define IRQ_SDI S3C2410_IRQ(21) +#define IRQ_SPI0 S3C2410_IRQ(22) +#define IRQ_UART1 S3C2410_IRQ(23) +#define IRQ_RESERVED24 S3C2410_IRQ(24) /* 40 */ +#define IRQ_NFCON S3C2410_IRQ(24) /* for s3c2440 */ +#define IRQ_USBD S3C2410_IRQ(25) +#define IRQ_USBH S3C2410_IRQ(26) +#define IRQ_IIC S3C2410_IRQ(27) +#define IRQ_UART0 S3C2410_IRQ(28) /* 44 */ +#define IRQ_SPI1 S3C2410_IRQ(29) +#define IRQ_RTC S3C2410_IRQ(30) +#define IRQ_ADCPARENT S3C2410_IRQ(31) + +/* interrupts generated from the external interrupts sources */ +#define IRQ_EINT4 S3C2410_IRQ(32) /* 48 */ +#define IRQ_EINT5 S3C2410_IRQ(33) +#define IRQ_EINT6 S3C2410_IRQ(34) +#define IRQ_EINT7 S3C2410_IRQ(35) +#define IRQ_EINT8 S3C2410_IRQ(36) +#define IRQ_EINT9 S3C2410_IRQ(37) +#define IRQ_EINT10 S3C2410_IRQ(38) +#define IRQ_EINT11 S3C2410_IRQ(39) +#define IRQ_EINT12 S3C2410_IRQ(40) +#define IRQ_EINT13 S3C2410_IRQ(41) +#define IRQ_EINT14 S3C2410_IRQ(42) +#define IRQ_EINT15 S3C2410_IRQ(43) +#define IRQ_EINT16 S3C2410_IRQ(44) +#define IRQ_EINT17 S3C2410_IRQ(45) +#define IRQ_EINT18 S3C2410_IRQ(46) +#define IRQ_EINT19 S3C2410_IRQ(47) +#define IRQ_EINT20 S3C2410_IRQ(48) /* 64 */ +#define IRQ_EINT21 S3C2410_IRQ(49) +#define IRQ_EINT22 S3C2410_IRQ(50) +#define IRQ_EINT23 S3C2410_IRQ(51) + +#define IRQ_EINT_BIT(x) ((x) - IRQ_EINT4 + 4) +#define IRQ_EINT(x) (((x) >= 4) ? (IRQ_EINT4 + (x) - 4) : (IRQ_EINT0 + (x))) + +#define IRQ_LCD_FIFO S3C2410_IRQ(52) +#define IRQ_LCD_FRAME S3C2410_IRQ(53) + +/* IRQs for the interal UARTs, and ADC + * these need to be ordered in number of appearance in the + * SUBSRC mask register +*/ + +#define S3C2410_IRQSUB(x) S3C2410_IRQ((x)+54) + +#define IRQ_S3CUART_RX0 S3C2410_IRQSUB(0) /* 70 */ +#define IRQ_S3CUART_TX0 S3C2410_IRQSUB(1) +#define IRQ_S3CUART_ERR0 S3C2410_IRQSUB(2) + +#define IRQ_S3CUART_RX1 S3C2410_IRQSUB(3) /* 73 */ +#define IRQ_S3CUART_TX1 S3C2410_IRQSUB(4) +#define IRQ_S3CUART_ERR1 S3C2410_IRQSUB(5) + +#define IRQ_S3CUART_RX2 S3C2410_IRQSUB(6) /* 76 */ +#define IRQ_S3CUART_TX2 S3C2410_IRQSUB(7) +#define IRQ_S3CUART_ERR2 S3C2410_IRQSUB(8) + +#define IRQ_TC S3C2410_IRQSUB(9) +#define IRQ_ADC S3C2410_IRQSUB(10) + +/* extra irqs for s3c2412 */ + +#define IRQ_S3C2412_CFSDI S3C2410_IRQ(21) + +#define IRQ_S3C2412_SDI S3C2410_IRQSUB(13) +#define IRQ_S3C2412_CF S3C2410_IRQSUB(14) + + +#define IRQ_S3C2416_EINT8t15 S3C2410_IRQ(5) +#define IRQ_S3C2416_DMA S3C2410_IRQ(17) +#define IRQ_S3C2416_UART3 S3C2410_IRQ(18) +#define IRQ_S3C2416_SDI1 S3C2410_IRQ(20) +#define IRQ_S3C2416_SDI0 S3C2410_IRQ(21) + +#define IRQ_S3C2416_LCD2 S3C2410_IRQSUB(15) +#define IRQ_S3C2416_LCD3 S3C2410_IRQSUB(16) +#define IRQ_S3C2416_LCD4 S3C2410_IRQSUB(17) +#define IRQ_S3C2416_DMA0 S3C2410_IRQSUB(18) +#define IRQ_S3C2416_DMA1 S3C2410_IRQSUB(19) +#define IRQ_S3C2416_DMA2 S3C2410_IRQSUB(20) +#define IRQ_S3C2416_DMA3 S3C2410_IRQSUB(21) +#define IRQ_S3C2416_DMA4 S3C2410_IRQSUB(22) +#define IRQ_S3C2416_DMA5 S3C2410_IRQSUB(23) +#define IRQ_S32416_WDT S3C2410_IRQSUB(27) +#define IRQ_S32416_AC97 S3C2410_IRQSUB(28) + + +/* extra irqs for s3c2440 */ + +#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */ +#define IRQ_S3C2440_CAM_P S3C2410_IRQSUB(12) /* S3C2443 too */ +#define IRQ_S3C2440_WDT S3C2410_IRQSUB(13) +#define IRQ_S3C2440_AC97 S3C2410_IRQSUB(14) + +/* irqs for s3c2443 */ + +#define IRQ_S3C2443_DMA S3C2410_IRQ(17) /* IRQ_DMA1 */ +#define IRQ_S3C2443_UART3 S3C2410_IRQ(18) /* IRQ_DMA2 */ +#define IRQ_S3C2443_CFCON S3C2410_IRQ(19) /* IRQ_DMA3 */ +#define IRQ_S3C2443_HSMMC S3C2410_IRQ(20) /* IRQ_SDI */ +#define IRQ_S3C2443_NAND S3C2410_IRQ(24) /* reserved */ + +#define IRQ_S3C2416_HSMMC0 S3C2410_IRQ(21) /* S3C2416/S3C2450 */ + +#define IRQ_HSMMC0 IRQ_S3C2416_HSMMC0 +#define IRQ_HSMMC1 IRQ_S3C2443_HSMMC + +#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14) +#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15) +#define IRQ_S3C2443_LCD3 S3C2410_IRQSUB(16) +#define IRQ_S3C2443_LCD4 S3C2410_IRQSUB(17) + +#define IRQ_S3C2443_DMA0 S3C2410_IRQSUB(18) +#define IRQ_S3C2443_DMA1 S3C2410_IRQSUB(19) +#define IRQ_S3C2443_DMA2 S3C2410_IRQSUB(20) +#define IRQ_S3C2443_DMA3 S3C2410_IRQSUB(21) +#define IRQ_S3C2443_DMA4 S3C2410_IRQSUB(22) +#define IRQ_S3C2443_DMA5 S3C2410_IRQSUB(23) + +/* UART3 */ +#define IRQ_S3C2443_RX3 S3C2410_IRQSUB(24) +#define IRQ_S3C2443_TX3 S3C2410_IRQSUB(25) +#define IRQ_S3C2443_ERR3 S3C2410_IRQSUB(26) + +#define IRQ_S3C2443_WDT S3C2410_IRQSUB(27) +#define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28) + +#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416) +#define NR_IRQS (IRQ_S3C2443_AC97+1) +#else +#define NR_IRQS (IRQ_S3C2440_AC97+1) +#endif + +/* compatibility define. */ +#define IRQ_UART3 IRQ_S3C2443_UART3 +#define IRQ_S3CUART_RX3 IRQ_S3C2443_RX3 +#define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3 +#define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3 + +#define IRQ_LCD_VSYNC IRQ_S3C2443_LCD3 +#define IRQ_LCD_SYSTEM IRQ_S3C2443_LCD2 + +#ifdef CONFIG_CPU_S3C2440 +#define IRQ_S3C244X_AC97 IRQ_S3C2440_AC97 +#else +#define IRQ_S3C244X_AC97 IRQ_S3C2443_AC97 +#endif + +/* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */ +#define FIQ_START IRQ_EINT0 + +#endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/leds-gpio.h b/arch/arm/mach-s3c24xx/include/mach/leds-gpio.h new file mode 100644 index 00000000..d8a76725 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/leds-gpio.h @@ -0,0 +1,28 @@ +/* arch/arm/mach-s3c2410/include/mach/leds-gpio.h + * + * Copyright (c) 2006 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C24XX - LEDs GPIO connector + * + * 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_LEDSGPIO_H +#define __ASM_ARCH_LEDSGPIO_H "leds-gpio.h" + +#define S3C24XX_LEDF_ACTLOW (1<<0) /* LED is on when GPIO low */ +#define S3C24XX_LEDF_TRISTATE (1<<1) /* tristate to turn off */ + +struct s3c24xx_led_platdata { + unsigned int gpio; + unsigned int flags; + + char *name; + char *def_trigger; +}; + +#endif /* __ASM_ARCH_LEDSGPIO_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/map.h b/arch/arm/mach-s3c24xx/include/mach/map.h new file mode 100644 index 00000000..78ae807f --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/map.h @@ -0,0 +1,165 @@ +/* arch/arm/mach-s3c2410/include/mach/map.h + * + * Copyright (c) 2003 Simtec Electronics + * Ben Dooks + * + * S3C2410 - 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 + +#include + +/* + * S3C2410 UART offset is 0x4000 but the other SoCs are 0x400. + * So need to define it, and here is to avoid redefinition warning. + */ +#define S3C_UART_OFFSET (0x4000) + +#include + +/* + * interrupt controller is the first thing we put in, to make + * the assembly code for the irq detection easier + */ +#define S3C2410_PA_IRQ (0x4A000000) +#define S3C24XX_SZ_IRQ SZ_1M + +/* memory controller registers */ +#define S3C2410_PA_MEMCTRL (0x48000000) +#define S3C24XX_SZ_MEMCTRL SZ_1M + +/* UARTs */ +#define S3C_VA_UARTx(uart) (S3C_VA_UART + ((uart * S3C_UART_OFFSET))) + +/* Timers */ +#define S3C2410_PA_TIMER (0x51000000) +#define S3C24XX_SZ_TIMER SZ_1M + +/* Clock and Power management */ +#define S3C24XX_SZ_CLKPWR SZ_1M + +/* USB Device port */ +#define S3C2410_PA_USBDEV (0x52000000) +#define S3C24XX_SZ_USBDEV SZ_1M + +/* Watchdog */ +#define S3C2410_PA_WATCHDOG (0x53000000) +#define S3C24XX_SZ_WATCHDOG SZ_1M + +/* Standard size definitions for peripheral blocks. */ + +#define S3C24XX_SZ_UART 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_GPIO SZ_1M + +/* USB host controller */ +#define S3C2410_PA_USBHOST (0x49000000) + +/* S3C2416/S3C2443/S3C2450 High-Speed USB Gadget */ +#define S3C2416_PA_HSUDC (0x49800000) +#define S3C2416_SZ_HSUDC (SZ_4K) + +/* DMA controller */ +#define S3C2410_PA_DMA (0x4B000000) +#define S3C24XX_SZ_DMA SZ_1M + +/* Clock and Power management */ +#define S3C2410_PA_CLKPWR (0x4C000000) + +/* LCD controller */ +#define S3C2410_PA_LCD (0x4D000000) +#define S3C24XX_SZ_LCD SZ_1M + +/* NAND flash controller */ +#define S3C2410_PA_NAND (0x4E000000) + +/* IIC hardware controller */ +#define S3C2410_PA_IIC (0x54000000) + +/* IIS controller */ +#define S3C2410_PA_IIS (0x55000000) + +/* RTC */ +#define S3C2410_PA_RTC (0x57000000) +#define S3C24XX_SZ_RTC SZ_1M + +/* ADC */ +#define S3C2410_PA_ADC (0x58000000) + +/* SPI */ +#define S3C2410_PA_SPI (0x59000000) + +/* SDI */ +#define S3C2410_PA_SDI (0x5A000000) + +/* CAMIF */ +#define S3C2440_PA_CAMIF (0x4F000000) +#define S3C2440_SZ_CAMIF SZ_1M + +/* AC97 */ + +#define S3C2440_PA_AC97 (0x5B000000) +#define S3C2440_SZ_AC97 SZ_1M + +/* S3C2443/S3C2416 High-speed SD/MMC */ +#define S3C2443_PA_HSMMC (0x4A800000) +#define S3C2416_PA_HSMMC0 (0x4AC00000) + +#define S3C2443_PA_FB (0x4C800000) + +/* S3C2412 memory and IO controls */ +#define S3C2412_PA_SSMC (0x4F000000) + +#define S3C2412_PA_EBI (0x48800000) + +/* physical addresses of all the chip-select areas */ + +#define S3C2410_CS0 (0x00000000) +#define S3C2410_CS1 (0x08000000) +#define S3C2410_CS2 (0x10000000) +#define S3C2410_CS3 (0x18000000) +#define S3C2410_CS4 (0x20000000) +#define S3C2410_CS5 (0x28000000) +#define S3C2410_CS6 (0x30000000) +#define S3C2410_CS7 (0x38000000) + +#define S3C2410_SDRAM_PA (S3C2410_CS6) + +/* Use a single interface for common resources between S3C24XX cpus */ + +#define S3C24XX_PA_IRQ S3C2410_PA_IRQ +#define S3C24XX_PA_MEMCTRL S3C2410_PA_MEMCTRL +#define S3C24XX_PA_DMA S3C2410_PA_DMA +#define S3C24XX_PA_CLKPWR S3C2410_PA_CLKPWR +#define S3C24XX_PA_LCD S3C2410_PA_LCD +#define S3C24XX_PA_TIMER S3C2410_PA_TIMER +#define S3C24XX_PA_USBDEV S3C2410_PA_USBDEV +#define S3C24XX_PA_WATCHDOG S3C2410_PA_WATCHDOG +#define S3C24XX_PA_IIS S3C2410_PA_IIS +#define S3C24XX_PA_RTC S3C2410_PA_RTC +#define S3C24XX_PA_ADC S3C2410_PA_ADC +#define S3C24XX_PA_SPI S3C2410_PA_SPI +#define S3C24XX_PA_SPI1 (S3C2410_PA_SPI + S3C2410_SPI1) +#define S3C24XX_PA_SDI S3C2410_PA_SDI +#define S3C24XX_PA_NAND S3C2410_PA_NAND + +#define S3C_PA_FB S3C2443_PA_FB +#define S3C_PA_IIC S3C2410_PA_IIC +#define S3C_PA_UART S3C24XX_PA_UART +#define S3C_PA_USBHOST S3C2410_PA_USBHOST +#define S3C_PA_HSMMC0 S3C2416_PA_HSMMC0 +#define S3C_PA_HSMMC1 S3C2443_PA_HSMMC +#define S3C_PA_WDT S3C2410_PA_WATCHDOG +#define S3C_PA_NAND S3C24XX_PA_NAND + +#endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/osiris-cpld.h b/arch/arm/mach-s3c24xx/include/mach/osiris-cpld.h new file mode 100644 index 00000000..e9e36b0a --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/osiris-cpld.h @@ -0,0 +1,30 @@ +/* arch/arm/mach-s3c2410/include/mach/osiris-cpld.h + * + * Copyright 2005 Simtec Electronics + * http://www.simtec.co.uk/products/ + * Ben Dooks + * + * OSIRIS - CPLD control constants + * + * 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_OSIRISCPLD_H +#define __ASM_ARCH_OSIRISCPLD_H + +/* CTRL0 - NAND WP control */ + +#define OSIRIS_CTRL0_NANDSEL (0x3) +#define OSIRIS_CTRL0_BOOT_INT (1<<3) +#define OSIRIS_CTRL0_PCMCIA (1<<4) +#define OSIRIS_CTRL0_FIX8 (1<<5) +#define OSIRIS_CTRL0_PCMCIA_nWAIT (1<<6) +#define OSIRIS_CTRL0_PCMCIA_nIOIS16 (1<<7) + +#define OSIRIS_CTRL1_FIX8 (1<<0) + +#define OSIRIS_ID_REVMASK (0x7) + +#endif /* __ASM_ARCH_OSIRISCPLD_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/osiris-map.h b/arch/arm/mach-s3c24xx/include/mach/osiris-map.h new file mode 100644 index 00000000..17380f84 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/osiris-map.h @@ -0,0 +1,42 @@ +/* arch/arm/mach-s3c2410/include/mach/osiris-map.h + * + * Copyright 2005 Simtec Electronics + * http://www.simtec.co.uk/products/ + * Ben Dooks + * + * OSIRIS - 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. +*/ + +/* needs arch/map.h including with this */ + +#ifndef __ASM_ARCH_OSIRISMAP_H +#define __ASM_ARCH_OSIRISMAP_H + +/* start peripherals off after the S3C2410 */ + +#define OSIRIS_IOADDR(x) (S3C2410_ADDR((x) + 0x04000000)) + +#define OSIRIS_PA_CPLD (S3C2410_CS1 | (1<<26)) + +/* we put the CPLD registers next, to get them out of the way */ + +#define OSIRIS_VA_CTRL0 OSIRIS_IOADDR(0x00000000) +#define OSIRIS_PA_CTRL0 (OSIRIS_PA_CPLD) + +#define OSIRIS_VA_CTRL1 OSIRIS_IOADDR(0x00100000) +#define OSIRIS_PA_CTRL1 (OSIRIS_PA_CPLD + (1<<23)) + +#define OSIRIS_VA_CTRL2 OSIRIS_IOADDR(0x00200000) +#define OSIRIS_PA_CTRL2 (OSIRIS_PA_CPLD + (2<<23)) + +#define OSIRIS_VA_CTRL3 OSIRIS_IOADDR(0x00300000) +#define OSIRIS_PA_CTRL3 (OSIRIS_PA_CPLD + (2<<23)) + +#define OSIRIS_VA_IDREG OSIRIS_IOADDR(0x00700000) +#define OSIRIS_PA_IDREG (OSIRIS_PA_CPLD + (7<<23)) + +#endif /* __ASM_ARCH_OSIRISMAP_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/otom-map.h b/arch/arm/mach-s3c24xx/include/mach/otom-map.h new file mode 100644 index 00000000..f9277a52 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/otom-map.h @@ -0,0 +1,30 @@ +/* arch/arm/mach-s3c2410/include/mach/otom-map.h + * + * (c) 2005 Guillaume GOURAT / NexVision + * guillaume.gourat@nexvision.fr + * + * NexVision OTOM board 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. +*/ + +/* needs arch/map.h including with this */ + +/* ok, we've used up to 0x01300000, now we need to find space for the + * peripherals that live in the nGCS[x] areas, which are quite numerous + * in their space. + */ + +#ifndef __ASM_ARCH_OTOMMAP_H +#define __ASM_ARCH_OTOMMAP_H + +#define OTOM_PA_CS8900A_BASE (S3C2410_CS3 + 0x01000000) /* nGCS3 +0x01000000 */ +#define OTOM_VA_CS8900A_BASE S3C2410_ADDR(0x04000000) /* 0xF4000000 */ + +/* physical offset addresses for the peripherals */ + +#define OTOM_PA_FLASH0_BASE (S3C2410_CS0) /* Bank 0 */ + +#endif /* __ASM_ARCH_OTOMMAP_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/pm-core.h b/arch/arm/mach-s3c24xx/include/mach/pm-core.h new file mode 100644 index 00000000..2eef7e6f --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/pm-core.h @@ -0,0 +1,67 @@ +/* linux/arch/arm/mach-s3c2410/include/pm-core.h + * + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * S3C24xx - PM core support for arch/arm/plat-s3c/pm.c + * + * 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. + */ + +static inline void s3c_pm_debug_init_uart(void) +{ + unsigned long tmp = __raw_readl(S3C2410_CLKCON); + + /* re-start uart clocks */ + tmp |= S3C2410_CLKCON_UART0; + tmp |= S3C2410_CLKCON_UART1; + tmp |= S3C2410_CLKCON_UART2; + + __raw_writel(tmp, S3C2410_CLKCON); + udelay(10); +} + +static inline void s3c_pm_arch_prepare_irqs(void) +{ + __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK); + __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK); + + /* ack any outstanding external interrupts before we go to sleep */ + + __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND); + __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND); + __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND); + +} + +static inline void s3c_pm_arch_stop_clocks(void) +{ + __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */ +} + +static void s3c_pm_show_resume_irqs(int start, unsigned long which, + unsigned long mask); + +static inline void s3c_pm_arch_show_resume_irqs(void) +{ + S3C_PMDBG("post sleep: IRQs 0x%08x, 0x%08x\n", + __raw_readl(S3C2410_SRCPND), + __raw_readl(S3C2410_EINTPEND)); + + s3c_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND), + s3c_irqwake_intmask); + + s3c_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND), + s3c_irqwake_eintmask); +} + +static inline void s3c_pm_arch_update_uart(void __iomem *regs, + struct pm_uart_save *save) +{ +} + +static inline void s3c_pm_restored_gpios(void) { } +static inline void samsung_pm_saved_gpios(void) { } diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h new file mode 100644 index 00000000..3415b600 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h @@ -0,0 +1,166 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-clock.h + * + * Copyright (c) 2003-2006 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. + * + * S3C2410 clock register definitions +*/ + +#ifndef __ASM_ARM_REGS_CLOCK +#define __ASM_ARM_REGS_CLOCK + +#define S3C2410_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR) + +#define S3C2410_PLLVAL(_m,_p,_s) ((_m) << 12 | ((_p) << 4) | ((_s))) + +#define S3C2410_LOCKTIME S3C2410_CLKREG(0x00) +#define S3C2410_MPLLCON S3C2410_CLKREG(0x04) +#define S3C2410_UPLLCON S3C2410_CLKREG(0x08) +#define S3C2410_CLKCON S3C2410_CLKREG(0x0C) +#define S3C2410_CLKSLOW S3C2410_CLKREG(0x10) +#define S3C2410_CLKDIVN S3C2410_CLKREG(0x14) + +#define S3C2410_CLKCON_IDLE (1<<2) +#define S3C2410_CLKCON_POWER (1<<3) +#define S3C2410_CLKCON_NAND (1<<4) +#define S3C2410_CLKCON_LCDC (1<<5) +#define S3C2410_CLKCON_USBH (1<<6) +#define S3C2410_CLKCON_USBD (1<<7) +#define S3C2410_CLKCON_PWMT (1<<8) +#define S3C2410_CLKCON_SDI (1<<9) +#define S3C2410_CLKCON_UART0 (1<<10) +#define S3C2410_CLKCON_UART1 (1<<11) +#define S3C2410_CLKCON_UART2 (1<<12) +#define S3C2410_CLKCON_GPIO (1<<13) +#define S3C2410_CLKCON_RTC (1<<14) +#define S3C2410_CLKCON_ADC (1<<15) +#define S3C2410_CLKCON_IIC (1<<16) +#define S3C2410_CLKCON_IIS (1<<17) +#define S3C2410_CLKCON_SPI (1<<18) + +/* DCLKCON register addresses in gpio.h */ + +#define S3C2410_DCLKCON_DCLK0EN (1<<0) +#define S3C2410_DCLKCON_DCLK0_PCLK (0<<1) +#define S3C2410_DCLKCON_DCLK0_UCLK (1<<1) +#define S3C2410_DCLKCON_DCLK0_DIV(x) (((x) - 1 )<<4) +#define S3C2410_DCLKCON_DCLK0_CMP(x) (((x) - 1 )<<8) +#define S3C2410_DCLKCON_DCLK0_DIV_MASK ((0xf)<<4) +#define S3C2410_DCLKCON_DCLK0_CMP_MASK ((0xf)<<8) + +#define S3C2410_DCLKCON_DCLK1EN (1<<16) +#define S3C2410_DCLKCON_DCLK1_PCLK (0<<17) +#define S3C2410_DCLKCON_DCLK1_UCLK (1<<17) +#define S3C2410_DCLKCON_DCLK1_DIV(x) (((x) - 1) <<20) +#define S3C2410_DCLKCON_DCLK1_CMP(x) (((x) - 1) <<24) +#define S3C2410_DCLKCON_DCLK1_DIV_MASK ((0xf) <<20) +#define S3C2410_DCLKCON_DCLK1_CMP_MASK ((0xf) <<24) + +#define S3C2410_CLKDIVN_PDIVN (1<<0) +#define S3C2410_CLKDIVN_HDIVN (1<<1) + +#define S3C2410_CLKSLOW_UCLK_OFF (1<<7) +#define S3C2410_CLKSLOW_MPLL_OFF (1<<5) +#define S3C2410_CLKSLOW_SLOW (1<<4) +#define S3C2410_CLKSLOW_SLOWVAL(x) (x) +#define S3C2410_CLKSLOW_GET_SLOWVAL(x) ((x) & 7) + +#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442) + +/* extra registers */ +#define S3C2440_CAMDIVN S3C2410_CLKREG(0x18) + +#define S3C2440_CLKCON_CAMERA (1<<19) +#define S3C2440_CLKCON_AC97 (1<<20) + +#define S3C2440_CLKDIVN_PDIVN (1<<0) +#define S3C2440_CLKDIVN_HDIVN_MASK (3<<1) +#define S3C2440_CLKDIVN_HDIVN_1 (0<<1) +#define S3C2440_CLKDIVN_HDIVN_2 (1<<1) +#define S3C2440_CLKDIVN_HDIVN_4_8 (2<<1) +#define S3C2440_CLKDIVN_HDIVN_3_6 (3<<1) +#define S3C2440_CLKDIVN_UCLK (1<<3) + +#define S3C2440_CAMDIVN_CAMCLK_MASK (0xf<<0) +#define S3C2440_CAMDIVN_CAMCLK_SEL (1<<4) +#define S3C2440_CAMDIVN_HCLK3_HALF (1<<8) +#define S3C2440_CAMDIVN_HCLK4_HALF (1<<9) +#define S3C2440_CAMDIVN_DVSEN (1<<12) + +#define S3C2442_CAMDIVN_CAMCLK_DIV3 (1<<5) + +#endif /* CONFIG_CPU_S3C2440 or CONFIG_CPU_S3C2442 */ + +#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) + +#define S3C2412_OSCSET S3C2410_CLKREG(0x18) +#define S3C2412_CLKSRC S3C2410_CLKREG(0x1C) + +#define S3C2412_PLLCON_OFF (1<<20) + +#define S3C2412_CLKDIVN_PDIVN (1<<2) +#define S3C2412_CLKDIVN_HDIVN_MASK (3<<0) +#define S3C2412_CLKDIVN_ARMDIVN (1<<3) +#define S3C2412_CLKDIVN_DVSEN (1<<4) +#define S3C2412_CLKDIVN_HALFHCLK (1<<5) +#define S3C2412_CLKDIVN_USB48DIV (1<<6) +#define S3C2412_CLKDIVN_UARTDIV_MASK (15<<8) +#define S3C2412_CLKDIVN_UARTDIV_SHIFT (8) +#define S3C2412_CLKDIVN_I2SDIV_MASK (15<<12) +#define S3C2412_CLKDIVN_I2SDIV_SHIFT (12) +#define S3C2412_CLKDIVN_CAMDIV_MASK (15<<16) +#define S3C2412_CLKDIVN_CAMDIV_SHIFT (16) + +#define S3C2412_CLKCON_WDT (1<<28) +#define S3C2412_CLKCON_SPI (1<<27) +#define S3C2412_CLKCON_IIS (1<<26) +#define S3C2412_CLKCON_IIC (1<<25) +#define S3C2412_CLKCON_ADC (1<<24) +#define S3C2412_CLKCON_RTC (1<<23) +#define S3C2412_CLKCON_GPIO (1<<22) +#define S3C2412_CLKCON_UART2 (1<<21) +#define S3C2412_CLKCON_UART1 (1<<20) +#define S3C2412_CLKCON_UART0 (1<<19) +#define S3C2412_CLKCON_SDI (1<<18) +#define S3C2412_CLKCON_PWMT (1<<17) +#define S3C2412_CLKCON_USBD (1<<16) +#define S3C2412_CLKCON_CAMCLK (1<<15) +#define S3C2412_CLKCON_UARTCLK (1<<14) +/* missing 13 */ +#define S3C2412_CLKCON_USB_HOST48 (1<<12) +#define S3C2412_CLKCON_USB_DEV48 (1<<11) +#define S3C2412_CLKCON_HCLKdiv2 (1<<10) +#define S3C2412_CLKCON_HCLKx2 (1<<9) +#define S3C2412_CLKCON_SDRAM (1<<8) +/* missing 7 */ +#define S3C2412_CLKCON_USBH S3C2410_CLKCON_USBH +#define S3C2412_CLKCON_LCDC S3C2410_CLKCON_LCDC +#define S3C2412_CLKCON_NAND S3C2410_CLKCON_NAND +#define S3C2412_CLKCON_DMA3 (1<<3) +#define S3C2412_CLKCON_DMA2 (1<<2) +#define S3C2412_CLKCON_DMA1 (1<<1) +#define S3C2412_CLKCON_DMA0 (1<<0) + +/* clock sourec controls */ + +#define S3C2412_CLKSRC_EXTCLKDIV_MASK (7 << 0) +#define S3C2412_CLKSRC_EXTCLKDIV_SHIFT (0) +#define S3C2412_CLKSRC_MDIVCLK_EXTCLKDIV (1<<3) +#define S3C2412_CLKSRC_MSYSCLK_MPLL (1<<4) +#define S3C2412_CLKSRC_USYSCLK_UPLL (1<<5) +#define S3C2412_CLKSRC_UARTCLK_MPLL (1<<8) +#define S3C2412_CLKSRC_I2SCLK_MPLL (1<<9) +#define S3C2412_CLKSRC_USBCLK_HCLK (1<<10) +#define S3C2412_CLKSRC_CAMCLK_HCLK (1<<11) +#define S3C2412_CLKSRC_UREFCLK_EXTCLK (1<<12) +#define S3C2412_CLKSRC_EREFCLK_EXTCLK (1<<14) + +#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */ + +#define S3C2416_CLKDIV2 S3C2410_CLKREG(0x28) + +#endif /* __ASM_ARM_REGS_CLOCK */ diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-dsc.h b/arch/arm/mach-s3c24xx/include/mach/regs-dsc.h new file mode 100644 index 00000000..98fd4a05 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-dsc.h @@ -0,0 +1,220 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-dsc.h + * + * Copyright (c) 2004 Simtec Electronics + * 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. + * + * S3C2440/S3C2412 Signal Drive Strength Control +*/ + + +#ifndef __ASM_ARCH_REGS_DSC_H +#define __ASM_ARCH_REGS_DSC_H "2440-dsc" + +#if defined(CONFIG_CPU_S3C2412) +#define S3C2412_DSC0 S3C2410_GPIOREG(0xdc) +#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0) +#endif + +#if defined(CONFIG_CPU_S3C2416) +#define S3C2416_DSC0 S3C2410_GPIOREG(0xc0) +#define S3C2416_DSC1 S3C2410_GPIOREG(0xc4) +#define S3C2416_DSC2 S3C2410_GPIOREG(0xc8) +#define S3C2416_DSC3 S3C2410_GPIOREG(0x110) + +#define S3C2416_SELECT_DSC0 (0 << 30) +#define S3C2416_SELECT_DSC1 (1 << 30) +#define S3C2416_SELECT_DSC2 (2 << 30) +#define S3C2416_SELECT_DSC3 (3 << 30) + +#define S3C2416_DSC_GETSHIFT(x) (x & 30) + +#define S3C2416_DSC0_CF (S3C2416_SELECT_DSC0 | 28) +#define S3C2416_DSC0_CF_5mA (0 << 28) +#define S3C2416_DSC0_CF_10mA (1 << 28) +#define S3C2416_DSC0_CF_15mA (2 << 28) +#define S3C2416_DSC0_CF_21mA (3 << 28) +#define S3C2416_DSC0_CF_MASK (3 << 28) + +#define S3C2416_DSC0_nRBE (S3C2416_SELECT_DSC0 | 26) +#define S3C2416_DSC0_nRBE_5mA (0 << 26) +#define S3C2416_DSC0_nRBE_10mA (1 << 26) +#define S3C2416_DSC0_nRBE_15mA (2 << 26) +#define S3C2416_DSC0_nRBE_21mA (3 << 26) +#define S3C2416_DSC0_nRBE_MASK (3 << 26) + +#define S3C2416_DSC0_nROE (S3C2416_SELECT_DSC0 | 24) +#define S3C2416_DSC0_nROE_5mA (0 << 24) +#define S3C2416_DSC0_nROE_10mA (1 << 24) +#define S3C2416_DSC0_nROE_15mA (2 << 24) +#define S3C2416_DSC0_nROE_21mA (3 << 24) +#define S3C2416_DSC0_nROE_MASK (3 << 24) + +#endif + +#if defined(CONFIG_CPU_S3C244X) + +#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4) +#define S3C2440_DSC1 S3C2410_GPIOREG(0xc8) + +#define S3C2440_SELECT_DSC0 (0) +#define S3C2440_SELECT_DSC1 (1<<31) + +#define S3C2440_DSC_GETSHIFT(x) ((x) & 31) + +#define S3C2440_DSC0_DISABLE (1<<31) + +#define S3C2440_DSC0_ADDR (S3C2440_SELECT_DSC0 | 8) +#define S3C2440_DSC0_ADDR_12mA (0<<8) +#define S3C2440_DSC0_ADDR_10mA (1<<8) +#define S3C2440_DSC0_ADDR_8mA (2<<8) +#define S3C2440_DSC0_ADDR_6mA (3<<8) +#define S3C2440_DSC0_ADDR_MASK (3<<8) + +/* D24..D31 */ +#define S3C2440_DSC0_DATA3 (S3C2440_SELECT_DSC0 | 6) +#define S3C2440_DSC0_DATA3_12mA (0<<6) +#define S3C2440_DSC0_DATA3_10mA (1<<6) +#define S3C2440_DSC0_DATA3_8mA (2<<6) +#define S3C2440_DSC0_DATA3_6mA (3<<6) +#define S3C2440_DSC0_DATA3_MASK (3<<6) + +/* D16..D23 */ +#define S3C2440_DSC0_DATA2 (S3C2440_SELECT_DSC0 | 4) +#define S3C2440_DSC0_DATA2_12mA (0<<4) +#define S3C2440_DSC0_DATA2_10mA (1<<4) +#define S3C2440_DSC0_DATA2_8mA (2<<4) +#define S3C2440_DSC0_DATA2_6mA (3<<4) +#define S3C2440_DSC0_DATA2_MASK (3<<4) + +/* D8..D15 */ +#define S3C2440_DSC0_DATA1 (S3C2440_SELECT_DSC0 | 2) +#define S3C2440_DSC0_DATA1_12mA (0<<2) +#define S3C2440_DSC0_DATA1_10mA (1<<2) +#define S3C2440_DSC0_DATA1_8mA (2<<2) +#define S3C2440_DSC0_DATA1_6mA (3<<2) +#define S3C2440_DSC0_DATA1_MASK (3<<2) + +/* D0..D7 */ +#define S3C2440_DSC0_DATA0 (S3C2440_SELECT_DSC0 | 0) +#define S3C2440_DSC0_DATA0_12mA (0<<0) +#define S3C2440_DSC0_DATA0_10mA (1<<0) +#define S3C2440_DSC0_DATA0_8mA (2<<0) +#define S3C2440_DSC0_DATA0_6mA (3<<0) +#define S3C2440_DSC0_DATA0_MASK (3<<0) + +#define S3C2440_DSC1_SCK1 (S3C2440_SELECT_DSC1 | 28) +#define S3C2440_DSC1_SCK1_12mA (0<<28) +#define S3C2440_DSC1_SCK1_10mA (1<<28) +#define S3C2440_DSC1_SCK1_8mA (2<<28) +#define S3C2440_DSC1_SCK1_6mA (3<<28) +#define S3C2440_DSC1_SCK1_MASK (3<<28) + +#define S3C2440_DSC1_SCK0 (S3C2440_SELECT_DSC1 | 26) +#define S3C2440_DSC1_SCK0_12mA (0<<26) +#define S3C2440_DSC1_SCK0_10mA (1<<26) +#define S3C2440_DSC1_SCK0_8mA (2<<26) +#define S3C2440_DSC1_SCK0_6mA (3<<26) +#define S3C2440_DSC1_SCK0_MASK (3<<26) + +#define S3C2440_DSC1_SCKE (S3C2440_SELECT_DSC1 | 24) +#define S3C2440_DSC1_SCKE_10mA (0<<24) +#define S3C2440_DSC1_SCKE_8mA (1<<24) +#define S3C2440_DSC1_SCKE_6mA (2<<24) +#define S3C2440_DSC1_SCKE_4mA (3<<24) +#define S3C2440_DSC1_SCKE_MASK (3<<24) + +/* SDRAM nRAS/nCAS */ +#define S3C2440_DSC1_SDR (S3C2440_SELECT_DSC1 | 22) +#define S3C2440_DSC1_SDR_10mA (0<<22) +#define S3C2440_DSC1_SDR_8mA (1<<22) +#define S3C2440_DSC1_SDR_6mA (2<<22) +#define S3C2440_DSC1_SDR_4mA (3<<22) +#define S3C2440_DSC1_SDR_MASK (3<<22) + +/* NAND Flash Controller */ +#define S3C2440_DSC1_NFC (S3C2440_SELECT_DSC1 | 20) +#define S3C2440_DSC1_NFC_10mA (0<<20) +#define S3C2440_DSC1_NFC_8mA (1<<20) +#define S3C2440_DSC1_NFC_6mA (2<<20) +#define S3C2440_DSC1_NFC_4mA (3<<20) +#define S3C2440_DSC1_NFC_MASK (3<<20) + +/* nBE[0..3] */ +#define S3C2440_DSC1_nBE (S3C2440_SELECT_DSC1 | 18) +#define S3C2440_DSC1_nBE_10mA (0<<18) +#define S3C2440_DSC1_nBE_8mA (1<<18) +#define S3C2440_DSC1_nBE_6mA (2<<18) +#define S3C2440_DSC1_nBE_4mA (3<<18) +#define S3C2440_DSC1_nBE_MASK (3<<18) + +#define S3C2440_DSC1_WOE (S3C2440_SELECT_DSC1 | 16) +#define S3C2440_DSC1_WOE_10mA (0<<16) +#define S3C2440_DSC1_WOE_8mA (1<<16) +#define S3C2440_DSC1_WOE_6mA (2<<16) +#define S3C2440_DSC1_WOE_4mA (3<<16) +#define S3C2440_DSC1_WOE_MASK (3<<16) + +#define S3C2440_DSC1_CS7 (S3C2440_SELECT_DSC1 | 14) +#define S3C2440_DSC1_CS7_10mA (0<<14) +#define S3C2440_DSC1_CS7_8mA (1<<14) +#define S3C2440_DSC1_CS7_6mA (2<<14) +#define S3C2440_DSC1_CS7_4mA (3<<14) +#define S3C2440_DSC1_CS7_MASK (3<<14) + +#define S3C2440_DSC1_CS6 (S3C2440_SELECT_DSC1 | 12) +#define S3C2440_DSC1_CS6_10mA (0<<12) +#define S3C2440_DSC1_CS6_8mA (1<<12) +#define S3C2440_DSC1_CS6_6mA (2<<12) +#define S3C2440_DSC1_CS6_4mA (3<<12) +#define S3C2440_DSC1_CS6_MASK (3<<12) + +#define S3C2440_DSC1_CS5 (S3C2440_SELECT_DSC1 | 10) +#define S3C2440_DSC1_CS5_10mA (0<<10) +#define S3C2440_DSC1_CS5_8mA (1<<10) +#define S3C2440_DSC1_CS5_6mA (2<<10) +#define S3C2440_DSC1_CS5_4mA (3<<10) +#define S3C2440_DSC1_CS5_MASK (3<<10) + +#define S3C2440_DSC1_CS4 (S3C2440_SELECT_DSC1 | 8) +#define S3C2440_DSC1_CS4_10mA (0<<8) +#define S3C2440_DSC1_CS4_8mA (1<<8) +#define S3C2440_DSC1_CS4_6mA (2<<8) +#define S3C2440_DSC1_CS4_4mA (3<<8) +#define S3C2440_DSC1_CS4_MASK (3<<8) + +#define S3C2440_DSC1_CS3 (S3C2440_SELECT_DSC1 | 6) +#define S3C2440_DSC1_CS3_10mA (0<<6) +#define S3C2440_DSC1_CS3_8mA (1<<6) +#define S3C2440_DSC1_CS3_6mA (2<<6) +#define S3C2440_DSC1_CS3_4mA (3<<6) +#define S3C2440_DSC1_CS3_MASK (3<<6) + +#define S3C2440_DSC1_CS2 (S3C2440_SELECT_DSC1 | 4) +#define S3C2440_DSC1_CS2_10mA (0<<4) +#define S3C2440_DSC1_CS2_8mA (1<<4) +#define S3C2440_DSC1_CS2_6mA (2<<4) +#define S3C2440_DSC1_CS2_4mA (3<<4) +#define S3C2440_DSC1_CS2_MASK (3<<4) + +#define S3C2440_DSC1_CS1 (S3C2440_SELECT_DSC1 | 2) +#define S3C2440_DSC1_CS1_10mA (0<<2) +#define S3C2440_DSC1_CS1_8mA (1<<2) +#define S3C2440_DSC1_CS1_6mA (2<<2) +#define S3C2440_DSC1_CS1_4mA (3<<2) +#define S3C2440_DSC1_CS1_MASK (3<<2) + +#define S3C2440_DSC1_CS0 (S3C2440_SELECT_DSC1 | 0) +#define S3C2440_DSC1_CS0_10mA (0<<0) +#define S3C2440_DSC1_CS0_8mA (1<<0) +#define S3C2440_DSC1_CS0_6mA (2<<0) +#define S3C2440_DSC1_CS0_4mA (3<<0) +#define S3C2440_DSC1_CS0_MASK (3<<0) + +#endif /* CONFIG_CPU_S3C2440 */ + +#endif /* __ASM_ARCH_REGS_DSC_H */ + diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h b/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h new file mode 100644 index 00000000..cac1ad6b --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h @@ -0,0 +1,602 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-gpio.h + * + * Copyright (c) 2003-2004 Simtec Electronics + * 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. + * + * S3C2410 GPIO register definitions +*/ + + +#ifndef __ASM_ARCH_REGS_GPIO_H +#define __ASM_ARCH_REGS_GPIO_H + +#include + +#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80) + +/* general configuration options */ + +#define S3C2410_GPIO_LEAVE (0xFFFFFFFF) +#define S3C2410_GPIO_INPUT (0xFFFFFFF0) /* not available on A */ +#define S3C2410_GPIO_OUTPUT (0xFFFFFFF1) +#define S3C2410_GPIO_IRQ (0xFFFFFFF2) /* not available for all */ +#define S3C2410_GPIO_SFN2 (0xFFFFFFF2) /* bank A => addr/cs/nand */ +#define S3C2410_GPIO_SFN3 (0xFFFFFFF3) /* not available on A */ + +/* register address for the GPIO registers. + * S3C24XX_GPIOREG2 is for the second set of registers in the + * GPIO which move between s3c2410 and s3c2412 type systems */ + +#define S3C2410_GPIOREG(x) ((x) + S3C24XX_VA_GPIO) +#define S3C24XX_GPIOREG2(x) ((x) + S3C24XX_VA_GPIO2) + + +/* configure GPIO ports A..G */ + +/* port A - S3C2410: 22bits, zero in bit X makes pin X output + * 1 makes port special function, this is default +*/ +#define S3C2410_GPACON S3C2410_GPIOREG(0x00) +#define S3C2410_GPADAT S3C2410_GPIOREG(0x04) + +#define S3C2410_GPA0_ADDR0 (1<<0) +#define S3C2410_GPA1_ADDR16 (1<<1) +#define S3C2410_GPA2_ADDR17 (1<<2) +#define S3C2410_GPA3_ADDR18 (1<<3) +#define S3C2410_GPA4_ADDR19 (1<<4) +#define S3C2410_GPA5_ADDR20 (1<<5) +#define S3C2410_GPA6_ADDR21 (1<<6) +#define S3C2410_GPA7_ADDR22 (1<<7) +#define S3C2410_GPA8_ADDR23 (1<<8) +#define S3C2410_GPA9_ADDR24 (1<<9) +#define S3C2410_GPA10_ADDR25 (1<<10) +#define S3C2410_GPA11_ADDR26 (1<<11) +#define S3C2410_GPA12_nGCS1 (1<<12) +#define S3C2410_GPA13_nGCS2 (1<<13) +#define S3C2410_GPA14_nGCS3 (1<<14) +#define S3C2410_GPA15_nGCS4 (1<<15) +#define S3C2410_GPA16_nGCS5 (1<<16) +#define S3C2410_GPA17_CLE (1<<17) +#define S3C2410_GPA18_ALE (1<<18) +#define S3C2410_GPA19_nFWE (1<<19) +#define S3C2410_GPA20_nFRE (1<<20) +#define S3C2410_GPA21_nRSTOUT (1<<21) +#define S3C2410_GPA22_nFCE (1<<22) + +/* 0x08 and 0x0c are reserved on S3C2410 */ + +/* S3C2410: + * GPB is 10 IO pins, each configured by 2 bits each in GPBCON. + * 00 = input, 01 = output, 10=special function, 11=reserved + + * bit 0,1 = pin 0, 2,3= pin 1... + * + * CPBUP = pull up resistor control, 1=disabled, 0=enabled +*/ + +#define S3C2410_GPBCON S3C2410_GPIOREG(0x10) +#define S3C2410_GPBDAT S3C2410_GPIOREG(0x14) +#define S3C2410_GPBUP S3C2410_GPIOREG(0x18) + +/* no i/o pin in port b can have value 3 (unless it is a s3c2443) ! */ + +#define S3C2410_GPB0_TOUT0 (0x02 << 0) + +#define S3C2410_GPB1_TOUT1 (0x02 << 2) + +#define S3C2410_GPB2_TOUT2 (0x02 << 4) + +#define S3C2410_GPB3_TOUT3 (0x02 << 6) + +#define S3C2410_GPB4_TCLK0 (0x02 << 8) +#define S3C2410_GPB4_MASK (0x03 << 8) + +#define S3C2410_GPB5_nXBACK (0x02 << 10) +#define S3C2443_GPB5_XBACK (0x03 << 10) + +#define S3C2410_GPB6_nXBREQ (0x02 << 12) +#define S3C2443_GPB6_XBREQ (0x03 << 12) + +#define S3C2410_GPB7_nXDACK1 (0x02 << 14) +#define S3C2443_GPB7_XDACK1 (0x03 << 14) + +#define S3C2410_GPB8_nXDREQ1 (0x02 << 16) + +#define S3C2410_GPB9_nXDACK0 (0x02 << 18) +#define S3C2443_GPB9_XDACK0 (0x03 << 18) + +#define S3C2410_GPB10_nXDRE0 (0x02 << 20) +#define S3C2443_GPB10_XDREQ0 (0x03 << 20) + +#define S3C2410_GPB_PUPDIS(x) (1<<(x)) + +/* Port C consits of 16 GPIO/Special function + * + * almost identical setup to port b, but the special functions are mostly + * to do with the video system's sync/etc. +*/ + +#define S3C2410_GPCCON S3C2410_GPIOREG(0x20) +#define S3C2410_GPCDAT S3C2410_GPIOREG(0x24) +#define S3C2410_GPCUP S3C2410_GPIOREG(0x28) +#define S3C2410_GPC0_LEND (0x02 << 0) +#define S3C2410_GPC1_VCLK (0x02 << 2) +#define S3C2410_GPC2_VLINE (0x02 << 4) +#define S3C2410_GPC3_VFRAME (0x02 << 6) +#define S3C2410_GPC4_VM (0x02 << 8) +#define S3C2410_GPC5_LCDVF0 (0x02 << 10) +#define S3C2410_GPC6_LCDVF1 (0x02 << 12) +#define S3C2410_GPC7_LCDVF2 (0x02 << 14) +#define S3C2410_GPC8_VD0 (0x02 << 16) +#define S3C2410_GPC9_VD1 (0x02 << 18) +#define S3C2410_GPC10_VD2 (0x02 << 20) +#define S3C2410_GPC11_VD3 (0x02 << 22) +#define S3C2410_GPC12_VD4 (0x02 << 24) +#define S3C2410_GPC13_VD5 (0x02 << 26) +#define S3C2410_GPC14_VD6 (0x02 << 28) +#define S3C2410_GPC15_VD7 (0x02 << 30) +#define S3C2410_GPC_PUPDIS(x) (1<<(x)) + +/* + * S3C2410: Port D consists of 16 GPIO/Special function + * + * almost identical setup to port b, but the special functions are mostly + * to do with the video system's data. + * + * almost identical setup to port c +*/ + +#define S3C2410_GPDCON S3C2410_GPIOREG(0x30) +#define S3C2410_GPDDAT S3C2410_GPIOREG(0x34) +#define S3C2410_GPDUP S3C2410_GPIOREG(0x38) + +#define S3C2410_GPD0_VD8 (0x02 << 0) +#define S3C2442_GPD0_nSPICS1 (0x03 << 0) + +#define S3C2410_GPD1_VD9 (0x02 << 2) +#define S3C2442_GPD1_SPICLK1 (0x03 << 2) + +#define S3C2410_GPD2_VD10 (0x02 << 4) + +#define S3C2410_GPD3_VD11 (0x02 << 6) + +#define S3C2410_GPD4_VD12 (0x02 << 8) + +#define S3C2410_GPD5_VD13 (0x02 << 10) + +#define S3C2410_GPD6_VD14 (0x02 << 12) + +#define S3C2410_GPD7_VD15 (0x02 << 14) + +#define S3C2410_GPD8_VD16 (0x02 << 16) +#define S3C2440_GPD8_SPIMISO1 (0x03 << 16) + +#define S3C2410_GPD9_VD17 (0x02 << 18) +#define S3C2440_GPD9_SPIMOSI1 (0x03 << 18) + +#define S3C2410_GPD10_VD18 (0x02 << 20) +#define S3C2440_GPD10_SPICLK1 (0x03 << 20) + +#define S3C2410_GPD11_VD19 (0x02 << 22) + +#define S3C2410_GPD12_VD20 (0x02 << 24) + +#define S3C2410_GPD13_VD21 (0x02 << 26) + +#define S3C2410_GPD14_VD22 (0x02 << 28) +#define S3C2410_GPD14_nSS1 (0x03 << 28) + +#define S3C2410_GPD15_VD23 (0x02 << 30) +#define S3C2410_GPD15_nSS0 (0x03 << 30) + +#define S3C2410_GPD_PUPDIS(x) (1<<(x)) + +/* S3C2410: + * Port E consists of 16 GPIO/Special function + * + * again, the same as port B, but dealing with I2S, SDI, and + * more miscellaneous functions + * + * GPIO / interrupt inputs +*/ + +#define S3C2410_GPECON S3C2410_GPIOREG(0x40) +#define S3C2410_GPEDAT S3C2410_GPIOREG(0x44) +#define S3C2410_GPEUP S3C2410_GPIOREG(0x48) + +#define S3C2410_GPE0_I2SLRCK (0x02 << 0) +#define S3C2443_GPE0_AC_nRESET (0x03 << 0) +#define S3C2410_GPE0_MASK (0x03 << 0) + +#define S3C2410_GPE1_I2SSCLK (0x02 << 2) +#define S3C2443_GPE1_AC_SYNC (0x03 << 2) +#define S3C2410_GPE1_MASK (0x03 << 2) + +#define S3C2410_GPE2_CDCLK (0x02 << 4) +#define S3C2443_GPE2_AC_BITCLK (0x03 << 4) + +#define S3C2410_GPE3_I2SSDI (0x02 << 6) +#define S3C2443_GPE3_AC_SDI (0x03 << 6) +#define S3C2410_GPE3_nSS0 (0x03 << 6) +#define S3C2410_GPE3_MASK (0x03 << 6) + +#define S3C2410_GPE4_I2SSDO (0x02 << 8) +#define S3C2443_GPE4_AC_SDO (0x03 << 8) +#define S3C2410_GPE4_I2SSDI (0x03 << 8) +#define S3C2410_GPE4_MASK (0x03 << 8) + +#define S3C2410_GPE5_SDCLK (0x02 << 10) +#define S3C2443_GPE5_SD1_CLK (0x02 << 10) +#define S3C2443_GPE5_AC_BITCLK (0x03 << 10) + +#define S3C2410_GPE6_SDCMD (0x02 << 12) +#define S3C2443_GPE6_SD1_CMD (0x02 << 12) +#define S3C2443_GPE6_AC_SDI (0x03 << 12) + +#define S3C2410_GPE7_SDDAT0 (0x02 << 14) +#define S3C2443_GPE5_SD1_DAT0 (0x02 << 14) +#define S3C2443_GPE7_AC_SDO (0x03 << 14) + +#define S3C2410_GPE8_SDDAT1 (0x02 << 16) +#define S3C2443_GPE8_SD1_DAT1 (0x02 << 16) +#define S3C2443_GPE8_AC_SYNC (0x03 << 16) + +#define S3C2410_GPE9_SDDAT2 (0x02 << 18) +#define S3C2443_GPE9_SD1_DAT2 (0x02 << 18) +#define S3C2443_GPE9_AC_nRESET (0x03 << 18) + +#define S3C2410_GPE10_SDDAT3 (0x02 << 20) +#define S3C2443_GPE10_SD1_DAT3 (0x02 << 20) + +#define S3C2410_GPE11_SPIMISO0 (0x02 << 22) + +#define S3C2410_GPE12_SPIMOSI0 (0x02 << 24) + +#define S3C2410_GPE13_SPICLK0 (0x02 << 26) + +#define S3C2410_GPE14_IICSCL (0x02 << 28) +#define S3C2410_GPE14_MASK (0x03 << 28) + +#define S3C2410_GPE15_IICSDA (0x02 << 30) +#define S3C2410_GPE15_MASK (0x03 << 30) + +#define S3C2440_GPE0_ACSYNC (0x03 << 0) +#define S3C2440_GPE1_ACBITCLK (0x03 << 2) +#define S3C2440_GPE2_ACRESET (0x03 << 4) +#define S3C2440_GPE3_ACIN (0x03 << 6) +#define S3C2440_GPE4_ACOUT (0x03 << 8) + +#define S3C2410_GPE_PUPDIS(x) (1<<(x)) + +/* S3C2410: + * Port F consists of 8 GPIO/Special function + * + * GPIO / interrupt inputs + * + * GPFCON has 2 bits for each of the input pins on port F + * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 undefined + * + * pull up works like all other ports. + * + * GPIO/serial/misc pins +*/ + +#define S3C2410_GPFCON S3C2410_GPIOREG(0x50) +#define S3C2410_GPFDAT S3C2410_GPIOREG(0x54) +#define S3C2410_GPFUP S3C2410_GPIOREG(0x58) + +#define S3C2410_GPF0_EINT0 (0x02 << 0) +#define S3C2410_GPF1_EINT1 (0x02 << 2) +#define S3C2410_GPF2_EINT2 (0x02 << 4) +#define S3C2410_GPF3_EINT3 (0x02 << 6) +#define S3C2410_GPF4_EINT4 (0x02 << 8) +#define S3C2410_GPF5_EINT5 (0x02 << 10) +#define S3C2410_GPF6_EINT6 (0x02 << 12) +#define S3C2410_GPF7_EINT7 (0x02 << 14) +#define S3C2410_GPF_PUPDIS(x) (1<<(x)) + +/* S3C2410: + * Port G consists of 8 GPIO/IRQ/Special function + * + * GPGCON has 2 bits for each of the input pins on port F + * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func + * + * pull up works like all other ports. +*/ + +#define S3C2410_GPGCON S3C2410_GPIOREG(0x60) +#define S3C2410_GPGDAT S3C2410_GPIOREG(0x64) +#define S3C2410_GPGUP S3C2410_GPIOREG(0x68) + +#define S3C2410_GPG0_EINT8 (0x02 << 0) + +#define S3C2410_GPG1_EINT9 (0x02 << 2) + +#define S3C2410_GPG2_EINT10 (0x02 << 4) +#define S3C2410_GPG2_nSS0 (0x03 << 4) + +#define S3C2410_GPG3_EINT11 (0x02 << 6) +#define S3C2410_GPG3_nSS1 (0x03 << 6) + +#define S3C2410_GPG4_EINT12 (0x02 << 8) +#define S3C2410_GPG4_LCDPWREN (0x03 << 8) +#define S3C2443_GPG4_LCDPWRDN (0x03 << 8) + +#define S3C2410_GPG5_EINT13 (0x02 << 10) +#define S3C2410_GPG5_SPIMISO1 (0x03 << 10) /* not s3c2443 */ + +#define S3C2410_GPG6_EINT14 (0x02 << 12) +#define S3C2410_GPG6_SPIMOSI1 (0x03 << 12) + +#define S3C2410_GPG7_EINT15 (0x02 << 14) +#define S3C2410_GPG7_SPICLK1 (0x03 << 14) + +#define S3C2410_GPG8_EINT16 (0x02 << 16) + +#define S3C2410_GPG9_EINT17 (0x02 << 18) + +#define S3C2410_GPG10_EINT18 (0x02 << 20) + +#define S3C2410_GPG11_EINT19 (0x02 << 22) +#define S3C2410_GPG11_TCLK1 (0x03 << 22) +#define S3C2443_GPG11_CF_nIREQ (0x03 << 22) + +#define S3C2410_GPG12_EINT20 (0x02 << 24) +#define S3C2410_GPG12_XMON (0x03 << 24) +#define S3C2442_GPG12_nSPICS0 (0x03 << 24) +#define S3C2443_GPG12_nINPACK (0x03 << 24) + +#define S3C2410_GPG13_EINT21 (0x02 << 26) +#define S3C2410_GPG13_nXPON (0x03 << 26) +#define S3C2443_GPG13_CF_nREG (0x03 << 26) + +#define S3C2410_GPG14_EINT22 (0x02 << 28) +#define S3C2410_GPG14_YMON (0x03 << 28) +#define S3C2443_GPG14_CF_RESET (0x03 << 28) + +#define S3C2410_GPG15_EINT23 (0x02 << 30) +#define S3C2410_GPG15_nYPON (0x03 << 30) +#define S3C2443_GPG15_CF_PWR (0x03 << 30) + +#define S3C2410_GPG_PUPDIS(x) (1<<(x)) + +/* Port H consists of11 GPIO/serial/Misc pins + * + * GPGCON has 2 bits for each of the input pins on port F + * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func + * + * pull up works like all other ports. +*/ + +#define S3C2410_GPHCON S3C2410_GPIOREG(0x70) +#define S3C2410_GPHDAT S3C2410_GPIOREG(0x74) +#define S3C2410_GPHUP S3C2410_GPIOREG(0x78) + +#define S3C2410_GPH0_nCTS0 (0x02 << 0) +#define S3C2416_GPH0_TXD0 (0x02 << 0) + +#define S3C2410_GPH1_nRTS0 (0x02 << 2) +#define S3C2416_GPH1_RXD0 (0x02 << 2) + +#define S3C2410_GPH2_TXD0 (0x02 << 4) +#define S3C2416_GPH2_TXD1 (0x02 << 4) + +#define S3C2410_GPH3_RXD0 (0x02 << 6) +#define S3C2416_GPH3_RXD1 (0x02 << 6) + +#define S3C2410_GPH4_TXD1 (0x02 << 8) +#define S3C2416_GPH4_TXD2 (0x02 << 8) + +#define S3C2410_GPH5_RXD1 (0x02 << 10) +#define S3C2416_GPH5_RXD2 (0x02 << 10) + +#define S3C2410_GPH6_TXD2 (0x02 << 12) +#define S3C2416_GPH6_TXD3 (0x02 << 12) +#define S3C2410_GPH6_nRTS1 (0x03 << 12) +#define S3C2416_GPH6_nRTS2 (0x03 << 12) + +#define S3C2410_GPH7_RXD2 (0x02 << 14) +#define S3C2416_GPH7_RXD3 (0x02 << 14) +#define S3C2410_GPH7_nCTS1 (0x03 << 14) +#define S3C2416_GPH7_nCTS2 (0x03 << 14) + +#define S3C2410_GPH8_UCLK (0x02 << 16) +#define S3C2416_GPH8_nCTS0 (0x02 << 16) + +#define S3C2410_GPH9_CLKOUT0 (0x02 << 18) +#define S3C2442_GPH9_nSPICS0 (0x03 << 18) +#define S3C2416_GPH9_nRTS0 (0x02 << 18) + +#define S3C2410_GPH10_CLKOUT1 (0x02 << 20) +#define S3C2416_GPH10_nCTS1 (0x02 << 20) + +#define S3C2416_GPH11_nRTS1 (0x02 << 22) + +#define S3C2416_GPH12_EXTUARTCLK (0x02 << 24) + +#define S3C2416_GPH13_CLKOUT0 (0x02 << 26) + +#define S3C2416_GPH14_CLKOUT1 (0x02 << 28) + +/* The S3C2412 and S3C2413 move the GPJ register set to after + * GPH, which means all registers after 0x80 are now offset by 0x10 + * for the 2412/2413 from the 2410/2440/2442 +*/ + +/* S3C2443 and above */ +#define S3C2440_GPJCON S3C2410_GPIOREG(0xD0) +#define S3C2440_GPJDAT S3C2410_GPIOREG(0xD4) +#define S3C2440_GPJUP S3C2410_GPIOREG(0xD8) + +#define S3C2443_GPKCON S3C2410_GPIOREG(0xE0) +#define S3C2443_GPKDAT S3C2410_GPIOREG(0xE4) +#define S3C2443_GPKUP S3C2410_GPIOREG(0xE8) + +#define S3C2443_GPLCON S3C2410_GPIOREG(0xF0) +#define S3C2443_GPLDAT S3C2410_GPIOREG(0xF4) +#define S3C2443_GPLUP S3C2410_GPIOREG(0xF8) + +#define S3C2443_GPMCON S3C2410_GPIOREG(0x100) +#define S3C2443_GPMDAT S3C2410_GPIOREG(0x104) +#define S3C2443_GPMUP S3C2410_GPIOREG(0x108) + +/* miscellaneous control */ +#define S3C2410_MISCCR S3C2410_GPIOREG(0x80) +#define S3C2410_DCLKCON S3C2410_GPIOREG(0x84) + +#define S3C24XX_DCLKCON S3C24XX_GPIOREG2(0x84) + +/* see clock.h for dclk definitions */ + +/* pullup control on databus */ +#define S3C2410_MISCCR_SPUCR_HEN (0<<0) +#define S3C2410_MISCCR_SPUCR_HDIS (1<<0) +#define S3C2410_MISCCR_SPUCR_LEN (0<<1) +#define S3C2410_MISCCR_SPUCR_LDIS (1<<1) + +#define S3C2410_MISCCR_USBDEV (0<<3) +#define S3C2410_MISCCR_USBHOST (1<<3) + +#define S3C2410_MISCCR_CLK0_MPLL (0<<4) +#define S3C2410_MISCCR_CLK0_UPLL (1<<4) +#define S3C2410_MISCCR_CLK0_FCLK (2<<4) +#define S3C2410_MISCCR_CLK0_HCLK (3<<4) +#define S3C2410_MISCCR_CLK0_PCLK (4<<4) +#define S3C2410_MISCCR_CLK0_DCLK0 (5<<4) +#define S3C2410_MISCCR_CLK0_MASK (7<<4) + +#define S3C2412_MISCCR_CLK0_RTC (2<<4) + +#define S3C2410_MISCCR_CLK1_MPLL (0<<8) +#define S3C2410_MISCCR_CLK1_UPLL (1<<8) +#define S3C2410_MISCCR_CLK1_FCLK (2<<8) +#define S3C2410_MISCCR_CLK1_HCLK (3<<8) +#define S3C2410_MISCCR_CLK1_PCLK (4<<8) +#define S3C2410_MISCCR_CLK1_DCLK1 (5<<8) +#define S3C2410_MISCCR_CLK1_MASK (7<<8) + +#define S3C2412_MISCCR_CLK1_CLKsrc (0<<8) + +#define S3C2410_MISCCR_USBSUSPND0 (1<<12) +#define S3C2416_MISCCR_SEL_SUSPND (1<<12) +#define S3C2410_MISCCR_USBSUSPND1 (1<<13) + +#define S3C2410_MISCCR_nRSTCON (1<<16) + +#define S3C2410_MISCCR_nEN_SCLK0 (1<<17) +#define S3C2410_MISCCR_nEN_SCLK1 (1<<18) +#define S3C2410_MISCCR_nEN_SCLKE (1<<19) /* not 2412 */ +#define S3C2410_MISCCR_SDSLEEP (7<<17) + +#define S3C2416_MISCCR_FLT_I2C (1<<24) +#define S3C2416_MISCCR_HSSPI_EN2 (1<<31) + +/* external interrupt control... */ +/* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7 + * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15 + * S3C2410_EXTINT2 -> irq sense control for EINT16..EINT23 + * + * note S3C2410_EXTINT2 has filtering options for EINT16..EINT23 + * + * Samsung datasheet p9-25 +*/ +#define S3C2410_EXTINT0 S3C2410_GPIOREG(0x88) +#define S3C2410_EXTINT1 S3C2410_GPIOREG(0x8C) +#define S3C2410_EXTINT2 S3C2410_GPIOREG(0x90) + +#define S3C24XX_EXTINT0 S3C24XX_GPIOREG2(0x88) +#define S3C24XX_EXTINT1 S3C24XX_GPIOREG2(0x8C) +#define S3C24XX_EXTINT2 S3C24XX_GPIOREG2(0x90) + +/* interrupt filtering conrrol for EINT16..EINT23 */ +#define S3C2410_EINFLT0 S3C2410_GPIOREG(0x94) +#define S3C2410_EINFLT1 S3C2410_GPIOREG(0x98) +#define S3C2410_EINFLT2 S3C2410_GPIOREG(0x9C) +#define S3C2410_EINFLT3 S3C2410_GPIOREG(0xA0) + +#define S3C24XX_EINFLT0 S3C24XX_GPIOREG2(0x94) +#define S3C24XX_EINFLT1 S3C24XX_GPIOREG2(0x98) +#define S3C24XX_EINFLT2 S3C24XX_GPIOREG2(0x9C) +#define S3C24XX_EINFLT3 S3C24XX_GPIOREG2(0xA0) + +/* values for interrupt filtering */ +#define S3C2410_EINTFLT_PCLK (0x00) +#define S3C2410_EINTFLT_EXTCLK (1<<7) +#define S3C2410_EINTFLT_WIDTHMSK(x) ((x) & 0x3f) + +/* removed EINTxxxx defs from here, not meant for this */ + +/* GSTATUS have miscellaneous information in them + * + * These move between s3c2410 and s3c2412 style systems. + */ + +#define S3C2410_GSTATUS0 S3C2410_GPIOREG(0x0AC) +#define S3C2410_GSTATUS1 S3C2410_GPIOREG(0x0B0) +#define S3C2410_GSTATUS2 S3C2410_GPIOREG(0x0B4) +#define S3C2410_GSTATUS3 S3C2410_GPIOREG(0x0B8) +#define S3C2410_GSTATUS4 S3C2410_GPIOREG(0x0BC) + +#define S3C2412_GSTATUS0 S3C2410_GPIOREG(0x0BC) +#define S3C2412_GSTATUS1 S3C2410_GPIOREG(0x0C0) +#define S3C2412_GSTATUS2 S3C2410_GPIOREG(0x0C4) +#define S3C2412_GSTATUS3 S3C2410_GPIOREG(0x0C8) +#define S3C2412_GSTATUS4 S3C2410_GPIOREG(0x0CC) + +#define S3C24XX_GSTATUS0 S3C24XX_GPIOREG2(0x0AC) +#define S3C24XX_GSTATUS1 S3C24XX_GPIOREG2(0x0B0) +#define S3C24XX_GSTATUS2 S3C24XX_GPIOREG2(0x0B4) +#define S3C24XX_GSTATUS3 S3C24XX_GPIOREG2(0x0B8) +#define S3C24XX_GSTATUS4 S3C24XX_GPIOREG2(0x0BC) + +#define S3C2410_GSTATUS0_nWAIT (1<<3) +#define S3C2410_GSTATUS0_NCON (1<<2) +#define S3C2410_GSTATUS0_RnB (1<<1) +#define S3C2410_GSTATUS0_nBATTFLT (1<<0) + +#define S3C2410_GSTATUS1_IDMASK (0xffff0000) +#define S3C2410_GSTATUS1_2410 (0x32410000) +#define S3C2410_GSTATUS1_2412 (0x32412001) +#define S3C2410_GSTATUS1_2416 (0x32416003) +#define S3C2410_GSTATUS1_2440 (0x32440000) +#define S3C2410_GSTATUS1_2442 (0x32440aaa) +/* some 2416 CPUs report this value also */ +#define S3C2410_GSTATUS1_2450 (0x32450003) + +#define S3C2410_GSTATUS2_WTRESET (1<<2) +#define S3C2410_GSTATUS2_OFFRESET (1<<1) +#define S3C2410_GSTATUS2_PONRESET (1<<0) + +/* 2412/2413 sleep configuration registers */ + +#define S3C2412_GPBSLPCON S3C2410_GPIOREG(0x1C) +#define S3C2412_GPCSLPCON S3C2410_GPIOREG(0x2C) +#define S3C2412_GPDSLPCON S3C2410_GPIOREG(0x3C) +#define S3C2412_GPFSLPCON S3C2410_GPIOREG(0x5C) +#define S3C2412_GPGSLPCON S3C2410_GPIOREG(0x6C) +#define S3C2412_GPHSLPCON S3C2410_GPIOREG(0x7C) + +/* definitions for each pin bit */ +#define S3C2412_GPIO_SLPCON_LOW ( 0x00 ) +#define S3C2412_GPIO_SLPCON_HIGH ( 0x01 ) +#define S3C2412_GPIO_SLPCON_IN ( 0x02 ) +#define S3C2412_GPIO_SLPCON_PULL ( 0x03 ) + +#define S3C2412_SLPCON_LOW(x) ( 0x00 << ((x) * 2)) +#define S3C2412_SLPCON_HIGH(x) ( 0x01 << ((x) * 2)) +#define S3C2412_SLPCON_IN(x) ( 0x02 << ((x) * 2)) +#define S3C2412_SLPCON_PULL(x) ( 0x03 << ((x) * 2)) +#define S3C2412_SLPCON_EINT(x) ( 0x02 << ((x) * 2)) /* only IRQ pins */ +#define S3C2412_SLPCON_MASK(x) ( 0x03 << ((x) * 2)) + +#define S3C2412_SLPCON_ALL_LOW (0x0) +#define S3C2412_SLPCON_ALL_HIGH (0x11111111 | 0x44444444) +#define S3C2412_SLPCON_ALL_IN (0x22222222 | 0x88888888) +#define S3C2412_SLPCON_ALL_PULL (0x33333333) + +#endif /* __ASM_ARCH_REGS_GPIO_H */ + diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-gpioj.h b/arch/arm/mach-s3c24xx/include/mach/regs-gpioj.h new file mode 100644 index 00000000..19575e06 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-gpioj.h @@ -0,0 +1,70 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-gpioj.h + * + * Copyright (c) 2004 Simtec Electronics + * 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. + * + * S3C2440 GPIO J register definitions +*/ + + +#ifndef __ASM_ARCH_REGS_GPIOJ_H +#define __ASM_ARCH_REGS_GPIOJ_H "gpioj" + +/* Port J consists of 13 GPIO/Camera pins + * + * GPJCON has 2 bits for each of the input pins on port F + * 00 = 0 input, 1 output, 2 Camera + * + * pull up works like all other ports. +*/ + +#define S3C2413_GPJCON S3C2410_GPIOREG(0x80) +#define S3C2413_GPJDAT S3C2410_GPIOREG(0x84) +#define S3C2413_GPJUP S3C2410_GPIOREG(0x88) +#define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C) + +#define S3C2440_GPJ0_OUTP (0x01 << 0) +#define S3C2440_GPJ0_CAMDATA0 (0x02 << 0) + +#define S3C2440_GPJ1_OUTP (0x01 << 2) +#define S3C2440_GPJ1_CAMDATA1 (0x02 << 2) + +#define S3C2440_GPJ2_OUTP (0x01 << 4) +#define S3C2440_GPJ2_CAMDATA2 (0x02 << 4) + +#define S3C2440_GPJ3_OUTP (0x01 << 6) +#define S3C2440_GPJ3_CAMDATA3 (0x02 << 6) + +#define S3C2440_GPJ4_OUTP (0x01 << 8) +#define S3C2440_GPJ4_CAMDATA4 (0x02 << 8) + +#define S3C2440_GPJ5_OUTP (0x01 << 10) +#define S3C2440_GPJ5_CAMDATA5 (0x02 << 10) + +#define S3C2440_GPJ6_OUTP (0x01 << 12) +#define S3C2440_GPJ6_CAMDATA6 (0x02 << 12) + +#define S3C2440_GPJ7_OUTP (0x01 << 14) +#define S3C2440_GPJ7_CAMDATA7 (0x02 << 14) + +#define S3C2440_GPJ8_OUTP (0x01 << 16) +#define S3C2440_GPJ8_CAMPCLK (0x02 << 16) + +#define S3C2440_GPJ9_OUTP (0x01 << 18) +#define S3C2440_GPJ9_CAMVSYNC (0x02 << 18) + +#define S3C2440_GPJ10_OUTP (0x01 << 20) +#define S3C2440_GPJ10_CAMHREF (0x02 << 20) + +#define S3C2440_GPJ11_OUTP (0x01 << 22) +#define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22) + +#define S3C2440_GPJ12_OUTP (0x01 << 24) +#define S3C2440_GPJ12_CAMRESET (0x02 << 24) + +#endif /* __ASM_ARCH_REGS_GPIOJ_H */ + diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-irq.h b/arch/arm/mach-s3c24xx/include/mach/regs-irq.h new file mode 100644 index 00000000..0f07ba30 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-irq.h @@ -0,0 +1,53 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-irq.h + * + * Copyright (c) 2003 Simtec Electronics + * 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_REGS_IRQ_H +#define ___ASM_ARCH_REGS_IRQ_H + +/* interrupt controller */ + +#define S3C2410_IRQREG(x) ((x) + S3C24XX_VA_IRQ) +#define S3C2410_EINTREG(x) ((x) + S3C24XX_VA_GPIO) +#define S3C24XX_EINTREG(x) ((x) + S3C24XX_VA_GPIO2) + +#define S3C2410_SRCPND S3C2410_IRQREG(0x000) +#define S3C2410_INTMOD S3C2410_IRQREG(0x004) +#define S3C2410_INTMSK S3C2410_IRQREG(0x008) +#define S3C2410_PRIORITY S3C2410_IRQREG(0x00C) +#define S3C2410_INTPND S3C2410_IRQREG(0x010) +#define S3C2410_INTOFFSET S3C2410_IRQREG(0x014) +#define S3C2410_SUBSRCPND S3C2410_IRQREG(0x018) +#define S3C2410_INTSUBMSK S3C2410_IRQREG(0x01C) + +#define S3C2416_PRIORITY_MODE1 S3C2410_IRQREG(0x030) +#define S3C2416_PRIORITY_UPDATE1 S3C2410_IRQREG(0x034) +#define S3C2416_SRCPND2 S3C2410_IRQREG(0x040) +#define S3C2416_INTMOD2 S3C2410_IRQREG(0x044) +#define S3C2416_INTMSK2 S3C2410_IRQREG(0x048) +#define S3C2416_INTPND2 S3C2410_IRQREG(0x050) +#define S3C2416_INTOFFSET2 S3C2410_IRQREG(0x054) +#define S3C2416_PRIORITY_MODE2 S3C2410_IRQREG(0x070) +#define S3C2416_PRIORITY_UPDATE2 S3C2410_IRQREG(0x074) + +/* mask: 0=enable, 1=disable + * 1 bit EINT, 4=EINT4, 23=EINT23 + * EINT0,1,2,3 are not handled here. +*/ + +#define S3C2410_EINTMASK S3C2410_EINTREG(0x0A4) +#define S3C2410_EINTPEND S3C2410_EINTREG(0X0A8) +#define S3C2412_EINTMASK S3C2410_EINTREG(0x0B4) +#define S3C2412_EINTPEND S3C2410_EINTREG(0X0B8) + +#define S3C24XX_EINTMASK S3C24XX_EINTREG(0x0A4) +#define S3C24XX_EINTPEND S3C24XX_EINTREG(0X0A8) + +#endif /* ___ASM_ARCH_REGS_IRQ_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-lcd.h b/arch/arm/mach-s3c24xx/include/mach/regs-lcd.h new file mode 100644 index 00000000..ee8f040a --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-lcd.h @@ -0,0 +1,162 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-lcd.h + * + * Copyright (c) 2003 Simtec Electronics + * 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_REGS_LCD_H +#define ___ASM_ARCH_REGS_LCD_H + +#define S3C2410_LCDREG(x) (x) + +/* LCD control registers */ +#define S3C2410_LCDCON1 S3C2410_LCDREG(0x00) +#define S3C2410_LCDCON2 S3C2410_LCDREG(0x04) +#define S3C2410_LCDCON3 S3C2410_LCDREG(0x08) +#define S3C2410_LCDCON4 S3C2410_LCDREG(0x0C) +#define S3C2410_LCDCON5 S3C2410_LCDREG(0x10) + +#define S3C2410_LCDCON1_CLKVAL(x) ((x) << 8) +#define S3C2410_LCDCON1_MMODE (1<<7) +#define S3C2410_LCDCON1_DSCAN4 (0<<5) +#define S3C2410_LCDCON1_STN4 (1<<5) +#define S3C2410_LCDCON1_STN8 (2<<5) +#define S3C2410_LCDCON1_TFT (3<<5) + +#define S3C2410_LCDCON1_STN1BPP (0<<1) +#define S3C2410_LCDCON1_STN2GREY (1<<1) +#define S3C2410_LCDCON1_STN4GREY (2<<1) +#define S3C2410_LCDCON1_STN8BPP (3<<1) +#define S3C2410_LCDCON1_STN12BPP (4<<1) + +#define S3C2410_LCDCON1_TFT1BPP (8<<1) +#define S3C2410_LCDCON1_TFT2BPP (9<<1) +#define S3C2410_LCDCON1_TFT4BPP (10<<1) +#define S3C2410_LCDCON1_TFT8BPP (11<<1) +#define S3C2410_LCDCON1_TFT16BPP (12<<1) +#define S3C2410_LCDCON1_TFT24BPP (13<<1) + +#define S3C2410_LCDCON1_ENVID (1) + +#define S3C2410_LCDCON1_MODEMASK 0x1E + +#define S3C2410_LCDCON2_VBPD(x) ((x) << 24) +#define S3C2410_LCDCON2_LINEVAL(x) ((x) << 14) +#define S3C2410_LCDCON2_VFPD(x) ((x) << 6) +#define S3C2410_LCDCON2_VSPW(x) ((x) << 0) + +#define S3C2410_LCDCON2_GET_VBPD(x) ( ((x) >> 24) & 0xFF) +#define S3C2410_LCDCON2_GET_VFPD(x) ( ((x) >> 6) & 0xFF) +#define S3C2410_LCDCON2_GET_VSPW(x) ( ((x) >> 0) & 0x3F) + +#define S3C2410_LCDCON3_HBPD(x) ((x) << 19) +#define S3C2410_LCDCON3_WDLY(x) ((x) << 19) +#define S3C2410_LCDCON3_HOZVAL(x) ((x) << 8) +#define S3C2410_LCDCON3_HFPD(x) ((x) << 0) +#define S3C2410_LCDCON3_LINEBLANK(x)((x) << 0) + +#define S3C2410_LCDCON3_GET_HBPD(x) ( ((x) >> 19) & 0x7F) +#define S3C2410_LCDCON3_GET_HFPD(x) ( ((x) >> 0) & 0xFF) + +/* LDCCON4 changes for STN mode on the S3C2412 */ + +#define S3C2410_LCDCON4_MVAL(x) ((x) << 8) +#define S3C2410_LCDCON4_HSPW(x) ((x) << 0) +#define S3C2410_LCDCON4_WLH(x) ((x) << 0) + +#define S3C2410_LCDCON4_GET_HSPW(x) ( ((x) >> 0) & 0xFF) + +#define S3C2410_LCDCON5_BPP24BL (1<<12) +#define S3C2410_LCDCON5_FRM565 (1<<11) +#define S3C2410_LCDCON5_INVVCLK (1<<10) +#define S3C2410_LCDCON5_INVVLINE (1<<9) +#define S3C2410_LCDCON5_INVVFRAME (1<<8) +#define S3C2410_LCDCON5_INVVD (1<<7) +#define S3C2410_LCDCON5_INVVDEN (1<<6) +#define S3C2410_LCDCON5_INVPWREN (1<<5) +#define S3C2410_LCDCON5_INVLEND (1<<4) +#define S3C2410_LCDCON5_PWREN (1<<3) +#define S3C2410_LCDCON5_ENLEND (1<<2) +#define S3C2410_LCDCON5_BSWP (1<<1) +#define S3C2410_LCDCON5_HWSWP (1<<0) + +/* framebuffer start addressed */ +#define S3C2410_LCDSADDR1 S3C2410_LCDREG(0x14) +#define S3C2410_LCDSADDR2 S3C2410_LCDREG(0x18) +#define S3C2410_LCDSADDR3 S3C2410_LCDREG(0x1C) + +#define S3C2410_LCDBANK(x) ((x) << 21) +#define S3C2410_LCDBASEU(x) (x) + +#define S3C2410_OFFSIZE(x) ((x) << 11) +#define S3C2410_PAGEWIDTH(x) (x) + +/* colour lookup and miscellaneous controls */ + +#define S3C2410_REDLUT S3C2410_LCDREG(0x20) +#define S3C2410_GREENLUT S3C2410_LCDREG(0x24) +#define S3C2410_BLUELUT S3C2410_LCDREG(0x28) + +#define S3C2410_DITHMODE S3C2410_LCDREG(0x4C) +#define S3C2410_TPAL S3C2410_LCDREG(0x50) + +#define S3C2410_TPAL_EN (1<<24) + +/* interrupt info */ +#define S3C2410_LCDINTPND S3C2410_LCDREG(0x54) +#define S3C2410_LCDSRCPND S3C2410_LCDREG(0x58) +#define S3C2410_LCDINTMSK S3C2410_LCDREG(0x5C) +#define S3C2410_LCDINT_FIWSEL (1<<2) +#define S3C2410_LCDINT_FRSYNC (1<<1) +#define S3C2410_LCDINT_FICNT (1<<0) + +/* s3c2442 extra stn registers */ + +#define S3C2442_REDLUT S3C2410_LCDREG(0x20) +#define S3C2442_GREENLUT S3C2410_LCDREG(0x24) +#define S3C2442_BLUELUT S3C2410_LCDREG(0x28) +#define S3C2442_DITHMODE S3C2410_LCDREG(0x20) + +#define S3C2410_LPCSEL S3C2410_LCDREG(0x60) + +#define S3C2410_TFTPAL(x) S3C2410_LCDREG((0x400 + (x)*4)) + +/* S3C2412 registers */ + +#define S3C2412_TPAL S3C2410_LCDREG(0x20) + +#define S3C2412_LCDINTPND S3C2410_LCDREG(0x24) +#define S3C2412_LCDSRCPND S3C2410_LCDREG(0x28) +#define S3C2412_LCDINTMSK S3C2410_LCDREG(0x2C) + +#define S3C2412_TCONSEL S3C2410_LCDREG(0x30) + +#define S3C2412_LCDCON6 S3C2410_LCDREG(0x34) +#define S3C2412_LCDCON7 S3C2410_LCDREG(0x38) +#define S3C2412_LCDCON8 S3C2410_LCDREG(0x3C) +#define S3C2412_LCDCON9 S3C2410_LCDREG(0x40) + +#define S3C2412_REDLUT(x) S3C2410_LCDREG(0x44 + ((x)*4)) +#define S3C2412_GREENLUT(x) S3C2410_LCDREG(0x60 + ((x)*4)) +#define S3C2412_BLUELUT(x) S3C2410_LCDREG(0x98 + ((x)*4)) + +#define S3C2412_FRCPAT(x) S3C2410_LCDREG(0xB4 + ((x)*4)) + +/* general registers */ + +/* base of the LCD registers, where INTPND, INTSRC and then INTMSK + * are available. */ + +#define S3C2410_LCDINTBASE S3C2410_LCDREG(0x54) +#define S3C2412_LCDINTBASE S3C2410_LCDREG(0x24) + +#define S3C24XX_LCDINTPND (0x00) +#define S3C24XX_LCDSRCPND (0x04) +#define S3C24XX_LCDINTMSK (0x08) + +#endif /* ___ASM_ARCH_REGS_LCD_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-mem.h b/arch/arm/mach-s3c24xx/include/mach/regs-mem.h new file mode 100644 index 00000000..e0c67b01 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-mem.h @@ -0,0 +1,202 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-mem.h + * + * Copyright (c) 2004 Simtec Electronics + * 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. + * + * S3C2410 Memory Control register definitions +*/ + +#ifndef __ASM_ARM_MEMREGS_H +#define __ASM_ARM_MEMREGS_H + +#ifndef S3C2410_MEMREG +#define S3C2410_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x)) +#endif + +/* bus width, and wait state control */ +#define S3C2410_BWSCON S3C2410_MEMREG(0x0000) + +/* bank zero config - note, pinstrapped from OM pins! */ +#define S3C2410_BWSCON_DW0_16 (1<<1) +#define S3C2410_BWSCON_DW0_32 (2<<1) + +/* bank one configs */ +#define S3C2410_BWSCON_DW1_8 (0<<4) +#define S3C2410_BWSCON_DW1_16 (1<<4) +#define S3C2410_BWSCON_DW1_32 (2<<4) +#define S3C2410_BWSCON_WS1 (1<<6) +#define S3C2410_BWSCON_ST1 (1<<7) + +/* bank 2 configurations */ +#define S3C2410_BWSCON_DW2_8 (0<<8) +#define S3C2410_BWSCON_DW2_16 (1<<8) +#define S3C2410_BWSCON_DW2_32 (2<<8) +#define S3C2410_BWSCON_WS2 (1<<10) +#define S3C2410_BWSCON_ST2 (1<<11) + +/* bank 3 configurations */ +#define S3C2410_BWSCON_DW3_8 (0<<12) +#define S3C2410_BWSCON_DW3_16 (1<<12) +#define S3C2410_BWSCON_DW3_32 (2<<12) +#define S3C2410_BWSCON_WS3 (1<<14) +#define S3C2410_BWSCON_ST3 (1<<15) + +/* bank 4 configurations */ +#define S3C2410_BWSCON_DW4_8 (0<<16) +#define S3C2410_BWSCON_DW4_16 (1<<16) +#define S3C2410_BWSCON_DW4_32 (2<<16) +#define S3C2410_BWSCON_WS4 (1<<18) +#define S3C2410_BWSCON_ST4 (1<<19) + +/* bank 5 configurations */ +#define S3C2410_BWSCON_DW5_8 (0<<20) +#define S3C2410_BWSCON_DW5_16 (1<<20) +#define S3C2410_BWSCON_DW5_32 (2<<20) +#define S3C2410_BWSCON_WS5 (1<<22) +#define S3C2410_BWSCON_ST5 (1<<23) + +/* bank 6 configurations */ +#define S3C2410_BWSCON_DW6_8 (0<<24) +#define S3C2410_BWSCON_DW6_16 (1<<24) +#define S3C2410_BWSCON_DW6_32 (2<<24) +#define S3C2410_BWSCON_WS6 (1<<26) +#define S3C2410_BWSCON_ST6 (1<<27) + +/* bank 7 configurations */ +#define S3C2410_BWSCON_DW7_8 (0<<28) +#define S3C2410_BWSCON_DW7_16 (1<<28) +#define S3C2410_BWSCON_DW7_32 (2<<28) +#define S3C2410_BWSCON_WS7 (1<<30) +#define S3C2410_BWSCON_ST7 (1<<31) + +/* accesor functions for getting BANK(n) configuration. (n != 0) */ + +#define S3C2410_BWSCON_GET(_bwscon, _bank) (((_bwscon) >> ((_bank) * 4)) & 0xf) + +#define S3C2410_BWSCON_DW8 (0) +#define S3C2410_BWSCON_DW16 (1) +#define S3C2410_BWSCON_DW32 (2) +#define S3C2410_BWSCON_WS (1 << 2) +#define S3C2410_BWSCON_ST (1 << 3) + +/* memory set (rom, ram) */ +#define S3C2410_BANKCON0 S3C2410_MEMREG(0x0004) +#define S3C2410_BANKCON1 S3C2410_MEMREG(0x0008) +#define S3C2410_BANKCON2 S3C2410_MEMREG(0x000C) +#define S3C2410_BANKCON3 S3C2410_MEMREG(0x0010) +#define S3C2410_BANKCON4 S3C2410_MEMREG(0x0014) +#define S3C2410_BANKCON5 S3C2410_MEMREG(0x0018) +#define S3C2410_BANKCON6 S3C2410_MEMREG(0x001C) +#define S3C2410_BANKCON7 S3C2410_MEMREG(0x0020) + +/* bank configuration registers */ + +#define S3C2410_BANKCON_PMCnorm (0x00) +#define S3C2410_BANKCON_PMC4 (0x01) +#define S3C2410_BANKCON_PMC8 (0x02) +#define S3C2410_BANKCON_PMC16 (0x03) + +/* bank configurations for banks 0..7, note banks + * 6 and 7 have different configurations depending on + * the memory type bits */ + +#define S3C2410_BANKCON_Tacp2 (0x0 << 2) +#define S3C2410_BANKCON_Tacp3 (0x1 << 2) +#define S3C2410_BANKCON_Tacp4 (0x2 << 2) +#define S3C2410_BANKCON_Tacp6 (0x3 << 2) +#define S3C2410_BANKCON_Tacp_SHIFT (2) + +#define S3C2410_BANKCON_Tcah0 (0x0 << 4) +#define S3C2410_BANKCON_Tcah1 (0x1 << 4) +#define S3C2410_BANKCON_Tcah2 (0x2 << 4) +#define S3C2410_BANKCON_Tcah4 (0x3 << 4) +#define S3C2410_BANKCON_Tcah_SHIFT (4) + +#define S3C2410_BANKCON_Tcoh0 (0x0 << 6) +#define S3C2410_BANKCON_Tcoh1 (0x1 << 6) +#define S3C2410_BANKCON_Tcoh2 (0x2 << 6) +#define S3C2410_BANKCON_Tcoh4 (0x3 << 6) +#define S3C2410_BANKCON_Tcoh_SHIFT (6) + +#define S3C2410_BANKCON_Tacc1 (0x0 << 8) +#define S3C2410_BANKCON_Tacc2 (0x1 << 8) +#define S3C2410_BANKCON_Tacc3 (0x2 << 8) +#define S3C2410_BANKCON_Tacc4 (0x3 << 8) +#define S3C2410_BANKCON_Tacc6 (0x4 << 8) +#define S3C2410_BANKCON_Tacc8 (0x5 << 8) +#define S3C2410_BANKCON_Tacc10 (0x6 << 8) +#define S3C2410_BANKCON_Tacc14 (0x7 << 8) +#define S3C2410_BANKCON_Tacc_SHIFT (8) + +#define S3C2410_BANKCON_Tcos0 (0x0 << 11) +#define S3C2410_BANKCON_Tcos1 (0x1 << 11) +#define S3C2410_BANKCON_Tcos2 (0x2 << 11) +#define S3C2410_BANKCON_Tcos4 (0x3 << 11) +#define S3C2410_BANKCON_Tcos_SHIFT (11) + +#define S3C2410_BANKCON_Tacs0 (0x0 << 13) +#define S3C2410_BANKCON_Tacs1 (0x1 << 13) +#define S3C2410_BANKCON_Tacs2 (0x2 << 13) +#define S3C2410_BANKCON_Tacs4 (0x3 << 13) +#define S3C2410_BANKCON_Tacs_SHIFT (13) + +#define S3C2410_BANKCON_SRAM (0x0 << 15) +#define S3C2410_BANKCON_SDRAM (0x3 << 15) + +/* next bits only for SDRAM in 6,7 */ +#define S3C2410_BANKCON_Trcd2 (0x00 << 2) +#define S3C2410_BANKCON_Trcd3 (0x01 << 2) +#define S3C2410_BANKCON_Trcd4 (0x02 << 2) + +/* control column address select */ +#define S3C2410_BANKCON_SCANb8 (0x00 << 0) +#define S3C2410_BANKCON_SCANb9 (0x01 << 0) +#define S3C2410_BANKCON_SCANb10 (0x02 << 0) + +#define S3C2410_REFRESH S3C2410_MEMREG(0x0024) +#define S3C2410_BANKSIZE S3C2410_MEMREG(0x0028) +#define S3C2410_MRSRB6 S3C2410_MEMREG(0x002C) +#define S3C2410_MRSRB7 S3C2410_MEMREG(0x0030) + +/* refresh control */ + +#define S3C2410_REFRESH_REFEN (1<<23) +#define S3C2410_REFRESH_SELF (1<<22) +#define S3C2410_REFRESH_REFCOUNTER ((1<<11)-1) + +#define S3C2410_REFRESH_TRP_MASK (3<<20) +#define S3C2410_REFRESH_TRP_2clk (0<<20) +#define S3C2410_REFRESH_TRP_3clk (1<<20) +#define S3C2410_REFRESH_TRP_4clk (2<<20) + +#define S3C2410_REFRESH_TSRC_MASK (3<<18) +#define S3C2410_REFRESH_TSRC_4clk (0<<18) +#define S3C2410_REFRESH_TSRC_5clk (1<<18) +#define S3C2410_REFRESH_TSRC_6clk (2<<18) +#define S3C2410_REFRESH_TSRC_7clk (3<<18) + + +/* mode select register(s) */ + +#define S3C2410_MRSRB_CL1 (0x00 << 4) +#define S3C2410_MRSRB_CL2 (0x02 << 4) +#define S3C2410_MRSRB_CL3 (0x03 << 4) + +/* bank size register */ +#define S3C2410_BANKSIZE_128M (0x2 << 0) +#define S3C2410_BANKSIZE_64M (0x1 << 0) +#define S3C2410_BANKSIZE_32M (0x0 << 0) +#define S3C2410_BANKSIZE_16M (0x7 << 0) +#define S3C2410_BANKSIZE_8M (0x6 << 0) +#define S3C2410_BANKSIZE_4M (0x5 << 0) +#define S3C2410_BANKSIZE_2M (0x4 << 0) +#define S3C2410_BANKSIZE_MASK (0x7 << 0) +#define S3C2410_BANKSIZE_SCLK_EN (1<<4) +#define S3C2410_BANKSIZE_SCKE_EN (1<<5) +#define S3C2410_BANKSIZE_BURST (1<<7) + +#endif /* __ASM_ARM_MEMREGS_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-power.h b/arch/arm/mach-s3c24xx/include/mach/regs-power.h new file mode 100644 index 00000000..4932b87b --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-power.h @@ -0,0 +1,40 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-power.h + * + * Copyright (c) 2003-2006 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. + * + * S3C24XX power control register definitions +*/ + +#ifndef __ASM_ARM_REGS_PWR +#define __ASM_ARM_REGS_PWR __FILE__ + +#define S3C24XX_PWRREG(x) ((x) + S3C24XX_VA_CLKPWR) + +#define S3C2412_PWRMODECON S3C24XX_PWRREG(0x20) +#define S3C2412_PWRCFG S3C24XX_PWRREG(0x24) + +#define S3C2412_INFORM0 S3C24XX_PWRREG(0x70) +#define S3C2412_INFORM1 S3C24XX_PWRREG(0x74) +#define S3C2412_INFORM2 S3C24XX_PWRREG(0x78) +#define S3C2412_INFORM3 S3C24XX_PWRREG(0x7C) + +#define S3C2412_PWRCFG_BATF_IRQ (1<<0) +#define S3C2412_PWRCFG_BATF_IGNORE (2<<0) +#define S3C2412_PWRCFG_BATF_SLEEP (3<<0) +#define S3C2412_PWRCFG_BATF_MASK (3<<0) + +#define S3C2412_PWRCFG_STANDBYWFI_IGNORE (0<<6) +#define S3C2412_PWRCFG_STANDBYWFI_IDLE (1<<6) +#define S3C2412_PWRCFG_STANDBYWFI_STOP (2<<6) +#define S3C2412_PWRCFG_STANDBYWFI_SLEEP (3<<6) +#define S3C2412_PWRCFG_STANDBYWFI_MASK (3<<6) + +#define S3C2412_PWRCFG_RTC_MASKIRQ (1<<8) +#define S3C2412_PWRCFG_NAND_NORST (1<<9) + +#endif /* __ASM_ARM_REGS_PWR */ diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412-mem.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412-mem.h new file mode 100644 index 00000000..fb635251 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412-mem.h @@ -0,0 +1,48 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h + * + * Copyright (c) 2008 Simtec Electronics + * Ben Dooks + * 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. + * + * S3C2412 memory register definitions +*/ + +#ifndef __ASM_ARM_REGS_S3C2412_MEM +#define __ASM_ARM_REGS_S3C2412_MEM + +#define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x)) +#define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x)) + +#define S3C2412_SSMCREG(x) (S3C2412_VA_SSMC + (x)) +#define S3C2412_SSMC(x, o) (S3C2412_SSMCREG((x * 0x20) + (o))) + +#define S3C2412_BANKCFG S3C2412_MEMREG(0x00) +#define S3C2412_BANKCON1 S3C2412_MEMREG(0x04) +#define S3C2412_BANKCON2 S3C2412_MEMREG(0x08) +#define S3C2412_BANKCON3 S3C2412_MEMREG(0x0C) + +#define S3C2412_REFRESH S3C2412_MEMREG(0x10) +#define S3C2412_TIMEOUT S3C2412_MEMREG(0x14) + +/* EBI control registers */ + +#define S3C2412_EBI_PR S3C2412_EBIREG(0x00) +#define S3C2412_EBI_BANKCFG S3C2412_EBIREG(0x04) + +/* SSMC control registers */ + +#define S3C2412_SSMC_BANK(x) S3C2412_SSMC(x, 0x00) +#define S3C2412_SMIDCYR(x) S3C2412_SSMC(x, 0x00) +#define S3C2412_SMBWSTRD(x) S3C2412_SSMC(x, 0x04) +#define S3C2412_SMBWSTWRR(x) S3C2412_SSMC(x, 0x08) +#define S3C2412_SMBWSTOENR(x) S3C2412_SSMC(x, 0x0C) +#define S3C2412_SMBWSTWENR(x) S3C2412_SSMC(x, 0x10) +#define S3C2412_SMBCR(x) S3C2412_SSMC(x, 0x14) +#define S3C2412_SMBSR(x) S3C2412_SSMC(x, 0x18) +#define S3C2412_SMBWSTBRDR(x) S3C2412_SSMC(x, 0x1C) + +#endif /* __ASM_ARM_REGS_S3C2412_MEM */ diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412.h new file mode 100644 index 00000000..aa69dc79 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2412.h @@ -0,0 +1,23 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h + * + * Copyright 2007 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * 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. + * + * S3C2412 specific register definitions +*/ + +#ifndef __ASM_ARCH_REGS_S3C2412_H +#define __ASM_ARCH_REGS_S3C2412_H "s3c2412" + +#define S3C2412_SWRST (S3C24XX_VA_CLKPWR + 0x30) +#define S3C2412_SWRST_RESET (0x533C2412) + +/* see regs-power.h for the other registers in the power block. */ + +#endif /* __ASM_ARCH_REGS_S3C2412_H */ + diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416-mem.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416-mem.h new file mode 100644 index 00000000..2f31b749 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416-mem.h @@ -0,0 +1,30 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h + * + * Copyright (c) 2009 Yauhen Kharuzhy , + * as part of OpenInkpot project + * Copyright (c) 2009 Promwad Innovation Company + * Yauhen Kharuzhy + * + * 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. + * + * S3C2416 memory register definitions +*/ + +#ifndef __ASM_ARM_REGS_S3C2416_MEM +#define __ASM_ARM_REGS_S3C2416_MEM + +#ifndef S3C2416_MEMREG +#define S3C2416_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x)) +#endif + +#define S3C2416_BANKCFG S3C2416_MEMREG(0x00) +#define S3C2416_BANKCON1 S3C2416_MEMREG(0x04) +#define S3C2416_BANKCON2 S3C2416_MEMREG(0x08) +#define S3C2416_BANKCON3 S3C2416_MEMREG(0x0C) + +#define S3C2416_REFRESH S3C2416_MEMREG(0x10) +#define S3C2416_TIMEOUT S3C2416_MEMREG(0x14) + +#endif /* __ASM_ARM_REGS_S3C2416_MEM */ diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416.h new file mode 100644 index 00000000..e443167e --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2416.h @@ -0,0 +1,24 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h + * + * Copyright (c) 2009 Yauhen Kharuzhy , + * as part of OpenInkpot project + * Copyright (c) 2009 Promwad Innovation Company + * Yauhen Kharuzhy + * + * 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. + * + * S3C2416 specific register definitions +*/ + +#ifndef __ASM_ARCH_REGS_S3C2416_H +#define __ASM_ARCH_REGS_S3C2416_H "s3c2416" + +#define S3C2416_SWRST (S3C24XX_VA_CLKPWR + 0x44) +#define S3C2416_SWRST_RESET (0x533C2416) + +/* see regs-power.h for the other registers in the power block. */ + +#endif /* __ASM_ARCH_REGS_S3C2416_H */ + diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h new file mode 100644 index 00000000..c3feff3c --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-s3c2443-clock.h @@ -0,0 +1,194 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h + * + * Copyright (c) 2007 Simtec Electronics + * Ben Dooks + * 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. + * + * S3C2443 clock register definitions +*/ + +#ifndef __ASM_ARM_REGS_S3C2443_CLOCK +#define __ASM_ARM_REGS_S3C2443_CLOCK + +#define S3C2443_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR) + +#define S3C2443_PLLCON_MDIVSHIFT 16 +#define S3C2443_PLLCON_PDIVSHIFT 8 +#define S3C2443_PLLCON_SDIVSHIFT 0 +#define S3C2443_PLLCON_MDIVMASK ((1<<(1+(23-16)))-1) +#define S3C2443_PLLCON_PDIVMASK ((1<<(1+(9-8)))-1) +#define S3C2443_PLLCON_SDIVMASK (3) + +#define S3C2443_MPLLCON S3C2443_CLKREG(0x10) +#define S3C2443_EPLLCON S3C2443_CLKREG(0x18) +#define S3C2443_CLKSRC S3C2443_CLKREG(0x20) +#define S3C2443_CLKDIV0 S3C2443_CLKREG(0x24) +#define S3C2443_CLKDIV1 S3C2443_CLKREG(0x28) +#define S3C2443_HCLKCON S3C2443_CLKREG(0x30) +#define S3C2443_PCLKCON S3C2443_CLKREG(0x34) +#define S3C2443_SCLKCON S3C2443_CLKREG(0x38) +#define S3C2443_PWRMODE S3C2443_CLKREG(0x40) +#define S3C2443_SWRST S3C2443_CLKREG(0x44) +#define S3C2443_BUSPRI0 S3C2443_CLKREG(0x50) +#define S3C2443_SYSID S3C2443_CLKREG(0x5C) +#define S3C2443_PWRCFG S3C2443_CLKREG(0x60) +#define S3C2443_RSTCON S3C2443_CLKREG(0x64) +#define S3C2443_PHYCTRL S3C2443_CLKREG(0x80) +#define S3C2443_PHYPWR S3C2443_CLKREG(0x84) +#define S3C2443_URSTCON S3C2443_CLKREG(0x88) +#define S3C2443_UCLKCON S3C2443_CLKREG(0x8C) + +#define S3C2443_SWRST_RESET (0x533c2443) + +#define S3C2443_PLLCON_OFF (1<<24) + +#define S3C2443_CLKSRC_EPLLREF_XTAL (2<<7) +#define S3C2443_CLKSRC_EPLLREF_EXTCLK (3<<7) +#define S3C2443_CLKSRC_EPLLREF_MPLLREF (0<<7) +#define S3C2443_CLKSRC_EPLLREF_MPLLREF2 (1<<7) +#define S3C2443_CLKSRC_EPLLREF_MASK (3<<7) + +#define S3C2443_CLKSRC_EXTCLK_DIV (1<<3) + +#define S3C2443_CLKDIV0_HALF_HCLK (1<<3) +#define S3C2443_CLKDIV0_HALF_PCLK (1<<2) + +#define S3C2443_CLKDIV0_HCLKDIV_MASK (3<<0) + +#define S3C2443_CLKDIV0_EXTDIV_MASK (3<<6) +#define S3C2443_CLKDIV0_EXTDIV_SHIFT (6) + +#define S3C2443_CLKDIV0_PREDIV_MASK (3<<4) +#define S3C2443_CLKDIV0_PREDIV_SHIFT (4) + +#define S3C2416_CLKDIV0_ARMDIV_MASK (7 << 9) +#define S3C2443_CLKDIV0_ARMDIV_MASK (15<<9) +#define S3C2443_CLKDIV0_ARMDIV_SHIFT (9) +#define S3C2443_CLKDIV0_ARMDIV_1 (0<<9) +#define S3C2443_CLKDIV0_ARMDIV_2 (8<<9) +#define S3C2443_CLKDIV0_ARMDIV_3 (2<<9) +#define S3C2443_CLKDIV0_ARMDIV_4 (9<<9) +#define S3C2443_CLKDIV0_ARMDIV_6 (10<<9) +#define S3C2443_CLKDIV0_ARMDIV_8 (11<<9) +#define S3C2443_CLKDIV0_ARMDIV_12 (13<<9) +#define S3C2443_CLKDIV0_ARMDIV_16 (15<<9) + +/* S3C2443_CLKDIV1 removed, only used in clock.c code */ + +#define S3C2443_CLKCON_NAND + +#define S3C2443_HCLKCON_DMA0 (1<<0) +#define S3C2443_HCLKCON_DMA1 (1<<1) +#define S3C2443_HCLKCON_DMA2 (1<<2) +#define S3C2443_HCLKCON_DMA3 (1<<3) +#define S3C2443_HCLKCON_DMA4 (1<<4) +#define S3C2443_HCLKCON_DMA5 (1<<5) +#define S3C2443_HCLKCON_CAMIF (1<<8) +#define S3C2443_HCLKCON_LCDC (1<<9) +#define S3C2443_HCLKCON_USBH (1<<11) +#define S3C2443_HCLKCON_USBD (1<<12) +#define S3C2416_HCLKCON_HSMMC0 (1<<15) +#define S3C2443_HCLKCON_HSMMC (1<<16) +#define S3C2443_HCLKCON_CFC (1<<17) +#define S3C2443_HCLKCON_SSMC (1<<18) +#define S3C2443_HCLKCON_DRAMC (1<<19) + +#define S3C2443_PCLKCON_UART0 (1<<0) +#define S3C2443_PCLKCON_UART1 (1<<1) +#define S3C2443_PCLKCON_UART2 (1<<2) +#define S3C2443_PCLKCON_UART3 (1<<3) +#define S3C2443_PCLKCON_IIC (1<<4) +#define S3C2443_PCLKCON_SDI (1<<5) +#define S3C2443_PCLKCON_HSSPI (1<<6) +#define S3C2443_PCLKCON_ADC (1<<7) +#define S3C2443_PCLKCON_AC97 (1<<8) +#define S3C2443_PCLKCON_IIS (1<<9) +#define S3C2443_PCLKCON_PWMT (1<<10) +#define S3C2443_PCLKCON_WDT (1<<11) +#define S3C2443_PCLKCON_RTC (1<<12) +#define S3C2443_PCLKCON_GPIO (1<<13) +#define S3C2443_PCLKCON_SPI0 (1<<14) +#define S3C2443_PCLKCON_SPI1 (1<<15) + +#define S3C2443_SCLKCON_DDRCLK (1<<16) +#define S3C2443_SCLKCON_SSMCCLK (1<<15) +#define S3C2443_SCLKCON_HSSPICLK (1<<14) +#define S3C2443_SCLKCON_HSMMCCLK_EXT (1<<13) +#define S3C2443_SCLKCON_HSMMCCLK_EPLL (1<<12) +#define S3C2443_SCLKCON_CAMCLK (1<<11) +#define S3C2443_SCLKCON_DISPCLK (1<<10) +#define S3C2443_SCLKCON_I2SCLK (1<<9) +#define S3C2443_SCLKCON_UARTCLK (1<<8) +#define S3C2443_SCLKCON_USBHOST (1<<1) + +#define S3C2443_PWRCFG_SLEEP (1<<15) + +#define S3C2443_PWRCFG_USBPHY (1 << 4) + +#define S3C2443_URSTCON_FUNCRST (1 << 2) +#define S3C2443_URSTCON_PHYRST (1 << 0) + +#define S3C2443_PHYCTRL_CLKSEL (1 << 3) +#define S3C2443_PHYCTRL_EXTCLK (1 << 2) +#define S3C2443_PHYCTRL_PLLSEL (1 << 1) +#define S3C2443_PHYCTRL_DSPORT (1 << 0) + +#define S3C2443_PHYPWR_COMMON_ON (1 << 31) +#define S3C2443_PHYPWR_ANALOG_PD (1 << 4) +#define S3C2443_PHYPWR_PLL_REFCLK (1 << 3) +#define S3C2443_PHYPWR_XO_ON (1 << 2) +#define S3C2443_PHYPWR_PLL_PWRDN (1 << 1) +#define S3C2443_PHYPWR_FSUSPEND (1 << 0) + +#define S3C2443_UCLKCON_DETECT_VBUS (1 << 31) +#define S3C2443_UCLKCON_FUNC_CLKEN (1 << 2) +#define S3C2443_UCLKCON_TCLKEN (1 << 0) + +#include + +static inline unsigned int +s3c2443_get_mpll(unsigned int pllval, unsigned int baseclk) +{ + unsigned int mdiv, pdiv, sdiv; + uint64_t fvco; + + mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT; + pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT; + sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT; + + mdiv &= S3C2443_PLLCON_MDIVMASK; + pdiv &= S3C2443_PLLCON_PDIVMASK; + sdiv &= S3C2443_PLLCON_SDIVMASK; + + fvco = (uint64_t)baseclk * (2 * (mdiv + 8)); + do_div(fvco, pdiv << sdiv); + + return (unsigned int)fvco; +} + +static inline unsigned int +s3c2443_get_epll(unsigned int pllval, unsigned int baseclk) +{ + unsigned int mdiv, pdiv, sdiv; + uint64_t fvco; + + mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT; + pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT; + sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT; + + mdiv &= S3C2443_PLLCON_MDIVMASK; + pdiv &= S3C2443_PLLCON_PDIVMASK; + sdiv &= S3C2443_PLLCON_SDIVMASK; + + fvco = (uint64_t)baseclk * (mdiv + 8); + do_div(fvco, (pdiv + 2) << sdiv); + + return (unsigned int)fvco; +} + +#endif /* __ASM_ARM_REGS_S3C2443_CLOCK */ + diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h b/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h new file mode 100644 index 00000000..cbf2d888 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h @@ -0,0 +1,127 @@ +/* arch/arm/mach-s3c2410/include/mach/regs-sdi.h + * + * Copyright (c) 2004 Simtec Electronics + * 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. + * + * S3C2410 MMC/SDIO register definitions +*/ + +#ifndef __ASM_ARM_REGS_SDI +#define __ASM_ARM_REGS_SDI "regs-sdi.h" + +#define S3C2410_SDICON (0x00) +#define S3C2410_SDIPRE (0x04) +#define S3C2410_SDICMDARG (0x08) +#define S3C2410_SDICMDCON (0x0C) +#define S3C2410_SDICMDSTAT (0x10) +#define S3C2410_SDIRSP0 (0x14) +#define S3C2410_SDIRSP1 (0x18) +#define S3C2410_SDIRSP2 (0x1C) +#define S3C2410_SDIRSP3 (0x20) +#define S3C2410_SDITIMER (0x24) +#define S3C2410_SDIBSIZE (0x28) +#define S3C2410_SDIDCON (0x2C) +#define S3C2410_SDIDCNT (0x30) +#define S3C2410_SDIDSTA (0x34) +#define S3C2410_SDIFSTA (0x38) + +#define S3C2410_SDIDATA (0x3C) +#define S3C2410_SDIIMSK (0x40) + +#define S3C2440_SDIDATA (0x40) +#define S3C2440_SDIIMSK (0x3C) + +#define S3C2440_SDICON_SDRESET (1<<8) +#define S3C2440_SDICON_MMCCLOCK (1<<5) +#define S3C2410_SDICON_BYTEORDER (1<<4) +#define S3C2410_SDICON_SDIOIRQ (1<<3) +#define S3C2410_SDICON_RWAITEN (1<<2) +#define S3C2410_SDICON_FIFORESET (1<<1) +#define S3C2410_SDICON_CLOCKTYPE (1<<0) + +#define S3C2410_SDICMDCON_ABORT (1<<12) +#define S3C2410_SDICMDCON_WITHDATA (1<<11) +#define S3C2410_SDICMDCON_LONGRSP (1<<10) +#define S3C2410_SDICMDCON_WAITRSP (1<<9) +#define S3C2410_SDICMDCON_CMDSTART (1<<8) +#define S3C2410_SDICMDCON_SENDERHOST (1<<6) +#define S3C2410_SDICMDCON_INDEX (0x3f) + +#define S3C2410_SDICMDSTAT_CRCFAIL (1<<12) +#define S3C2410_SDICMDSTAT_CMDSENT (1<<11) +#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1<<10) +#define S3C2410_SDICMDSTAT_RSPFIN (1<<9) +#define S3C2410_SDICMDSTAT_XFERING (1<<8) +#define S3C2410_SDICMDSTAT_INDEX (0xff) + +#define S3C2440_SDIDCON_DS_BYTE (0<<22) +#define S3C2440_SDIDCON_DS_HALFWORD (1<<22) +#define S3C2440_SDIDCON_DS_WORD (2<<22) +#define S3C2410_SDIDCON_IRQPERIOD (1<<21) +#define S3C2410_SDIDCON_TXAFTERRESP (1<<20) +#define S3C2410_SDIDCON_RXAFTERCMD (1<<19) +#define S3C2410_SDIDCON_BUSYAFTERCMD (1<<18) +#define S3C2410_SDIDCON_BLOCKMODE (1<<17) +#define S3C2410_SDIDCON_WIDEBUS (1<<16) +#define S3C2410_SDIDCON_DMAEN (1<<15) +#define S3C2410_SDIDCON_STOP (1<<14) +#define S3C2440_SDIDCON_DATSTART (1<<14) +#define S3C2410_SDIDCON_DATMODE (3<<12) +#define S3C2410_SDIDCON_BLKNUM (0x7ff) + +/* constants for S3C2410_SDIDCON_DATMODE */ +#define S3C2410_SDIDCON_XFER_READY (0<<12) +#define S3C2410_SDIDCON_XFER_CHKSTART (1<<12) +#define S3C2410_SDIDCON_XFER_RXSTART (2<<12) +#define S3C2410_SDIDCON_XFER_TXSTART (3<<12) + +#define S3C2410_SDIDCON_BLKNUM_MASK (0xFFF) +#define S3C2410_SDIDCNT_BLKNUM_SHIFT (12) + +#define S3C2410_SDIDSTA_RDYWAITREQ (1<<10) +#define S3C2410_SDIDSTA_SDIOIRQDETECT (1<<9) +#define S3C2410_SDIDSTA_FIFOFAIL (1<<8) /* reserved on 2440 */ +#define S3C2410_SDIDSTA_CRCFAIL (1<<7) +#define S3C2410_SDIDSTA_RXCRCFAIL (1<<6) +#define S3C2410_SDIDSTA_DATATIMEOUT (1<<5) +#define S3C2410_SDIDSTA_XFERFINISH (1<<4) +#define S3C2410_SDIDSTA_BUSYFINISH (1<<3) +#define S3C2410_SDIDSTA_SBITERR (1<<2) /* reserved on 2410a/2440 */ +#define S3C2410_SDIDSTA_TXDATAON (1<<1) +#define S3C2410_SDIDSTA_RXDATAON (1<<0) + +#define S3C2440_SDIFSTA_FIFORESET (1<<16) +#define S3C2440_SDIFSTA_FIFOFAIL (3<<14) /* 3 is correct (2 bits) */ +#define S3C2410_SDIFSTA_TFDET (1<<13) +#define S3C2410_SDIFSTA_RFDET (1<<12) +#define S3C2410_SDIFSTA_TFHALF (1<<11) +#define S3C2410_SDIFSTA_TFEMPTY (1<<10) +#define S3C2410_SDIFSTA_RFLAST (1<<9) +#define S3C2410_SDIFSTA_RFFULL (1<<8) +#define S3C2410_SDIFSTA_RFHALF (1<<7) +#define S3C2410_SDIFSTA_COUNTMASK (0x7f) + +#define S3C2410_SDIIMSK_RESPONSECRC (1<<17) +#define S3C2410_SDIIMSK_CMDSENT (1<<16) +#define S3C2410_SDIIMSK_CMDTIMEOUT (1<<15) +#define S3C2410_SDIIMSK_RESPONSEND (1<<14) +#define S3C2410_SDIIMSK_READWAIT (1<<13) +#define S3C2410_SDIIMSK_SDIOIRQ (1<<12) +#define S3C2410_SDIIMSK_FIFOFAIL (1<<11) +#define S3C2410_SDIIMSK_CRCSTATUS (1<<10) +#define S3C2410_SDIIMSK_DATACRC (1<<9) +#define S3C2410_SDIIMSK_DATATIMEOUT (1<<8) +#define S3C2410_SDIIMSK_DATAFINISH (1<<7) +#define S3C2410_SDIIMSK_BUSYFINISH (1<<6) +#define S3C2410_SDIIMSK_SBITERR (1<<5) /* reserved 2440/2410a */ +#define S3C2410_SDIIMSK_TXFIFOHALF (1<<4) +#define S3C2410_SDIIMSK_TXFIFOEMPTY (1<<3) +#define S3C2410_SDIIMSK_RXFIFOLAST (1<<2) +#define S3C2410_SDIIMSK_RXFIFOFULL (1<<1) +#define S3C2410_SDIIMSK_RXFIFOHALF (1<<0) + +#endif /* __ASM_ARM_REGS_SDI */ diff --git a/arch/arm/mach-s3c24xx/include/mach/tick.h b/arch/arm/mach-s3c24xx/include/mach/tick.h new file mode 100644 index 00000000..544da419 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/tick.h @@ -0,0 +1,15 @@ +/* linux/arch/arm/mach-s3c2410/include/mach/tick.h + * + * Copyright 2008 Simtec Electronics + * Ben Dooks + * 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; +} diff --git a/arch/arm/mach-s3c24xx/include/mach/timex.h b/arch/arm/mach-s3c24xx/include/mach/timex.h new file mode 100644 index 00000000..fe9ca1ff --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/timex.h @@ -0,0 +1,24 @@ +/* arch/arm/mach-s3c2410/include/mach/timex.h + * + * Copyright (c) 2003-2005 Simtec Electronics + * Ben Dooks + * + * 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 + +/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it + * a variable is useless. It seems as long as we make our timers an + * exact multiple of HZ, any value that makes a 1->1 correspondence + * for the time conversion functions to/from jiffies is acceptable. +*/ + +#define CLOCK_TICK_RATE 12000000 + +#endif /* __ASM_ARCH_TIMEX_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/uncompress.h b/arch/arm/mach-s3c24xx/include/mach/uncompress.h new file mode 100644 index 00000000..8b283f84 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/uncompress.h @@ -0,0 +1,54 @@ +/* arch/arm/mach-s3c2410/include/mach/uncompress.h + * + * Copyright (c) 2003-2007 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * S3C2410 - 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 +#include + +/* working in physical space... */ +#undef S3C2410_GPIOREG +#define S3C2410_GPIOREG(x) ((S3C24XX_PA_GPIO + (x))) + +#include + +static inline int is_arm926(void) +{ + unsigned int cpuid; + + asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (cpuid)); + + return ((cpuid & 0xff0) == 0x260); +} + +static void arch_detect_cpu(void) +{ + unsigned int cpuid; + + cpuid = *((volatile unsigned int *)S3C2410_GSTATUS1); + cpuid &= S3C2410_GSTATUS1_IDMASK; + + if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 || + cpuid == S3C2410_GSTATUS1_2442 || + cpuid == S3C2410_GSTATUS1_2416 || + cpuid == S3C2410_GSTATUS1_2450) { + fifo_mask = S3C2440_UFSTAT_TXMASK; + fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT; + } else { + fifo_mask = S3C2410_UFSTAT_TXMASK; + fifo_max = 15 << S3C2410_UFSTAT_TXSHIFT; + } +} + +#endif /* __ASM_ARCH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/vr1000-cpld.h b/arch/arm/mach-s3c24xx/include/mach/vr1000-cpld.h new file mode 100644 index 00000000..e4119913 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/vr1000-cpld.h @@ -0,0 +1,18 @@ +/* arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h + * + * Copyright (c) 2003 Simtec Electronics + * Ben Dooks + * + * VR1000 - CPLD control constants + * + * 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_VR1000CPLD_H +#define __ASM_ARCH_VR1000CPLD_H + +#define VR1000_CPLD_CTRL2_RAMWEN (0x04) /* SRAM Write Enable */ + +#endif /* __ASM_ARCH_VR1000CPLD_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/vr1000-irq.h b/arch/arm/mach-s3c24xx/include/mach/vr1000-irq.h new file mode 100644 index 00000000..47add133 --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/vr1000-irq.h @@ -0,0 +1,26 @@ +/* arch/arm/mach-s3c2410/include/mach/vr1000-irq.h + * + * Copyright (c) 2003-2004 Simtec Electronics + * Ben Dooks + * + * Machine VR1000 - IRQ Number 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_VR1000IRQ_H +#define __ASM_ARCH_VR1000IRQ_H + +/* irq numbers to onboard peripherals */ + +#define IRQ_USBOC IRQ_EINT19 +#define IRQ_IDE0 IRQ_EINT16 +#define IRQ_IDE1 IRQ_EINT17 +#define IRQ_VR1000_SERIAL IRQ_EINT12 +#define IRQ_VR1000_DM9000A IRQ_EINT10 +#define IRQ_VR1000_DM9000N IRQ_EINT9 +#define IRQ_SMALERT IRQ_EINT8 + +#endif /* __ASM_ARCH_VR1000IRQ_H */ diff --git a/arch/arm/mach-s3c24xx/include/mach/vr1000-map.h b/arch/arm/mach-s3c24xx/include/mach/vr1000-map.h new file mode 100644 index 00000000..99612fcc --- /dev/null +++ b/arch/arm/mach-s3c24xx/include/mach/vr1000-map.h @@ -0,0 +1,110 @@ +/* arch/arm/mach-s3c2410/include/mach/vr1000-map.h + * + * Copyright (c) 2003-2005 Simtec Electronics + * Ben Dooks + * + * Machine VR1000 - 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. +*/ + +/* needs arch/map.h including with this */ + +/* ok, we've used up to 0x13000000, now we need to find space for the + * peripherals that live in the nGCS[x] areas, which are quite numerous + * in their space. We also have the board's CPLD to find register space + * for. + */ + +#ifndef __ASM_ARCH_VR1000MAP_H +#define __ASM_ARCH_VR1000MAP_H + +#include + +#define VR1000_IOADDR(x) BAST_IOADDR(x) + +/* we put the CPLD registers next, to get them out of the way */ + +#define VR1000_VA_CTRL1 VR1000_IOADDR(0x00000000) /* 0x01300000 */ +#define VR1000_PA_CTRL1 (S3C2410_CS5 | 0x7800000) + +#define VR1000_VA_CTRL2 VR1000_IOADDR(0x00100000) /* 0x01400000 */ +#define VR1000_PA_CTRL2 (S3C2410_CS1 | 0x6000000) + +#define VR1000_VA_CTRL3 VR1000_IOADDR(0x00200000) /* 0x01500000 */ +#define VR1000_PA_CTRL3 (S3C2410_CS1 | 0x6800000) + +#define VR1000_VA_CTRL4 VR1000_IOADDR(0x00300000) /* 0x01600000 */ +#define VR1000_PA_CTRL4 (S3C2410_CS1 | 0x7000000) + +/* next, we have the PC104 ISA interrupt registers */ + +#define VR1000_PA_PC104_IRQREQ (S3C2410_CS5 | 0x6000000) /* 0x01700000 */ +#define VR1000_VA_PC104_IRQREQ VR1000_IOADDR(0x00400000) + +#define VR1000_PA_PC104_IRQRAW (S3C2410_CS5 | 0x6800000) /* 0x01800000 */ +#define VR1000_VA_PC104_IRQRAW VR1000_IOADDR(0x00500000) + +#define VR1000_PA_PC104_IRQMASK (S3C2410_CS5 | 0x7000000) /* 0x01900000 */ +#define VR1000_VA_PC104_IRQMASK VR1000_IOADDR(0x00600000) + +/* 0xE0000000 contains the IO space that is split by speed and + * wether the access is for 8 or 16bit IO... this ensures that + * the correct access is made + * + * 0x10000000 of space, partitioned as so: + * + * 0x00000000 to 0x04000000 8bit, slow + * 0x04000000 to 0x08000000 16bit, slow + * 0x08000000 to 0x0C000000 16bit, net + * 0x0C000000 to 0x10000000 16bit, fast + * + * each of these spaces has the following in: + * + * 0x02000000 to 0x02100000 1MB IDE primary channel + * 0x02100000 to 0x02200000 1MB IDE primary channel aux + * 0x02200000 to 0x02400000 1MB IDE secondary channel + * 0x02300000 to 0x02400000 1MB IDE secondary channel aux + * 0x02500000 to 0x02600000 1MB Davicom DM9000 ethernet controllers + * 0x02600000 to 0x02700000 1MB + * + * the phyiscal layout of the zones are: + * nGCS2 - 8bit, slow + * nGCS3 - 16bit, slow + * nGCS4 - 16bit, net + * nGCS5 - 16bit, fast + */ + +#define VR1000_VA_MULTISPACE (0xE0000000) + +#define VR1000_VA_ISAIO (VR1000_VA_MULTISPACE + 0x00000000) +#define VR1000_VA_ISAMEM (VR1000_VA_MULTISPACE + 0x01000000) +#define VR1000_VA_IDEPRI (VR1000_VA_MULTISPACE + 0x02000000) +#define VR1000_VA_IDEPRIAUX (VR1000_VA_MULTISPACE + 0x02100000) +#define VR1000_VA_IDESEC (VR1000_VA_MULTISPACE + 0x02200000) +#define VR1000_VA_IDESECAUX (VR1000_VA_MULTISPACE + 0x02300000) +#define VR1000_VA_ASIXNET (VR1000_VA_MULTISPACE + 0x02400000) +#define VR1000_VA_DM9000 (VR1000_VA_MULTISPACE + 0x02500000) +#define VR1000_VA_SUPERIO (VR1000_VA_MULTISPACE + 0x02600000) + +/* physical offset addresses for the peripherals */ + +#define VR1000_PA_IDEPRI (0x02000000) +#define VR1000_PA_IDEPRIAUX (0x02800000) +#define VR1000_PA_IDESEC (0x03000000) +#define VR1000_PA_IDESECAUX (0x03800000) +#define VR1000_PA_DM9000 (0x05000000) + +#define VR1000_PA_SERIAL (0x11800000) +#define VR1000_VA_SERIAL (VR1000_IOADDR(0x00700000)) + +/* VR1000 ram is in CS1, with A26..A24 = 2_101 */ +#define VR1000_PA_SRAM (S3C2410_CS1 | 0x05000000) + +/* some configurations for the peripherals */ + +#define VR1000_DM9000_CS VR1000_VAM_CS4 + +#endif /* __ASM_ARCH_VR1000MAP_H */ diff --git a/arch/arm/mach-s3c24xx/irq-s3c2412.c b/arch/arm/mach-s3c24xx/irq-s3c2412.c new file mode 100644 index 00000000..e65619dd --- /dev/null +++ b/arch/arm/mach-s3c24xx/irq-s3c2412.c @@ -0,0 +1,214 @@ +/* linux/arch/arm/mach-s3c2412/irq.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1) +#define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0)))) + +/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by + * having them turn up in both the INT* and the EINT* registers. Whilst + * both show the status, they both now need to be acked when the IRQs + * go off. +*/ + +static void +s3c2412_irq_mask(struct irq_data *data) +{ + unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); + unsigned long mask; + + mask = __raw_readl(S3C2410_INTMSK); + __raw_writel(mask | bitval, S3C2410_INTMSK); + + mask = __raw_readl(S3C2412_EINTMASK); + __raw_writel(mask | bitval, S3C2412_EINTMASK); +} + +static inline void +s3c2412_irq_ack(struct irq_data *data) +{ + unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); + + __raw_writel(bitval, S3C2412_EINTPEND); + __raw_writel(bitval, S3C2410_SRCPND); + __raw_writel(bitval, S3C2410_INTPND); +} + +static inline void +s3c2412_irq_maskack(struct irq_data *data) +{ + unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); + unsigned long mask; + + mask = __raw_readl(S3C2410_INTMSK); + __raw_writel(mask|bitval, S3C2410_INTMSK); + + mask = __raw_readl(S3C2412_EINTMASK); + __raw_writel(mask | bitval, S3C2412_EINTMASK); + + __raw_writel(bitval, S3C2412_EINTPEND); + __raw_writel(bitval, S3C2410_SRCPND); + __raw_writel(bitval, S3C2410_INTPND); +} + +static void +s3c2412_irq_unmask(struct irq_data *data) +{ + unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); + unsigned long mask; + + mask = __raw_readl(S3C2412_EINTMASK); + __raw_writel(mask & ~bitval, S3C2412_EINTMASK); + + mask = __raw_readl(S3C2410_INTMSK); + __raw_writel(mask & ~bitval, S3C2410_INTMSK); +} + +static struct irq_chip s3c2412_irq_eint0t4 = { + .irq_ack = s3c2412_irq_ack, + .irq_mask = s3c2412_irq_mask, + .irq_unmask = s3c2412_irq_unmask, + .irq_set_wake = s3c_irq_wake, + .irq_set_type = s3c_irqext_type, +}; + +#define INTBIT(x) (1 << ((x) - S3C2410_IRQSUB(0))) + +/* CF and SDI sub interrupts */ + +static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc) +{ + unsigned int subsrc, submsk; + + subsrc = __raw_readl(S3C2410_SUBSRCPND); + submsk = __raw_readl(S3C2410_INTSUBMSK); + + subsrc &= ~submsk; + + if (subsrc & INTBIT(IRQ_S3C2412_SDI)) + generic_handle_irq(IRQ_S3C2412_SDI); + + if (subsrc & INTBIT(IRQ_S3C2412_CF)) + generic_handle_irq(IRQ_S3C2412_CF); +} + +#define INTMSK_CFSDI (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0)) +#define SUBMSK_CFSDI INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF) + +static void s3c2412_irq_cfsdi_mask(struct irq_data *data) +{ + s3c_irqsub_mask(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI); +} + +static void s3c2412_irq_cfsdi_unmask(struct irq_data *data) +{ + s3c_irqsub_unmask(data->irq, INTMSK_CFSDI); +} + +static void s3c2412_irq_cfsdi_ack(struct irq_data *data) +{ + s3c_irqsub_maskack(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI); +} + +static struct irq_chip s3c2412_irq_cfsdi = { + .name = "s3c2412-cfsdi", + .irq_ack = s3c2412_irq_cfsdi_ack, + .irq_mask = s3c2412_irq_cfsdi_mask, + .irq_unmask = s3c2412_irq_cfsdi_unmask, +}; + +static int s3c2412_irq_rtc_wake(struct irq_data *data, unsigned int state) +{ + unsigned long pwrcfg; + + pwrcfg = __raw_readl(S3C2412_PWRCFG); + if (state) + pwrcfg &= ~S3C2412_PWRCFG_RTC_MASKIRQ; + else + pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ; + __raw_writel(pwrcfg, S3C2412_PWRCFG); + + return s3c_irq_chip.irq_set_wake(data, state); +} + +static struct irq_chip s3c2412_irq_rtc_chip; + +static int s3c2412_irq_add(struct device *dev, struct subsys_interface *sif) +{ + unsigned int irqno; + + for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { + irq_set_chip_and_handler(irqno, &s3c2412_irq_eint0t4, + handle_edge_irq); + set_irq_flags(irqno, IRQF_VALID); + } + + /* add demux support for CF/SDI */ + + irq_set_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi); + + for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) { + irq_set_chip_and_handler(irqno, &s3c2412_irq_cfsdi, + handle_level_irq); + set_irq_flags(irqno, IRQF_VALID); + } + + /* change RTC IRQ's set wake method */ + + s3c2412_irq_rtc_chip = s3c_irq_chip; + s3c2412_irq_rtc_chip.irq_set_wake = s3c2412_irq_rtc_wake; + + irq_set_chip(IRQ_RTC, &s3c2412_irq_rtc_chip); + + return 0; +} + +static struct subsys_interface s3c2412_irq_interface = { + .name = "s3c2412_irq", + .subsys = &s3c2412_subsys, + .add_dev = s3c2412_irq_add, +}; + +static int s3c2412_irq_init(void) +{ + return subsys_interface_register(&s3c2412_irq_interface); +} + +arch_initcall(s3c2412_irq_init); diff --git a/arch/arm/mach-s3c24xx/irq-s3c2416.c b/arch/arm/mach-s3c24xx/irq-s3c2416.c new file mode 100644 index 00000000..fd49f35e --- /dev/null +++ b/arch/arm/mach-s3c24xx/irq-s3c2416.c @@ -0,0 +1,250 @@ +/* linux/arch/arm/mach-s3c2416/irq.c + * + * Copyright (c) 2009 Yauhen Kharuzhy , + * as part of OpenInkpot project + * Copyright (c) 2009 Promwad Innovation Company + * Yauhen Kharuzhy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1) + +static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len) +{ + unsigned int subsrc, submsk; + unsigned int end; + + /* read the current pending interrupts, and the mask + * for what it is available */ + + subsrc = __raw_readl(S3C2410_SUBSRCPND); + submsk = __raw_readl(S3C2410_INTSUBMSK); + + subsrc &= ~submsk; + subsrc >>= (irq - S3C2410_IRQSUB(0)); + subsrc &= (1 << len)-1; + + end = len + irq; + + for (; irq < end && subsrc; irq++) { + if (subsrc & 1) + generic_handle_irq(irq); + + subsrc >>= 1; + } +} + +/* WDT/AC97 sub interrupts */ + +static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc) +{ + s3c2416_irq_demux(IRQ_S3C2443_WDT, 4); +} + +#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0)) +#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97) + +static void s3c2416_irq_wdtac97_mask(struct irq_data *data) +{ + s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97); +} + +static void s3c2416_irq_wdtac97_unmask(struct irq_data *data) +{ + s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97); +} + +static void s3c2416_irq_wdtac97_ack(struct irq_data *data) +{ + s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97); +} + +static struct irq_chip s3c2416_irq_wdtac97 = { + .irq_mask = s3c2416_irq_wdtac97_mask, + .irq_unmask = s3c2416_irq_wdtac97_unmask, + .irq_ack = s3c2416_irq_wdtac97_ack, +}; + +/* LCD sub interrupts */ + +static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc) +{ + s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4); +} + +#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) +#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4) + +static void s3c2416_irq_lcd_mask(struct irq_data *data) +{ + s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD); +} + +static void s3c2416_irq_lcd_unmask(struct irq_data *data) +{ + s3c_irqsub_unmask(data->irq, INTMSK_LCD); +} + +static void s3c2416_irq_lcd_ack(struct irq_data *data) +{ + s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD); +} + +static struct irq_chip s3c2416_irq_lcd = { + .irq_mask = s3c2416_irq_lcd_mask, + .irq_unmask = s3c2416_irq_lcd_unmask, + .irq_ack = s3c2416_irq_lcd_ack, +}; + +/* DMA sub interrupts */ + +static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc) +{ + s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6); +} + +#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0)) +#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5) + + +static void s3c2416_irq_dma_mask(struct irq_data *data) +{ + s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA); +} + +static void s3c2416_irq_dma_unmask(struct irq_data *data) +{ + s3c_irqsub_unmask(data->irq, INTMSK_DMA); +} + +static void s3c2416_irq_dma_ack(struct irq_data *data) +{ + s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA); +} + +static struct irq_chip s3c2416_irq_dma = { + .irq_mask = s3c2416_irq_dma_mask, + .irq_unmask = s3c2416_irq_dma_unmask, + .irq_ack = s3c2416_irq_dma_ack, +}; + +/* UART3 sub interrupts */ + +static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc) +{ + s3c2416_irq_demux(IRQ_S3C2443_RX3, 3); +} + +#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0)) +#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0))) + +static void s3c2416_irq_uart3_mask(struct irq_data *data) +{ + s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3); +} + +static void s3c2416_irq_uart3_unmask(struct irq_data *data) +{ + s3c_irqsub_unmask(data->irq, INTMSK_UART3); +} + +static void s3c2416_irq_uart3_ack(struct irq_data *data) +{ + s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3); +} + +static struct irq_chip s3c2416_irq_uart3 = { + .irq_mask = s3c2416_irq_uart3_mask, + .irq_unmask = s3c2416_irq_uart3_unmask, + .irq_ack = s3c2416_irq_uart3_ack, +}; + +/* IRQ initialisation code */ + +static int __init s3c2416_add_sub(unsigned int base, + void (*demux)(unsigned int, + struct irq_desc *), + struct irq_chip *chip, + unsigned int start, unsigned int end) +{ + unsigned int irqno; + + irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq); + irq_set_chained_handler(base, demux); + + for (irqno = start; irqno <= end; irqno++) { + irq_set_chip_and_handler(irqno, chip, handle_level_irq); + set_irq_flags(irqno, IRQF_VALID); + } + + return 0; +} + +static int __init s3c2416_irq_add(struct device *dev, + struct subsys_interface *sif) +{ + printk(KERN_INFO "S3C2416: IRQ Support\n"); + + s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd, + IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4); + + s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma, + &s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5); + + s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3, + &s3c2416_irq_uart3, + IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3); + + s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97, + &s3c2416_irq_wdtac97, + IRQ_S3C2443_WDT, IRQ_S3C2443_AC97); + + return 0; +} + +static struct subsys_interface s3c2416_irq_interface = { + .name = "s3c2416_irq", + .subsys = &s3c2416_subsys, + .add_dev = s3c2416_irq_add, +}; + +static int __init s3c2416_irq_init(void) +{ + return subsys_interface_register(&s3c2416_irq_interface); +} + +arch_initcall(s3c2416_irq_init); + diff --git a/arch/arm/mach-s3c24xx/irq-s3c2440.c b/arch/arm/mach-s3c24xx/irq-s3c2440.c new file mode 100644 index 00000000..4a18cde4 --- /dev/null +++ b/arch/arm/mach-s3c24xx/irq-s3c2440.c @@ -0,0 +1,128 @@ +/* linux/arch/arm/mach-s3c2440/irq.c + * + * Copyright (c) 2003-2004 Simtec Electronics + * Ben Dooks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +/* WDT/AC97 */ + +static void s3c_irq_demux_wdtac97(unsigned int irq, + struct irq_desc *desc) +{ + unsigned int subsrc, submsk; + + /* read the current pending interrupts, and the mask + * for what it is available */ + + subsrc = __raw_readl(S3C2410_SUBSRCPND); + submsk = __raw_readl(S3C2410_INTSUBMSK); + + subsrc &= ~submsk; + subsrc >>= 13; + subsrc &= 3; + + if (subsrc != 0) { + if (subsrc & 1) { + generic_handle_irq(IRQ_S3C2440_WDT); + } + if (subsrc & 2) { + generic_handle_irq(IRQ_S3C2440_AC97); + } + } +} + + +#define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0)) + +static void +s3c_irq_wdtac97_mask(struct irq_data *data) +{ + s3c_irqsub_mask(data->irq, INTMSK_WDT, 3 << 13); +} + +static void +s3c_irq_wdtac97_unmask(struct irq_data *data) +{ + s3c_irqsub_unmask(data->irq, INTMSK_WDT); +} + +static void +s3c_irq_wdtac97_ack(struct irq_data *data) +{ + s3c_irqsub_maskack(data->irq, INTMSK_WDT, 3 << 13); +} + +static struct irq_chip s3c_irq_wdtac97 = { + .irq_mask = s3c_irq_wdtac97_mask, + .irq_unmask = s3c_irq_wdtac97_unmask, + .irq_ack = s3c_irq_wdtac97_ack, +}; + +static int s3c2440_irq_add(struct device *dev, struct subsys_interface *sif) +{ + unsigned int irqno; + + printk("S3C2440: IRQ Support\n"); + + /* add new chained handler for wdt, ac7 */ + + irq_set_chip_and_handler(IRQ_WDT, &s3c_irq_level_chip, + handle_level_irq); + irq_set_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97); + + for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) { + irq_set_chip_and_handler(irqno, &s3c_irq_wdtac97, + handle_level_irq); + set_irq_flags(irqno, IRQF_VALID); + } + + return 0; +} + +static struct subsys_interface s3c2440_irq_interface = { + .name = "s3c2440_irq", + .subsys = &s3c2440_subsys, + .add_dev = s3c2440_irq_add, +}; + +static int s3c2440_irq_init(void) +{ + return subsys_interface_register(&s3c2440_irq_interface); +} + +arch_initcall(s3c2440_irq_init); + diff --git a/arch/arm/mach-s3c24xx/irq-s3c2443.c b/arch/arm/mach-s3c24xx/irq-s3c2443.c new file mode 100644 index 00000000..ac2829f5 --- /dev/null +++ b/arch/arm/mach-s3c24xx/irq-s3c2443.c @@ -0,0 +1,281 @@ +/* linux/arch/arm/mach-s3c2443/irq.c + * + * Copyright (c) 2007 Simtec Electronics + * Ben Dooks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1) + +static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len) +{ + unsigned int subsrc, submsk; + unsigned int end; + + /* read the current pending interrupts, and the mask + * for what it is available */ + + subsrc = __raw_readl(S3C2410_SUBSRCPND); + submsk = __raw_readl(S3C2410_INTSUBMSK); + + subsrc &= ~submsk; + subsrc >>= (irq - S3C2410_IRQSUB(0)); + subsrc &= (1 << len)-1; + + end = len + irq; + + for (; irq < end && subsrc; irq++) { + if (subsrc & 1) + generic_handle_irq(irq); + + subsrc >>= 1; + } +} + +/* WDT/AC97 sub interrupts */ + +static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc) +{ + s3c2443_irq_demux(IRQ_S3C2443_WDT, 4); +} + +#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0)) +#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97) + +static void s3c2443_irq_wdtac97_mask(struct irq_data *data) +{ + s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97); +} + +static void s3c2443_irq_wdtac97_unmask(struct irq_data *data) +{ + s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97); +} + +static void s3c2443_irq_wdtac97_ack(struct irq_data *data) +{ + s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97); +} + +static struct irq_chip s3c2443_irq_wdtac97 = { + .irq_mask = s3c2443_irq_wdtac97_mask, + .irq_unmask = s3c2443_irq_wdtac97_unmask, + .irq_ack = s3c2443_irq_wdtac97_ack, +}; + +/* LCD sub interrupts */ + +static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc) +{ + s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4); +} + +#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) +#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4) + +static void s3c2443_irq_lcd_mask(struct irq_data *data) +{ + s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD); +} + +static void s3c2443_irq_lcd_unmask(struct irq_data *data) +{ + s3c_irqsub_unmask(data->irq, INTMSK_LCD); +} + +static void s3c2443_irq_lcd_ack(struct irq_data *data) +{ + s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD); +} + +static struct irq_chip s3c2443_irq_lcd = { + .irq_mask = s3c2443_irq_lcd_mask, + .irq_unmask = s3c2443_irq_lcd_unmask, + .irq_ack = s3c2443_irq_lcd_ack, +}; + +/* DMA sub interrupts */ + +static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc) +{ + s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6); +} + +#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0)) +#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5) + +static void s3c2443_irq_dma_mask(struct irq_data *data) +{ + s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA); +} + +static void s3c2443_irq_dma_unmask(struct irq_data *data) +{ + s3c_irqsub_unmask(data->irq, INTMSK_DMA); +} + +static void s3c2443_irq_dma_ack(struct irq_data *data) +{ + s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA); +} + +static struct irq_chip s3c2443_irq_dma = { + .irq_mask = s3c2443_irq_dma_mask, + .irq_unmask = s3c2443_irq_dma_unmask, + .irq_ack = s3c2443_irq_dma_ack, +}; + +/* UART3 sub interrupts */ + +static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc) +{ + s3c2443_irq_demux(IRQ_S3C2443_RX3, 3); +} + +#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0)) +#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0))) + +static void s3c2443_irq_uart3_mask(struct irq_data *data) +{ + s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3); +} + +static void s3c2443_irq_uart3_unmask(struct irq_data *data) +{ + s3c_irqsub_unmask(data->irq, INTMSK_UART3); +} + +static void s3c2443_irq_uart3_ack(struct irq_data *data) +{ + s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3); +} + +static struct irq_chip s3c2443_irq_uart3 = { + .irq_mask = s3c2443_irq_uart3_mask, + .irq_unmask = s3c2443_irq_uart3_unmask, + .irq_ack = s3c2443_irq_uart3_ack, +}; + +/* CAM sub interrupts */ + +static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc) +{ + s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4); +} + +#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0)) +#define SUBMSK_CAM INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P) + +static void s3c2443_irq_cam_mask(struct irq_data *data) +{ + s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM); +} + +static void s3c2443_irq_cam_unmask(struct irq_data *data) +{ + s3c_irqsub_unmask(data->irq, INTMSK_CAM); +} + +static void s3c2443_irq_cam_ack(struct irq_data *data) +{ + s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM); +} + +static struct irq_chip s3c2443_irq_cam = { + .irq_mask = s3c2443_irq_cam_mask, + .irq_unmask = s3c2443_irq_cam_unmask, + .irq_ack = s3c2443_irq_cam_ack, +}; + +/* IRQ initialisation code */ + +static int __init s3c2443_add_sub(unsigned int base, + void (*demux)(unsigned int, + struct irq_desc *), + struct irq_chip *chip, + unsigned int start, unsigned int end) +{ + unsigned int irqno; + + irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq); + irq_set_chained_handler(base, demux); + + for (irqno = start; irqno <= end; irqno++) { + irq_set_chip_and_handler(irqno, chip, handle_level_irq); + set_irq_flags(irqno, IRQF_VALID); + } + + return 0; +} + +static int __init s3c2443_irq_add(struct device *dev, + struct subsys_interface *sif) +{ + printk("S3C2443: IRQ Support\n"); + + s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam, + IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P); + + s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd, + IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4); + + s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma, + &s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5); + + s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3, + &s3c2443_irq_uart3, + IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3); + + s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97, + &s3c2443_irq_wdtac97, + IRQ_S3C2443_WDT, IRQ_S3C2443_AC97); + + return 0; +} + +static struct subsys_interface s3c2443_irq_interface = { + .name = "s3c2443_irq", + .subsys = &s3c2443_subsys, + .add_dev = s3c2443_irq_add, +}; + +static int __init s3c2443_irq_init(void) +{ + return subsys_interface_register(&s3c2443_irq_interface); +} + +arch_initcall(s3c2443_irq_init); + diff --git a/arch/arm/mach-s3c24xx/irq-s3c244x.c b/arch/arm/mach-s3c24xx/irq-s3c244x.c new file mode 100644 index 00000000..5fe8e58d --- /dev/null +++ b/arch/arm/mach-s3c24xx/irq-s3c244x.c @@ -0,0 +1,142 @@ +/* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c + * + * Copyright (c) 2003-2004 Simtec Electronics + * Ben Dooks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +/* camera irq */ + +static void s3c_irq_demux_cam(unsigned int irq, + struct irq_desc *desc) +{ + unsigned int subsrc, submsk; + + /* read the current pending interrupts, and the mask + * for what it is available */ + + subsrc = __raw_readl(S3C2410_SUBSRCPND); + submsk = __raw_readl(S3C2410_INTSUBMSK); + + subsrc &= ~submsk; + subsrc >>= 11; + subsrc &= 3; + + if (subsrc != 0) { + if (subsrc & 1) { + generic_handle_irq(IRQ_S3C2440_CAM_C); + } + if (subsrc & 2) { + generic_handle_irq(IRQ_S3C2440_CAM_P); + } + } +} + +#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0)) + +static void +s3c_irq_cam_mask(struct irq_data *data) +{ + s3c_irqsub_mask(data->irq, INTMSK_CAM, 3 << 11); +} + +static void +s3c_irq_cam_unmask(struct irq_data *data) +{ + s3c_irqsub_unmask(data->irq, INTMSK_CAM); +} + +static void +s3c_irq_cam_ack(struct irq_data *data) +{ + s3c_irqsub_maskack(data->irq, INTMSK_CAM, 3 << 11); +} + +static struct irq_chip s3c_irq_cam = { + .irq_mask = s3c_irq_cam_mask, + .irq_unmask = s3c_irq_cam_unmask, + .irq_ack = s3c_irq_cam_ack, +}; + +static int s3c244x_irq_add(struct device *dev, struct subsys_interface *sif) +{ + unsigned int irqno; + + irq_set_chip_and_handler(IRQ_NFCON, &s3c_irq_level_chip, + handle_level_irq); + set_irq_flags(IRQ_NFCON, IRQF_VALID); + + /* add chained handler for camera */ + + irq_set_chip_and_handler(IRQ_CAM, &s3c_irq_level_chip, + handle_level_irq); + irq_set_chained_handler(IRQ_CAM, s3c_irq_demux_cam); + + for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) { + irq_set_chip_and_handler(irqno, &s3c_irq_cam, + handle_level_irq); + set_irq_flags(irqno, IRQF_VALID); + } + + return 0; +} + +static struct subsys_interface s3c2440_irq_interface = { + .name = "s3c2440_irq", + .subsys = &s3c2440_subsys, + .add_dev = s3c244x_irq_add, +}; + +static int s3c2440_irq_init(void) +{ + return subsys_interface_register(&s3c2440_irq_interface); +} + +arch_initcall(s3c2440_irq_init); + +static struct subsys_interface s3c2442_irq_interface = { + .name = "s3c2442_irq", + .subsys = &s3c2442_subsys, + .add_dev = s3c244x_irq_add, +}; + + +static int s3c2442_irq_init(void) +{ + return subsys_interface_register(&s3c2442_irq_interface); +} + +arch_initcall(s3c2442_irq_init); diff --git a/arch/arm/mach-s3c24xx/mach-amlm5900.c b/arch/arm/mach-s3c24xx/mach-amlm5900.c new file mode 100644 index 00000000..4220cc60 --- /dev/null +++ b/arch/arm/mach-s3c24xx/mach-amlm5900.c @@ -0,0 +1,247 @@ +/* linux/arch/arm/mach-s3c2410/mach-amlm5900.c + * + * linux/arch/arm/mach-s3c2410/mach-amlm5900.c + * + * Copyright (c) 2006 American Microsystems Limited + * David Anders + + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * @History: + * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by + * Ben Dooks + * + ***********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "common.h" + +static struct resource amlm5900_nor_resource = { + .start = 0x00000000, + .end = 0x01000000 - 1, + .flags = IORESOURCE_MEM, +}; + + + +static struct mtd_partition amlm5900_mtd_partitions[] = { + { + .name = "System", + .size = 0x240000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "Kernel", + .size = 0x100000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "Ramdisk", + .size = 0x300000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "JFFS2", + .size = 0x9A0000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "Settings", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct physmap_flash_data amlm5900_flash_data = { + .width = 2, + .parts = amlm5900_mtd_partitions, + .nr_parts = ARRAY_SIZE(amlm5900_mtd_partitions), +}; + +static struct platform_device amlm5900_device_nor = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &amlm5900_flash_data, + }, + .num_resources = 1, + .resource = &amlm5900_nor_resource, +}; + +static struct map_desc amlm5900_iodesc[] __initdata = { +}; + +#define UCON S3C2410_UCON_DEFAULT +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE + +static struct s3c2410_uartcfg amlm5900_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + } +}; + + +static struct platform_device *amlm5900_devices[] __initdata = { +#ifdef CONFIG_FB_S3C2410 + &s3c_device_lcd, +#endif + &s3c_device_adc, + &s3c_device_wdt, + &s3c_device_i2c0, + &s3c_device_ohci, + &s3c_device_rtc, + &s3c_device_usbgadget, + &s3c_device_sdi, + &amlm5900_device_nor, +}; + +static void __init amlm5900_map_io(void) +{ + s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc)); + s3c24xx_init_clocks(0); + s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs)); +} + +#ifdef CONFIG_FB_S3C2410 +static struct s3c2410fb_display __initdata amlm5900_lcd_info = { + .width = 160, + .height = 160, + + .type = S3C2410_LCDCON1_STN4, + + .pixclock = 680000, /* HCLK = 100MHz */ + .xres = 160, + .yres = 160, + .bpp = 4, + .left_margin = 1 << (4 + 3), + .right_margin = 8 << 3, + .hsync_len = 48, + .upper_margin = 0, + .lower_margin = 0, + + .lcdcon5 = 0x00000001, +}; + +static struct s3c2410fb_mach_info __initdata amlm5900_fb_info = { + + .displays = &amlm5900_lcd_info, + .num_displays = 1, + .default_display = 0, + + .gpccon = 0xaaaaaaaa, + .gpccon_mask = 0xffffffff, + .gpcup = 0x0000ffff, + .gpcup_mask = 0xffffffff, + + .gpdcon = 0xaaaaaaaa, + .gpdcon_mask = 0xffffffff, + .gpdup = 0x0000ffff, + .gpdup_mask = 0xffffffff, +}; +#endif + +static irqreturn_t +amlm5900_wake_interrupt(int irq, void *ignored) +{ + return IRQ_HANDLED; +} + +static void amlm5900_init_pm(void) +{ + int ret = 0; + + ret = request_irq(IRQ_EINT9, &amlm5900_wake_interrupt, + IRQF_TRIGGER_RISING | IRQF_SHARED, + "amlm5900_wakeup", &amlm5900_wake_interrupt); + if (ret != 0) { + printk(KERN_ERR "AML-M5900: no wakeup irq, %d?\n", ret); + } else { + enable_irq_wake(IRQ_EINT9); + /* configure the suspend/resume status pin */ + s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); + s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_UP); + } +} +static void __init amlm5900_init(void) +{ + amlm5900_init_pm(); +#ifdef CONFIG_FB_S3C2410 + s3c24xx_fb_set_platdata(&amlm5900_fb_info); +#endif + s3c_i2c0_set_platdata(NULL); + platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices)); +} + +MACHINE_START(AML_M5900, "AML_M5900") + .atag_offset = 0x100, + .map_io = amlm5900_map_io, + .init_irq = s3c24xx_init_irq, + .init_machine = amlm5900_init, + .timer = &s3c24xx_timer, + .restart = s3c2410_restart, +MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c new file mode 100644 index 00000000..60c72c54 --- /dev/null +++ b/arch/arm/mach-s3c24xx/mach-anubis.c @@ -0,0 +1,492 @@ +/* linux/arch/arm/mach-s3c2440/mach-anubis.c + * + * Copyright 2003-2009 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "simtec.h" +#include "common.h" + +#define COPYRIGHT ", Copyright 2005-2009 Simtec Electronics" + +static struct map_desc anubis_iodesc[] __initdata = { + /* ISA IO areas */ + + { + .virtual = (u32)S3C24XX_VA_ISA_BYTE, + .pfn = __phys_to_pfn(0x0), + .length = SZ_4M, + .type = MT_DEVICE, + }, { + .virtual = (u32)S3C24XX_VA_ISA_WORD, + .pfn = __phys_to_pfn(0x0), + .length = SZ_4M, + .type = MT_DEVICE, + }, + + /* we could possibly compress the next set down into a set of smaller tables + * pagetables, but that would mean using an L2 section, and it still means + * we cannot actually feed the same register to an LDR due to 16K spacing + */ + + /* CPLD control registers */ + + { + .virtual = (u32)ANUBIS_VA_CTRL1, + .pfn = __phys_to_pfn(ANUBIS_PA_CTRL1), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (u32)ANUBIS_VA_IDREG, + .pfn = __phys_to_pfn(ANUBIS_PA_IDREG), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE + +static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, + }, + [1] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, + }, +}; + +/* NAND Flash on Anubis board */ + +static int external_map[] = { 2 }; +static int chip0_map[] = { 0 }; +static int chip1_map[] = { 1 }; + +static struct mtd_partition __initdata anubis_default_nand_part[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_16K, + .offset = 0, + }, + [1] = { + .name = "/boot", + .size = SZ_4M - SZ_16K, + .offset = SZ_16K, + }, + [2] = { + .name = "user1", + .offset = SZ_4M, + .size = SZ_32M - SZ_4M, + }, + [3] = { + .name = "user2", + .offset = SZ_32M, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct mtd_partition __initdata anubis_default_nand_part_large[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_128K, + .offset = 0, + }, + [1] = { + .name = "/boot", + .size = SZ_4M - SZ_128K, + .offset = SZ_128K, + }, + [2] = { + .name = "user1", + .offset = SZ_4M, + .size = SZ_32M - SZ_4M, + }, + [3] = { + .name = "user2", + .offset = SZ_32M, + .size = MTDPART_SIZ_FULL, + } +}; + +/* the Anubis has 3 selectable slots for nand-flash, the two + * on-board chip areas, as well as the external slot. + * + * Note, there is no current hot-plug support for the External + * socket. +*/ + +static struct s3c2410_nand_set __initdata anubis_nand_sets[] = { + [1] = { + .name = "External", + .nr_chips = 1, + .nr_map = external_map, + .nr_partitions = ARRAY_SIZE(anubis_default_nand_part), + .partitions = anubis_default_nand_part, + }, + [0] = { + .name = "chip0", + .nr_chips = 1, + .nr_map = chip0_map, + .nr_partitions = ARRAY_SIZE(anubis_default_nand_part), + .partitions = anubis_default_nand_part, + }, + [2] = { + .name = "chip1", + .nr_chips = 1, + .nr_map = chip1_map, + .nr_partitions = ARRAY_SIZE(anubis_default_nand_part), + .partitions = anubis_default_nand_part, + }, +}; + +static void anubis_nand_select(struct s3c2410_nand_set *set, int slot) +{ + unsigned int tmp; + + slot = set->nr_map[slot] & 3; + + pr_debug("anubis_nand: selecting slot %d (set %p,%p)\n", + slot, set, set->nr_map); + + tmp = __raw_readb(ANUBIS_VA_CTRL1); + tmp &= ~ANUBIS_CTRL1_NANDSEL; + tmp |= slot; + + pr_debug("anubis_nand: ctrl1 now %02x\n", tmp); + + __raw_writeb(tmp, ANUBIS_VA_CTRL1); +} + +static struct s3c2410_platform_nand __initdata anubis_nand_info = { + .tacls = 25, + .twrph0 = 55, + .twrph1 = 40, + .nr_sets = ARRAY_SIZE(anubis_nand_sets), + .sets = anubis_nand_sets, + .select_chip = anubis_nand_select, +}; + +/* IDE channels */ + +static struct pata_platform_info anubis_ide_platdata = { + .ioport_shift = 5, +}; + +static struct resource anubis_ide0_resource[] = { + { + .start = S3C2410_CS3, + .end = S3C2410_CS3 + (8*32) - 1, + .flags = IORESOURCE_MEM, + }, { + .start = S3C2410_CS3 + (1<<26) + (6*32), + .end = S3C2410_CS3 + (1<<26) + (7*32) - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_IDE0, + .end = IRQ_IDE0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device anubis_device_ide0 = { + .name = "pata_platform", + .id = 0, + .num_resources = ARRAY_SIZE(anubis_ide0_resource), + .resource = anubis_ide0_resource, + .dev = { + .platform_data = &anubis_ide_platdata, + .coherent_dma_mask = ~0, + }, +}; + +static struct resource anubis_ide1_resource[] = { + { + .start = S3C2410_CS4, + .end = S3C2410_CS4 + (8*32) - 1, + .flags = IORESOURCE_MEM, + }, { + .start = S3C2410_CS4 + (1<<26) + (6*32), + .end = S3C2410_CS4 + (1<<26) + (7*32) - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_IDE0, + .end = IRQ_IDE0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device anubis_device_ide1 = { + .name = "pata_platform", + .id = 1, + .num_resources = ARRAY_SIZE(anubis_ide1_resource), + .resource = anubis_ide1_resource, + .dev = { + .platform_data = &anubis_ide_platdata, + .coherent_dma_mask = ~0, + }, +}; + +/* Asix AX88796 10/100 ethernet controller */ + +static struct ax_plat_data anubis_asix_platdata = { + .flags = AXFLG_MAC_FROMDEV, + .wordlength = 2, + .dcr_val = 0x48, + .rcr_val = 0x40, +}; + +static struct resource anubis_asix_resource[] = { + [0] = { + .start = S3C2410_CS5, + .end = S3C2410_CS5 + (0x20 * 0x20) -1, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = IRQ_ASIX, + .end = IRQ_ASIX, + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device anubis_device_asix = { + .name = "ax88796", + .id = 0, + .num_resources = ARRAY_SIZE(anubis_asix_resource), + .resource = anubis_asix_resource, + .dev = { + .platform_data = &anubis_asix_platdata, + } +}; + +/* SM501 */ + +static struct resource anubis_sm501_resource[] = { + [0] = { + .start = S3C2410_CS2, + .end = S3C2410_CS2 + SZ_8M, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = S3C2410_CS2 + SZ_64M - SZ_2M, + .end = S3C2410_CS2 + SZ_64M - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_EINT0, + .end = IRQ_EINT0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sm501_initdata anubis_sm501_initdata = { + .gpio_high = { + .set = 0x3F000000, /* 24bit panel */ + .mask = 0x0, + }, + .misc_timing = { + .set = 0x010100, /* SDRAM timing */ + .mask = 0x1F1F00, + }, + .misc_control = { + .set = SM501_MISC_PNL_24BIT, + .mask = 0, + }, + + .devices = SM501_USE_GPIO, + + /* set the SDRAM and bus clocks */ + .mclk = 72 * MHZ, + .m1xclk = 144 * MHZ, +}; + +static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c[] = { + [0] = { + .bus_num = 1, + .pin_scl = 44, + .pin_sda = 45, + }, + [1] = { + .bus_num = 2, + .pin_scl = 40, + .pin_sda = 41, + }, +}; + +static struct sm501_platdata anubis_sm501_platdata = { + .init = &anubis_sm501_initdata, + .gpio_base = -1, + .gpio_i2c = anubis_sm501_gpio_i2c, + .gpio_i2c_nr = ARRAY_SIZE(anubis_sm501_gpio_i2c), +}; + +static struct platform_device anubis_device_sm501 = { + .name = "sm501", + .id = 0, + .num_resources = ARRAY_SIZE(anubis_sm501_resource), + .resource = anubis_sm501_resource, + .dev = { + .platform_data = &anubis_sm501_platdata, + }, +}; + +/* Standard Anubis devices */ + +static struct platform_device *anubis_devices[] __initdata = { + &s3c_device_ohci, + &s3c_device_wdt, + &s3c_device_adc, + &s3c_device_i2c0, + &s3c_device_rtc, + &s3c_device_nand, + &anubis_device_ide0, + &anubis_device_ide1, + &anubis_device_asix, + &anubis_device_sm501, +}; + +static struct clk *anubis_clocks[] __initdata = { + &s3c24xx_dclk0, + &s3c24xx_dclk1, + &s3c24xx_clkout0, + &s3c24xx_clkout1, + &s3c24xx_uclk, +}; + +/* I2C devices. */ + +static struct i2c_board_info anubis_i2c_devs[] __initdata = { + { + I2C_BOARD_INFO("tps65011", 0x48), + .irq = IRQ_EINT20, + } +}; + +/* Audio setup */ +static struct s3c24xx_audio_simtec_pdata __initdata anubis_audio = { + .have_mic = 1, + .have_lout = 1, + .output_cdclk = 1, + .use_mpllin = 1, + .amp_gpio = S3C2410_GPB(2), + .amp_gain[0] = S3C2410_GPD(10), + .amp_gain[1] = S3C2410_GPD(11), +}; + +static void __init anubis_map_io(void) +{ + /* initialise the clocks */ + + s3c24xx_dclk0.parent = &clk_upll; + s3c24xx_dclk0.rate = 12*1000*1000; + + s3c24xx_dclk1.parent = &clk_upll; + s3c24xx_dclk1.rate = 24*1000*1000; + + s3c24xx_clkout0.parent = &s3c24xx_dclk0; + s3c24xx_clkout1.parent = &s3c24xx_dclk1; + + s3c24xx_uclk.parent = &s3c24xx_clkout1; + + s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks)); + + s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc)); + s3c24xx_init_clocks(0); + s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs)); + + /* check for the newer revision boards with large page nand */ + + if ((__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK) >= 4) { + printk(KERN_INFO "ANUBIS-B detected (revision %d)\n", + __raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK); + anubis_nand_sets[0].partitions = anubis_default_nand_part_large; + anubis_nand_sets[0].nr_partitions = ARRAY_SIZE(anubis_default_nand_part_large); + } else { + /* ensure that the GPIO is setup */ + s3c2410_gpio_setpin(S3C2410_GPA(0), 1); + } +} + +static void __init anubis_init(void) +{ + s3c_i2c0_set_platdata(NULL); + s3c_nand_set_platdata(&anubis_nand_info); + simtec_audio_add(NULL, false, &anubis_audio); + + platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices)); + + i2c_register_board_info(0, anubis_i2c_devs, + ARRAY_SIZE(anubis_i2c_devs)); +} + + +MACHINE_START(ANUBIS, "Simtec-Anubis") + /* Maintainer: Ben Dooks */ + .atag_offset = 0x100, + .map_io = anubis_map_io, + .init_machine = anubis_init, + .init_irq = s3c24xx_init_irq, + .timer = &s3c24xx_timer, + .restart = s3c244x_restart, +MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-at2440evb.c b/arch/arm/mach-s3c24xx/mach-at2440evb.c new file mode 100644 index 00000000..d7ae49c9 --- /dev/null +++ b/arch/arm/mach-s3c24xx/mach-at2440evb.c @@ -0,0 +1,226 @@ +/* linux/arch/arm/mach-s3c2440/mach-at2440evb.c + * + * Copyright (c) 2008 Ramax Lo + * Based on mach-anubis.c by Ben Dooks + * and modifications by SBZ and + * Weibing + * + * For product information, visit http://www.arm.com/ + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "common.h" + +static struct map_desc at2440evb_iodesc[] __initdata = { + /* Nothing here */ +}; + +#define UCON S3C2410_UCON_DEFAULT +#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) +#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) + +static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, + }, +}; + +/* NAND Flash on AT2440EVB board */ + +static struct mtd_partition __initdata at2440evb_default_nand_part[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_256K, + .offset = 0, + }, + [1] = { + .name = "Kernel", + .size = SZ_2M, + .offset = SZ_256K, + }, + [2] = { + .name = "Root", + .offset = SZ_256K + SZ_2M, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct s3c2410_nand_set __initdata at2440evb_nand_sets[] = { + [0] = { + .name = "nand", + .nr_chips = 1, + .nr_partitions = ARRAY_SIZE(at2440evb_default_nand_part), + .partitions = at2440evb_default_nand_part, + }, +}; + +static struct s3c2410_platform_nand __initdata at2440evb_nand_info = { + .tacls = 25, + .twrph0 = 55, + .twrph1 = 40, + .nr_sets = ARRAY_SIZE(at2440evb_nand_sets), + .sets = at2440evb_nand_sets, +}; + +/* DM9000AEP 10/100 ethernet controller */ + +static struct resource at2440evb_dm9k_resource[] = { + [0] = { + .start = S3C2410_CS3, + .end = S3C2410_CS3 + 3, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = S3C2410_CS3 + 4, + .end = S3C2410_CS3 + 7, + .flags = IORESOURCE_MEM + }, + [2] = { + .start = IRQ_EINT7, + .end = IRQ_EINT7, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, + } +}; + +static struct dm9000_plat_data at2440evb_dm9k_pdata = { + .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM), +}; + +static struct platform_device at2440evb_device_eth = { + .name = "dm9000", + .id = -1, + .num_resources = ARRAY_SIZE(at2440evb_dm9k_resource), + .resource = at2440evb_dm9k_resource, + .dev = { + .platform_data = &at2440evb_dm9k_pdata, + }, +}; + +static struct s3c24xx_mci_pdata at2440evb_mci_pdata __initdata = { + .gpio_detect = S3C2410_GPG(10), +}; + +/* 7" LCD panel */ + +static struct s3c2410fb_display at2440evb_lcd_cfg __initdata = { + + .lcdcon5 = S3C2410_LCDCON5_FRM565 | + S3C2410_LCDCON5_INVVLINE | + S3C2410_LCDCON5_INVVFRAME | + S3C2410_LCDCON5_PWREN | + S3C2410_LCDCON5_HWSWP, + + .type = S3C2410_LCDCON1_TFT, + + .width = 800, + .height = 480, + + .pixclock = 33333, /* HCLK 60 MHz, divisor 2 */ + .xres = 800, + .yres = 480, + .bpp = 16, + .left_margin = 88, + .right_margin = 40, + .hsync_len = 128, + .upper_margin = 32, + .lower_margin = 11, + .vsync_len = 2, +}; + +static struct s3c2410fb_mach_info at2440evb_fb_info __initdata = { + .displays = &at2440evb_lcd_cfg, + .num_displays = 1, + .default_display = 0, +}; + +static struct platform_device *at2440evb_devices[] __initdata = { + &s3c_device_ohci, + &s3c_device_wdt, + &s3c_device_adc, + &s3c_device_i2c0, + &s3c_device_rtc, + &s3c_device_nand, + &s3c_device_sdi, + &s3c_device_lcd, + &at2440evb_device_eth, +}; + +static void __init at2440evb_map_io(void) +{ + s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc)); + s3c24xx_init_clocks(16934400); + s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs)); +} + +static void __init at2440evb_init(void) +{ + s3c24xx_fb_set_platdata(&at2440evb_fb_info); + s3c24xx_mci_set_platdata(&at2440evb_mci_pdata); + s3c_nand_set_platdata(&at2440evb_nand_info); + s3c_i2c0_set_platdata(NULL); + + platform_add_devices(at2440evb_devices, ARRAY_SIZE(at2440evb_devices)); +} + + +MACHINE_START(AT2440EVB, "AT2440EVB") + .atag_offset = 0x100, + .map_io = at2440evb_map_io, + .init_machine = at2440evb_init, + .init_irq = s3c24xx_init_irq, + .timer = &s3c24xx_timer, + .restart = s3c244x_restart, +MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c new file mode 100644 index 00000000..53219c02 --- /dev/null +++ b/arch/arm/mach-s3c24xx/mach-bast.c @@ -0,0 +1,644 @@ +/* linux/arch/arm/mach-s3c2410/mach-bast.c + * + * Copyright 2003-2008 Simtec Electronics + * Ben Dooks + * + * http://www.simtec.co.uk/products/EB2410ITX/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +//#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "simtec.h" +#include "common.h" + +#define COPYRIGHT ", Copyright 2004-2008 Simtec Electronics" + +/* macros for virtual address mods for the io space entries */ +#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5) +#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4) +#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3) +#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2) + +/* macros to modify the physical addresses for io space */ + +#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2)) +#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3)) +#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4)) +#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5)) + +static struct map_desc bast_iodesc[] __initdata = { + /* ISA IO areas */ + { + .virtual = (u32)S3C24XX_VA_ISA_BYTE, + .pfn = PA_CS2(BAST_PA_ISAIO), + .length = SZ_16M, + .type = MT_DEVICE, + }, { + .virtual = (u32)S3C24XX_VA_ISA_WORD, + .pfn = PA_CS3(BAST_PA_ISAIO), + .length = SZ_16M, + .type = MT_DEVICE, + }, + /* bast CPLD control registers, and external interrupt controls */ + { + .virtual = (u32)BAST_VA_CTRL1, + .pfn = __phys_to_pfn(BAST_PA_CTRL1), + .length = SZ_1M, + .type = MT_DEVICE, + }, { + .virtual = (u32)BAST_VA_CTRL2, + .pfn = __phys_to_pfn(BAST_PA_CTRL2), + .length = SZ_1M, + .type = MT_DEVICE, + }, { + .virtual = (u32)BAST_VA_CTRL3, + .pfn = __phys_to_pfn(BAST_PA_CTRL3), + .length = SZ_1M, + .type = MT_DEVICE, + }, { + .virtual = (u32)BAST_VA_CTRL4, + .pfn = __phys_to_pfn(BAST_PA_CTRL4), + .length = SZ_1M, + .type = MT_DEVICE, + }, + /* PC104 IRQ mux */ + { + .virtual = (u32)BAST_VA_PC104_IRQREQ, + .pfn = __phys_to_pfn(BAST_PA_PC104_IRQREQ), + .length = SZ_1M, + .type = MT_DEVICE, + }, { + .virtual = (u32)BAST_VA_PC104_IRQRAW, + .pfn = __phys_to_pfn(BAST_PA_PC104_IRQRAW), + .length = SZ_1M, + .type = MT_DEVICE, + }, { + .virtual = (u32)BAST_VA_PC104_IRQMASK, + .pfn = __phys_to_pfn(BAST_PA_PC104_IRQMASK), + .length = SZ_1M, + .type = MT_DEVICE, + }, + + /* peripheral space... one for each of fast/slow/byte/16bit */ + /* note, ide is only decoded in word space, even though some registers + * are only 8bit */ + + /* slow, byte */ + { VA_C2(BAST_VA_ISAIO), PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + { VA_C2(BAST_VA_ISAMEM), PA_CS2(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, + { VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, + + /* slow, word */ + { VA_C3(BAST_VA_ISAIO), PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + { VA_C3(BAST_VA_ISAMEM), PA_CS3(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, + { VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, + + /* fast, byte */ + { VA_C4(BAST_VA_ISAIO), PA_CS4(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + { VA_C4(BAST_VA_ISAMEM), PA_CS4(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, + { VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, + + /* fast, word */ + { VA_C5(BAST_VA_ISAIO), PA_CS5(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + { VA_C5(BAST_VA_ISAMEM), PA_CS5(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, + { VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, +}; + +#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE + +static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + /* port 2 is not actually used */ + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + } +}; + +/* NAND Flash on BAST board */ + +#ifdef CONFIG_PM +static int bast_pm_suspend(void) +{ + /* ensure that an nRESET is not generated on resume. */ + gpio_direction_output(S3C2410_GPA(21), 1); + return 0; +} + +static void bast_pm_resume(void) +{ + s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT); +} + +#else +#define bast_pm_suspend NULL +#define bast_pm_resume NULL +#endif + +static struct syscore_ops bast_pm_syscore_ops = { + .suspend = bast_pm_suspend, + .resume = bast_pm_resume, +}; + +static int smartmedia_map[] = { 0 }; +static int chip0_map[] = { 1 }; +static int chip1_map[] = { 2 }; +static int chip2_map[] = { 3 }; + +static struct mtd_partition __initdata bast_default_nand_part[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_16K, + .offset = 0, + }, + [1] = { + .name = "/boot", + .size = SZ_4M - SZ_16K, + .offset = SZ_16K, + }, + [2] = { + .name = "user", + .offset = SZ_4M, + .size = MTDPART_SIZ_FULL, + } +}; + +/* the bast has 4 selectable slots for nand-flash, the three + * on-board chip areas, as well as the external SmartMedia + * slot. + * + * Note, there is no current hot-plug support for the SmartMedia + * socket. +*/ + +static struct s3c2410_nand_set __initdata bast_nand_sets[] = { + [0] = { + .name = "SmartMedia", + .nr_chips = 1, + .nr_map = smartmedia_map, + .options = NAND_SCAN_SILENT_NODEV, + .nr_partitions = ARRAY_SIZE(bast_default_nand_part), + .partitions = bast_default_nand_part, + }, + [1] = { + .name = "chip0", + .nr_chips = 1, + .nr_map = chip0_map, + .nr_partitions = ARRAY_SIZE(bast_default_nand_part), + .partitions = bast_default_nand_part, + }, + [2] = { + .name = "chip1", + .nr_chips = 1, + .nr_map = chip1_map, + .options = NAND_SCAN_SILENT_NODEV, + .nr_partitions = ARRAY_SIZE(bast_default_nand_part), + .partitions = bast_default_nand_part, + }, + [3] = { + .name = "chip2", + .nr_chips = 1, + .nr_map = chip2_map, + .options = NAND_SCAN_SILENT_NODEV, + .nr_partitions = ARRAY_SIZE(bast_default_nand_part), + .partitions = bast_default_nand_part, + } +}; + +static void bast_nand_select(struct s3c2410_nand_set *set, int slot) +{ + unsigned int tmp; + + slot = set->nr_map[slot] & 3; + + pr_debug("bast_nand: selecting slot %d (set %p,%p)\n", + slot, set, set->nr_map); + + tmp = __raw_readb(BAST_VA_CTRL2); + tmp &= BAST_CPLD_CTLR2_IDERST; + tmp |= slot; + tmp |= BAST_CPLD_CTRL2_WNAND; + + pr_debug("bast_nand: ctrl2 now %02x\n", tmp); + + __raw_writeb(tmp, BAST_VA_CTRL2); +} + +static struct s3c2410_platform_nand __initdata bast_nand_info = { + .tacls = 30, + .twrph0 = 60, + .twrph1 = 60, + .nr_sets = ARRAY_SIZE(bast_nand_sets), + .sets = bast_nand_sets, + .select_chip = bast_nand_select, +}; + +/* DM9000 */ + +static struct resource bast_dm9k_resource[] = { + [0] = { + .start = S3C2410_CS5 + BAST_PA_DM9000, + .end = S3C2410_CS5 + BAST_PA_DM9000 + 3, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = S3C2410_CS5 + BAST_PA_DM9000 + 0x40, + .end = S3C2410_CS5 + BAST_PA_DM9000 + 0x40 + 0x3f, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_DM9000, + .end = IRQ_DM9000, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + } + +}; + +/* for the moment we limit ourselves to 16bit IO until some + * better IO routines can be written and tested +*/ + +static struct dm9000_plat_data bast_dm9k_platdata = { + .flags = DM9000_PLATF_16BITONLY, +}; + +static struct platform_device bast_device_dm9k = { + .name = "dm9000", + .id = 0, + .num_resources = ARRAY_SIZE(bast_dm9k_resource), + .resource = bast_dm9k_resource, + .dev = { + .platform_data = &bast_dm9k_platdata, + } +}; + +/* serial devices */ + +#define SERIAL_BASE (S3C2410_CS2 + BAST_PA_SUPERIO) +#define SERIAL_FLAGS (UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SHARE_IRQ) +#define SERIAL_CLK (1843200) + +static struct plat_serial8250_port bast_sio_data[] = { + [0] = { + .mapbase = SERIAL_BASE + 0x2f8, + .irq = IRQ_PCSERIAL1, + .flags = SERIAL_FLAGS, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = SERIAL_CLK, + }, + [1] = { + .mapbase = SERIAL_BASE + 0x3f8, + .irq = IRQ_PCSERIAL2, + .flags = SERIAL_FLAGS, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = SERIAL_CLK, + }, + { } +}; + +static struct platform_device bast_sio = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = &bast_sio_data, + }, +}; + +/* we have devices on the bus which cannot work much over the + * standard 100KHz i2c bus frequency +*/ + +static struct s3c2410_platform_i2c __initdata bast_i2c_info = { + .flags = 0, + .slave_addr = 0x10, + .frequency = 100*1000, +}; + +/* Asix AX88796 10/100 ethernet controller */ + +static struct ax_plat_data bast_asix_platdata = { + .flags = AXFLG_MAC_FROMDEV, + .wordlength = 2, + .dcr_val = 0x48, + .rcr_val = 0x40, +}; + +static struct resource bast_asix_resource[] = { + [0] = { + .start = S3C2410_CS5 + BAST_PA_ASIXNET, + .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20) - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20), + .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20), + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_ASIX, + .end = IRQ_ASIX, + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device bast_device_asix = { + .name = "ax88796", + .id = 0, + .num_resources = ARRAY_SIZE(bast_asix_resource), + .resource = bast_asix_resource, + .dev = { + .platform_data = &bast_asix_platdata + } +}; + +/* Asix AX88796 10/100 ethernet controller parallel port */ + +static struct resource bast_asixpp_resource[] = { + [0] = { + .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20), + .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1b * 0x20) - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device bast_device_axpp = { + .name = "ax88796-pp", + .id = 0, + .num_resources = ARRAY_SIZE(bast_asixpp_resource), + .resource = bast_asixpp_resource, +}; + +/* LCD/VGA controller */ + +static struct s3c2410fb_display __initdata bast_lcd_info[] = { + { + .type = S3C2410_LCDCON1_TFT, + .width = 640, + .height = 480, + + .pixclock = 33333, + .xres = 640, + .yres = 480, + .bpp = 4, + .left_margin = 40, + .right_margin = 20, + .hsync_len = 88, + .upper_margin = 30, + .lower_margin = 32, + .vsync_len = 3, + + .lcdcon5 = 0x00014b02, + }, + { + .type = S3C2410_LCDCON1_TFT, + .width = 640, + .height = 480, + + .pixclock = 33333, + .xres = 640, + .yres = 480, + .bpp = 8, + .left_margin = 40, + .right_margin = 20, + .hsync_len = 88, + .upper_margin = 30, + .lower_margin = 32, + .vsync_len = 3, + + .lcdcon5 = 0x00014b02, + }, + { + .type = S3C2410_LCDCON1_TFT, + .width = 640, + .height = 480, + + .pixclock = 33333, + .xres = 640, + .yres = 480, + .bpp = 16, + .left_margin = 40, + .right_margin = 20, + .hsync_len = 88, + .upper_margin = 30, + .lower_margin = 32, + .vsync_len = 3, + + .lcdcon5 = 0x00014b02, + }, +}; + +/* LCD/VGA controller */ + +static struct s3c2410fb_mach_info __initdata bast_fb_info = { + + .displays = bast_lcd_info, + .num_displays = ARRAY_SIZE(bast_lcd_info), + .default_display = 1, +}; + +/* I2C devices fitted. */ + +static struct i2c_board_info bast_i2c_devs[] __initdata = { + { + I2C_BOARD_INFO("tlv320aic23", 0x1a), + }, { + I2C_BOARD_INFO("simtec-pmu", 0x6b), + }, { + I2C_BOARD_INFO("ch7013", 0x75), + }, +}; + +static struct s3c_hwmon_pdata bast_hwmon_info = { + /* LCD contrast (0-6.6V) */ + .in[0] = &(struct s3c_hwmon_chcfg) { + .name = "lcd-contrast", + .mult = 3300, + .div = 512, + }, + /* LED current feedback */ + .in[1] = &(struct s3c_hwmon_chcfg) { + .name = "led-feedback", + .mult = 3300, + .div = 1024, + }, + /* LCD feedback (0-6.6V) */ + .in[2] = &(struct s3c_hwmon_chcfg) { + .name = "lcd-feedback", + .mult = 3300, + .div = 512, + }, + /* Vcore (1.8-2.0V), Vref 3.3V */ + .in[3] = &(struct s3c_hwmon_chcfg) { + .name = "vcore", + .mult = 3300, + .div = 1024, + }, +}; + +/* Standard BAST devices */ +// cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0 + +static struct platform_device *bast_devices[] __initdata = { + &s3c_device_ohci, + &s3c_device_lcd, + &s3c_device_wdt, + &s3c_device_i2c0, + &s3c_device_rtc, + &s3c_device_nand, + &s3c_device_adc, + &s3c_device_hwmon, + &bast_device_dm9k, + &bast_device_asix, + &bast_device_axpp, + &bast_sio, +}; + +static struct clk *bast_clocks[] __initdata = { + &s3c24xx_dclk0, + &s3c24xx_dclk1, + &s3c24xx_clkout0, + &s3c24xx_clkout1, + &s3c24xx_uclk, +}; + +static struct s3c_cpufreq_board __initdata bast_cpufreq = { + .refresh = 7800, /* 7.8usec */ + .auto_io = 1, + .need_io = 1, +}; + +static struct s3c24xx_audio_simtec_pdata __initdata bast_audio = { + .have_mic = 1, + .have_lout = 1, +}; + +static void __init bast_map_io(void) +{ + /* initialise the clocks */ + + s3c24xx_dclk0.parent = &clk_upll; + s3c24xx_dclk0.rate = 12*1000*1000; + + s3c24xx_dclk1.parent = &clk_upll; + s3c24xx_dclk1.rate = 24*1000*1000; + + s3c24xx_clkout0.parent = &s3c24xx_dclk0; + s3c24xx_clkout1.parent = &s3c24xx_dclk1; + + s3c24xx_uclk.parent = &s3c24xx_clkout1; + + s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); + + s3c_hwmon_set_platdata(&bast_hwmon_info); + + s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); + s3c24xx_init_clocks(0); + s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs)); +} + +static void __init bast_init(void) +{ + register_syscore_ops(&bast_pm_syscore_ops); + + s3c_i2c0_set_platdata(&bast_i2c_info); + s3c_nand_set_platdata(&bast_nand_info); + s3c24xx_fb_set_platdata(&bast_fb_info); + platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices)); + + i2c_register_board_info(0, bast_i2c_devs, + ARRAY_SIZE(bast_i2c_devs)); + + usb_simtec_init(); + nor_simtec_init(); + simtec_audio_add(NULL, true, &bast_audio); + + WARN_ON(gpio_request(S3C2410_GPA(21), "bast nreset")); + + s3c_cpufreq_setboard(&bast_cpufreq); +} + +MACHINE_START(BAST, "Simtec-BAST") + /* Maintainer: Ben Dooks */ + .atag_offset = 0x100, + .map_io = bast_map_io, + .init_irq = s3c24xx_init_irq, + .init_machine = bast_init, + .timer = &s3c24xx_timer, + .restart = s3c2410_restart, +MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c new file mode 100644 index 00000000..ba5d8539 --- /dev/null +++ b/arch/arm/mach-s3c24xx/mach-gta02.c @@ -0,0 +1,605 @@ +/* + * linux/arch/arm/mach-s3c2442/mach-gta02.c + * + * S3C2442 Machine Support for Openmoko GTA02 / FreeRunner. + * + * Copyright (C) 2006-2009 by Openmoko, Inc. + * Authors: Harald Welte + * Andy Green + * Werner Almesberger + * All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +static struct pcf50633 *gta02_pcf; + +/* + * This gets called frequently when we paniced. + */ + +static long gta02_panic_blink(int state) +{ + long delay = 0; + char led; + + led = (state) ? 1 : 0; + gpio_direction_output(GTA02_GPIO_AUX_LED, led); + + return delay; +} + + +static struct map_desc gta02_iodesc[] __initdata = { + { + .virtual = 0xe0000000, + .pfn = __phys_to_pfn(S3C2410_CS3 + 0x01000000), + .length = SZ_1M, + .type = MT_DEVICE + }, +}; + +#define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN) +#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) +#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) + +static struct s3c2410_uartcfg gta02_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, +}; + +#ifdef CONFIG_CHARGER_PCF50633 +/* + * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin. + * We use this to recognize that we can pull 1A from the USB socket. + * + * These constants are the measured pcf50633 ADC levels with the 1A + * charger / 48K resistor, and with no pulldown resistor. + */ + +#define ADC_NOM_CHG_DETECT_1A 6 +#define ADC_NOM_CHG_DETECT_USB 43 + +static void +gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res) +{ + int ma; + + /* Interpret charger type */ + if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) { + + /* + * Sanity - stop GPO driving out now that we have a 1A charger + * GPO controls USB Host power generation on GTA02 + */ + pcf50633_gpio_set(pcf, PCF50633_GPO, 0); + + ma = 1000; + } else + ma = 100; + + pcf50633_mbc_usb_curlim_set(pcf, ma); +} + +static struct delayed_work gta02_charger_work; +static int gta02_usb_vbus_draw; + +static void gta02_charger_worker(struct work_struct *work) +{ + if (gta02_usb_vbus_draw) { + pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw); + return; + } + +#ifdef CONFIG_PCF50633_ADC + pcf50633_adc_async_read(gta02_pcf, + PCF50633_ADCC1_MUX_ADCIN1, + PCF50633_ADCC1_AVERAGE_16, + gta02_configure_pmu_for_charger, + NULL); +#else + /* + * If the PCF50633 ADC is disabled we fallback to a + * 100mA limit for safety. + */ + pcf50633_mbc_usb_curlim_set(pcf, 100); +#endif +} + +#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000) + +static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq) +{ + if (irq == PCF50633_IRQ_USBINS) { + schedule_delayed_work(>a02_charger_work, + GTA02_CHARGER_CONFIGURE_TIMEOUT); + + return; + } + + if (irq == PCF50633_IRQ_USBREM) { + cancel_delayed_work_sync(>a02_charger_work); + gta02_usb_vbus_draw = 0; + } +} + +static void gta02_udc_vbus_draw(unsigned int ma) +{ + if (!gta02_pcf) + return; + + gta02_usb_vbus_draw = ma; + + schedule_delayed_work(>a02_charger_work, + GTA02_CHARGER_CONFIGURE_TIMEOUT); +} +#else /* !CONFIG_CHARGER_PCF50633 */ +#define gta02_pmu_event_callback NULL +#define gta02_udc_vbus_draw NULL +#endif + +/* + * This is called when pc50633 is probed, unfortunately quite late in the + * day since it is an I2C bus device. Here we can belatedly define some + * platform devices with the advantage that we can mark the pcf50633 as the + * parent. This makes them get suspended and resumed with their parent + * the pcf50633 still around. + */ + +static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf); + + +static char *gta02_batteries[] = { + "battery", +}; + +static struct pcf50633_bl_platform_data gta02_backlight_data = { + .default_brightness = 0x3f, + .default_brightness_limit = 0, + .ramp_time = 5, +}; + +static struct pcf50633_platform_data gta02_pcf_pdata = { + .resumers = { + [0] = PCF50633_INT1_USBINS | + PCF50633_INT1_USBREM | + PCF50633_INT1_ALARM, + [1] = PCF50633_INT2_ONKEYF, + [2] = PCF50633_INT3_ONKEY1S, + [3] = PCF50633_INT4_LOWSYS | + PCF50633_INT4_LOWBAT | + PCF50633_INT4_HIGHTMP, + }, + + .batteries = gta02_batteries, + .num_batteries = ARRAY_SIZE(gta02_batteries), + + .charger_reference_current_ma = 1000, + + .backlight_data = >a02_backlight_data, + + .reg_init_data = { + [PCF50633_REGULATOR_AUTO] = { + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .always_on = 1, + .apply_uV = 1, + }, + }, + [PCF50633_REGULATOR_DOWN1] = { + .constraints = { + .min_uV = 1300000, + .max_uV = 1600000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .always_on = 1, + .apply_uV = 1, + }, + }, + [PCF50633_REGULATOR_DOWN2] = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .apply_uV = 1, + .always_on = 1, + }, + }, + [PCF50633_REGULATOR_HCLDO] = { + .constraints = { + .min_uV = 2000000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + }, + }, + [PCF50633_REGULATOR_LDO1] = { + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + }, + }, + [PCF50633_REGULATOR_LDO2] = { + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .apply_uV = 1, + }, + }, + [PCF50633_REGULATOR_LDO3] = { + .constraints = { + .min_uV = 3000000, + .max_uV = 3000000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .apply_uV = 1, + }, + }, + [PCF50633_REGULATOR_LDO4] = { + .constraints = { + .min_uV = 3200000, + .max_uV = 3200000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + }, + }, + [PCF50633_REGULATOR_LDO5] = { + .constraints = { + .min_uV = 3000000, + .max_uV = 3000000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .apply_uV = 1, + }, + }, + [PCF50633_REGULATOR_LDO6] = { + .constraints = { + .min_uV = 3000000, + .max_uV = 3000000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + }, + }, + [PCF50633_REGULATOR_MEMLDO] = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + }, + }, + + }, + .probe_done = gta02_pmu_attach_child_devices, + .mbc_event_callback = gta02_pmu_event_callback, +}; + + +/* NOR Flash. */ + +#define GTA02_FLASH_BASE 0x18000000 /* GCS3 */ +#define GTA02_FLASH_SIZE 0x200000 /* 2MBytes */ + +static struct physmap_flash_data gta02_nor_flash_data = { + .width = 2, +}; + +static struct resource gta02_nor_flash_resource = { + .start = GTA02_FLASH_BASE, + .end = GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device gta02_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = >a02_nor_flash_data, + }, + .resource = >a02_nor_flash_resource, + .num_resources = 1, +}; + + +static struct platform_device s3c24xx_pwm_device = { + .name = "s3c24xx_pwm", + .num_resources = 0, +}; + +static struct platform_device gta02_dfbmcs320_device = { + .name = "dfbmcs320", +}; + +static struct i2c_board_info gta02_i2c_devs[] __initdata = { + { + I2C_BOARD_INFO("pcf50633", 0x73), + .irq = GTA02_IRQ_PCF50633, + .platform_data = >a02_pcf_pdata, + }, + { + I2C_BOARD_INFO("wm8753", 0x1a), + }, +}; + +static struct s3c2410_nand_set __initdata gta02_nand_sets[] = { + [0] = { + /* + * This name is also hard-coded in the boot loaders, so + * changing it would would require all users to upgrade + * their boot loaders, some of which are stored in a NOR + * that is considered to be immutable. + */ + .name = "neo1973-nand", + .nr_chips = 1, + .flash_bbt = 1, + }, +}; + +/* + * Choose a set of timings derived from S3C@2442B MCP54 + * data sheet (K5D2G13ACM-D075 MCP Memory). + */ + +static struct s3c2410_platform_nand __initdata gta02_nand_info = { + .tacls = 0, + .twrph0 = 25, + .twrph1 = 15, + .nr_sets = ARRAY_SIZE(gta02_nand_sets), + .sets = gta02_nand_sets, +}; + + +/* Get PMU to set USB current limit accordingly. */ +static struct s3c2410_udc_mach_info gta02_udc_cfg __initdata = { + .vbus_draw = gta02_udc_vbus_draw, + .pullup_pin = GTA02_GPIO_USB_PULLUP, +}; + +/* USB */ +static struct s3c2410_hcd_info gta02_usb_info __initdata = { + .port[0] = { + .flags = S3C_HCDFLG_USED, + }, + .port[1] = { + .flags = 0, + }, +}; + +/* Touchscreen */ +static struct s3c2410_ts_mach_info gta02_ts_info = { + .delay = 10000, + .presc = 0xff, /* slow as we can go */ + .oversampling_shift = 2, +}; + +/* Buttons */ +static struct gpio_keys_button gta02_buttons[] = { + { + .gpio = GTA02_GPIO_AUX_KEY, + .code = KEY_PHONE, + .desc = "Aux", + .type = EV_KEY, + .debounce_interval = 100, + }, + { + .gpio = GTA02_GPIO_HOLD_KEY, + .code = KEY_PAUSE, + .desc = "Hold", + .type = EV_KEY, + .debounce_interval = 100, + }, +}; + +static struct gpio_keys_platform_data gta02_buttons_pdata = { + .buttons = gta02_buttons, + .nbuttons = ARRAY_SIZE(gta02_buttons), +}; + +static struct platform_device gta02_buttons_device = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = >a02_buttons_pdata, + }, +}; + +static void __init gta02_map_io(void) +{ + s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc)); + s3c24xx_init_clocks(12000000); + s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs)); +} + + +/* These are the guys that don't need to be children of PMU. */ + +static struct platform_device *gta02_devices[] __initdata = { + &s3c_device_ohci, + &s3c_device_wdt, + &s3c_device_sdi, + &s3c_device_usbgadget, + &s3c_device_nand, + >a02_nor_flash, + &s3c24xx_pwm_device, + &s3c_device_iis, + &samsung_asoc_dma, + &s3c_device_i2c0, + >a02_dfbmcs320_device, + >a02_buttons_device, + &s3c_device_adc, + &s3c_device_ts, +}; + +/* These guys DO need to be children of PMU. */ + +static struct platform_device *gta02_devices_pmu_children[] = { +}; + + +/* + * This is called when pc50633 is probed, quite late in the day since it is an + * I2C bus device. Here we can define platform devices with the advantage that + * we can mark the pcf50633 as the parent. This makes them get suspended and + * resumed with their parent the pcf50633 still around. All devices whose + * operation depends on something from pcf50633 must have this relationship + * made explicit like this, or suspend and resume will become an unreliable + * hellworld. + */ + +static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf) +{ + int n; + + /* Grab a copy of the now probed PMU pointer. */ + gta02_pcf = pcf; + + for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++) + gta02_devices_pmu_children[n]->dev.parent = pcf->dev; + + platform_add_devices(gta02_devices_pmu_children, + ARRAY_SIZE(gta02_devices_pmu_children)); +} + +static void gta02_poweroff(void) +{ + pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1); +} + +static void __init gta02_machine_init(void) +{ + /* Set the panic callback to turn AUX LED on or off. */ + panic_blink = gta02_panic_blink; + + s3c_pm_init(); + +#ifdef CONFIG_CHARGER_PCF50633 + INIT_DELAYED_WORK(>a02_charger_work, gta02_charger_worker); +#endif + + s3c24xx_udc_set_platdata(>a02_udc_cfg); + s3c24xx_ts_set_platdata(>a02_ts_info); + s3c_ohci_set_platdata(>a02_usb_info); + s3c_nand_set_platdata(>a02_nand_info); + s3c_i2c0_set_platdata(NULL); + + i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs)); + + platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices)); + pm_power_off = gta02_poweroff; + + regulator_has_full_constraints(); +} + + +MACHINE_START(NEO1973_GTA02, "GTA02") + /* Maintainer: Nelson Castillo */ + .atag_offset = 0x100, + .map_io = gta02_map_io, + .init_irq = s3c24xx_init_irq, + .init_machine = gta02_machine_init, + .timer = &s3c24xx_timer, + .restart = s3c244x_restart, +MACHINE_END diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c new file mode 100644 index 00000000..6b21ba10 --- /dev/null +++ b/arch/arm/mach-s3c24xx/mach-h1940.c @@ -0,0 +1,757 @@ +/* linux/arch/arm/mach-s3c2410/mach-h1940.c + * + * Copyright (c) 2003-2005 Simtec Electronics + * Ben Dooks + * + * http://www.handhelds.org/projects/h1940.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include