aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig12
-rw-r--r--arch/arm/configs/mx51_defconfig1
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h13
-rw-r--r--arch/arm/include/asm/memblock.h7
-rw-r--r--arch/arm/include/asm/outercache.h24
-rw-r--r--arch/arm/kernel/machine_kexec.c3
-rw-r--r--arch/arm/kernel/vmlinux.lds.S1
-rw-r--r--arch/arm/mach-imx/mach-mx27_3ds.c38
-rw-r--r--arch/arm/mach-ixp2000/core.c2
-rw-r--r--arch/arm/mach-mx25/Kconfig1
-rw-r--r--arch/arm/mach-mx25/mach-mx25_3ds.c10
-rw-r--r--arch/arm/mach-mx3/Kconfig2
-rw-r--r--arch/arm/mach-mx3/devices.c16
-rw-r--r--arch/arm/mach-mx3/mach-mx31_3ds.c38
-rw-r--r--arch/arm/mach-mx3/mach-mx35_3ds.c16
-rw-r--r--arch/arm/mach-mx5/Kconfig2
-rw-r--r--arch/arm/mach-mx5/Makefile1
-rw-r--r--arch/arm/mach-mx5/board-mx51_babbage.c49
-rw-r--r--arch/arm/mach-mx5/clock-mx51.c22
-rw-r--r--arch/arm/mach-mx5/cpu_op-mx51.c29
-rw-r--r--arch/arm/mach-mx5/cpu_op-mx51.h14
-rw-r--r--arch/arm/mach-mx5/devices-imx51.h2
-rw-r--r--arch/arm/mach-omap2/omap4-common.c13
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio.h10
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s3c2412/s3c2412.c3
-rw-r--r--arch/arm/mach-s3c2416/Kconfig6
-rw-r--r--arch/arm/mach-s3c2416/Makefile2
-rw-r--r--arch/arm/mach-s3c2416/irq.c2
-rw-r--r--arch/arm/mach-s3c2416/pm.c84
-rw-r--r--arch/arm/mach-s3c2416/s3c2416.c3
-rw-r--r--arch/arm/mach-s3c2440/s3c244x.c3
-rw-r--r--arch/arm/mach-s3c2443/s3c2443.c3
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig21
-rw-r--r--arch/arm/mach-s3c64xx/Makefile1
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c63
-rw-r--r--arch/arm/mach-s3c64xx/gpiolib.c8
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s3c64xx/mach-mini6410.c357
-rw-r--r--arch/arm/mach-s3c64xx/mach-real6410.c198
-rw-r--r--arch/arm/mach-s3c64xx/setup-fb-24bpp.c13
-rw-r--r--arch/arm/mach-s3c64xx/setup-ide.c11
-rw-r--r--arch/arm/mach-s3c64xx/setup-keypad.c16
-rw-r--r--arch/arm/mach-s3c64xx/setup-sdhci-gpio.c41
-rw-r--r--arch/arm/mach-s5p6442/Kconfig1
-rw-r--r--arch/arm/mach-s5p6442/clock.c28
-rw-r--r--arch/arm/mach-s5p6442/dev-audio.c30
-rw-r--r--arch/arm/mach-s5p6442/dev-spi.c6
-rw-r--r--arch/arm/mach-s5p6442/dma.c2
-rw-r--r--arch/arm/mach-s5p6442/include/mach/regs-clock.h1
-rw-r--r--arch/arm/mach-s5p6442/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s5p64x0/Kconfig2
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6440.c19
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c19
-rw-r--r--arch/arm/mach-s5p64x0/clock.c18
-rw-r--r--arch/arm/mach-s5p64x0/dev-audio.c26
-rw-r--r--arch/arm/mach-s5p64x0/dev-spi.c38
-rw-r--r--arch/arm/mach-s5p64x0/dma.c2
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/regs-clock.h2
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s5p64x0/setup-i2c0.c12
-rw-r--r--arch/arm/mach-s5p64x0/setup-i2c1.c12
-rw-r--r--arch/arm/mach-s5pc100/Kconfig1
-rw-r--r--arch/arm/mach-s5pc100/Makefile2
-rw-r--r--arch/arm/mach-s5pc100/clock.c174
-rw-r--r--arch/arm/mach-s5pc100/dev-audio.c86
-rw-r--r--arch/arm/mach-s5pc100/dev-spi.c22
-rw-r--r--arch/arm/mach-s5pc100/dma.c4
-rw-r--r--arch/arm/mach-s5pc100/gpiolib.c216
-rw-r--r--arch/arm/mach-s5pc100/include/mach/gpio.h7
-rw-r--r--arch/arm/mach-s5pc100/include/mach/irqs.h13
-rw-r--r--arch/arm/mach-s5pc100/include/mach/map.h2
-rw-r--r--arch/arm/mach-s5pc100/include/mach/regs-gpio.h49
-rw-r--r--arch/arm/mach-s5pc100/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s5pc100/irq-gpio.c266
-rw-r--r--arch/arm/mach-s5pc100/mach-smdkc100.c4
-rw-r--r--arch/arm/mach-s5pc100/setup-fb-24bpp.c30
-rw-r--r--arch/arm/mach-s5pc100/setup-i2c0.c6
-rw-r--r--arch/arm/mach-s5pc100/setup-i2c1.c6
-rw-r--r--arch/arm/mach-s5pc100/setup-ide.c41
-rw-r--r--arch/arm/mach-s5pc100/setup-keypad.c15
-rw-r--r--arch/arm/mach-s5pc100/setup-sdhci-gpio.c35
-rw-r--r--arch/arm/mach-s5pv210/Kconfig37
-rw-r--r--arch/arm/mach-s5pv210/Makefile3
-rw-r--r--arch/arm/mach-s5pv210/clock.c207
-rw-r--r--arch/arm/mach-s5pv210/cpu.c15
-rw-r--r--arch/arm/mach-s5pv210/cpufreq.c484
-rw-r--r--arch/arm/mach-s5pv210/dev-audio.c86
-rw-r--r--arch/arm/mach-s5pv210/dev-spi.c19
-rw-r--r--arch/arm/mach-s5pv210/dma.c4
-rw-r--r--arch/arm/mach-s5pv210/gpiolib.c14
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h12
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h12
-rw-r--r--arch/arm/mach-s5pv210/include/mach/pm-core.h43
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-clock.h39
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-gpio.h7
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-sys.h19
-rw-r--r--arch/arm/mach-s5pv210/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s5pv210/mach-aquila.c169
-rw-r--r--arch/arm/mach-s5pv210/mach-goni.c381
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkc110.c4
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c4
-rw-r--r--arch/arm/mach-s5pv210/mach-torbreck.c131
-rw-r--r--arch/arm/mach-s5pv210/pm.c166
-rw-r--r--arch/arm/mach-s5pv210/setup-fb-24bpp.c34
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c0.c6
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c1.c6
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c2.c6
-rw-r--r--arch/arm/mach-s5pv210/setup-ide.c49
-rw-r--r--arch/arm/mach-s5pv210/setup-keypad.c14
-rw-r--r--arch/arm/mach-s5pv210/setup-sdhci-gpio.c57
-rw-r--r--arch/arm/mach-s5pv210/sleep.S170
-rw-r--r--arch/arm/mach-s5pv310/Kconfig95
-rw-r--r--arch/arm/mach-s5pv310/Makefile10
-rw-r--r--arch/arm/mach-s5pv310/clock.c635
-rw-r--r--arch/arm/mach-s5pv310/cpu.c47
-rw-r--r--arch/arm/mach-s5pv310/gpiolib.c304
-rw-r--r--arch/arm/mach-s5pv310/hotplug.c144
-rw-r--r--arch/arm/mach-s5pv310/include/mach/irqs.h44
-rw-r--r--arch/arm/mach-s5pv310/include/mach/map.h19
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-clock.h32
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-gpio.h42
-rw-r--r--arch/arm/mach-s5pv310/include/mach/regs-srom.h50
-rw-r--r--arch/arm/mach-s5pv310/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-s5pv310/irq-combiner.c6
-rw-r--r--arch/arm/mach-s5pv310/irq-eint.c228
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkc210.c202
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkv310.c121
-rw-r--r--arch/arm/mach-s5pv310/mach-universal_c210.c81
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c0.c6
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c1.c6
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c2.c6
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c3.c23
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c4.c23
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c5.c23
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c6.c23
-rw-r--r--arch/arm/mach-s5pv310/setup-i2c7.c23
-rw-r--r--arch/arm/mach-s5pv310/setup-sdhci-gpio.c152
-rw-r--r--arch/arm/mach-s5pv310/setup-sdhci.c69
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1100.c5
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c326
-rw-r--r--arch/arm/mach-shmobile/clock-sh7367.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c78
-rw-r--r--arch/arm/mach-shmobile/clock-sh7377.c2
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h10
-rw-r--r--arch/arm/mach-shmobile/intc-sh7372.c28
-rw-r--r--arch/arm/mach-shmobile/pfc-sh7372.c8
-rw-r--r--arch/arm/mach-shmobile/setup-sh7367.c1
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c94
-rw-r--r--arch/arm/mach-shmobile/setup-sh7377.c1
-rw-r--r--arch/arm/mach-ux500/cpu.c45
-rw-r--r--arch/arm/mm/Kconfig8
-rw-r--r--arch/arm/mm/cache-fa.S12
-rw-r--r--arch/arm/mm/cache-l2x0.c78
-rw-r--r--arch/arm/mm/cache-v3.S10
-rw-r--r--arch/arm/mm/cache-v4.S10
-rw-r--r--arch/arm/mm/cache-v4wb.S12
-rw-r--r--arch/arm/mm/cache-v4wt.S12
-rw-r--r--arch/arm/mm/fault-armv.c28
-rw-r--r--arch/arm/mm/init.c155
-rw-r--r--arch/arm/mm/mmu.c73
-rw-r--r--arch/arm/mm/proc-arm1020.S15
-rw-r--r--arch/arm/mm/proc-arm1020e.S15
-rw-r--r--arch/arm/mm/proc-arm1022.S15
-rw-r--r--arch/arm/mm/proc-arm1026.S15
-rw-r--r--arch/arm/mm/proc-arm920.S12
-rw-r--r--arch/arm/mm/proc-arm922.S12
-rw-r--r--arch/arm/mm/proc-arm925.S12
-rw-r--r--arch/arm/mm/proc-arm926.S12
-rw-r--r--arch/arm/mm/proc-arm940.S12
-rw-r--r--arch/arm/mm/proc-arm946.S12
-rw-r--r--arch/arm/mm/proc-feroceon.S13
-rw-r--r--arch/arm/mm/proc-xsc3.S12
-rw-r--r--arch/arm/mm/proc-xscale.S12
-rw-r--r--arch/arm/plat-mxc/Makefile1
-rw-r--r--arch/arm/plat-mxc/cpufreq.c206
-rw-r--r--arch/arm/plat-mxc/devices/Kconfig6
-rw-r--r--arch/arm/plat-mxc/devices/Makefile1
-rw-r--r--arch/arm/plat-mxc/devices/platform-gpio_keys.c27
-rw-r--r--arch/arm/plat-mxc/gpio.c32
-rw-r--r--arch/arm/plat-mxc/include/mach/devices-common.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx51.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/mx31.h1
-rw-r--r--arch/arm/plat-mxc/include/mach/mx35.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc.h13
-rw-r--r--arch/arm/plat-s3c24xx/common-smdk.c2
-rw-r--r--arch/arm/plat-s3c24xx/gpiolib.c8
-rw-r--r--arch/arm/plat-s5p/Kconfig5
-rw-r--r--arch/arm/plat-s5p/Makefile3
-rw-r--r--arch/arm/plat-s5p/clock.c29
-rw-r--r--arch/arm/plat-s5p/include/plat/irqs.h18
-rw-r--r--arch/arm/plat-s5p/include/plat/map-s5p.h40
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-clock.h4
-rw-r--r--arch/arm/plat-s5p/irq-eint.c10
-rw-r--r--arch/arm/plat-s5p/irq-gpioint.c237
-rw-r--r--arch/arm/plat-s5p/irq-pm.c93
-rw-r--r--arch/arm/plat-s5p/pm.c52
-rw-r--r--arch/arm/plat-samsung/Kconfig25
-rw-r--r--arch/arm/plat-samsung/Makefile5
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc.c8
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc1.c8
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc2.c8
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc3.c12
-rw-r--r--arch/arm/plat-samsung/dev-i2c2.c4
-rw-r--r--arch/arm/plat-samsung/dev-i2c3.c68
-rw-r--r--arch/arm/plat-samsung/dev-i2c4.c68
-rw-r--r--arch/arm/plat-samsung/dev-i2c5.c68
-rw-r--r--arch/arm/plat-samsung/dev-i2c6.c68
-rw-r--r--arch/arm/plat-samsung/dev-i2c7.c68
-rw-r--r--arch/arm/plat-samsung/gpio-config.c50
-rw-r--r--arch/arm/plat-samsung/gpio.c8
-rw-r--r--arch/arm/plat-samsung/include/plat/audio.h9
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h7
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg.h56
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h15
-rw-r--r--arch/arm/plat-samsung/include/plat/iic.h10
-rw-r--r--arch/arm/plat-samsung/include/plat/map-base.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/nand-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h64
-rw-r--r--arch/arm/plat-samsung/pm-gpio.c4
-rw-r--r--arch/arm/plat-samsung/s3c-pl330.c34
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c29
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c60
-rw-r--r--arch/sh/boards/mach-kfr2r09/setup.c29
-rw-r--r--arch/sh/boards/mach-migor/setup.c58
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c54
-rw-r--r--drivers/video/sh_mipi_dsi.c32
-rw-r--r--drivers/video/sh_mobile_hdmi.c629
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c348
-rw-r--r--drivers/video/sh_mobile_lcdcfb.h41
-rw-r--r--include/video/sh_mobile_lcdc.h5
234 files changed, 8861 insertions, 2080 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b527bf5701c9..a19a5266d5fc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -720,9 +720,11 @@ config ARCH_S5PC100
720config ARCH_S5PV210 720config ARCH_S5PV210
721 bool "Samsung S5PV210/S5PC110" 721 bool "Samsung S5PV210/S5PC110"
722 select CPU_V7 722 select CPU_V7
723 select ARCH_SPARSEMEM_ENABLE
723 select GENERIC_GPIO 724 select GENERIC_GPIO
724 select HAVE_CLK 725 select HAVE_CLK
725 select ARM_L1_CACHE_SHIFT_6 726 select ARM_L1_CACHE_SHIFT_6
727 select ARCH_HAS_CPUFREQ
726 select ARCH_USES_GETTIMEOFFSET 728 select ARCH_USES_GETTIMEOFFSET
727 select HAVE_S3C2410_I2C 729 select HAVE_S3C2410_I2C
728 select HAVE_S3C_RTC 730 select HAVE_S3C_RTC
@@ -733,9 +735,13 @@ config ARCH_S5PV210
733config ARCH_S5PV310 735config ARCH_S5PV310
734 bool "Samsung S5PV310/S5PC210" 736 bool "Samsung S5PV310/S5PC210"
735 select CPU_V7 737 select CPU_V7
738 select ARCH_SPARSEMEM_ENABLE
736 select GENERIC_GPIO 739 select GENERIC_GPIO
737 select HAVE_CLK 740 select HAVE_CLK
738 select GENERIC_CLOCKEVENTS 741 select GENERIC_CLOCKEVENTS
742 select HAVE_S3C_RTC
743 select HAVE_S3C2410_I2C
744 select HAVE_S3C2410_WATCHDOG
739 help 745 help
740 Samsung S5PV310 series based systems 746 Samsung S5PV310 series based systems
741 747
@@ -1662,6 +1668,12 @@ if ARCH_HAS_CPUFREQ
1662 1668
1663source "drivers/cpufreq/Kconfig" 1669source "drivers/cpufreq/Kconfig"
1664 1670
1671config CPU_FREQ_IMX
1672 tristate "CPUfreq driver for i.MX CPUs"
1673 depends on ARCH_MXC && CPU_FREQ
1674 help
1675 This enables the CPUfreq driver for i.MX CPUs.
1676
1665config CPU_FREQ_SA1100 1677config CPU_FREQ_SA1100
1666 bool 1678 bool
1667 1679
diff --git a/arch/arm/configs/mx51_defconfig b/arch/arm/configs/mx51_defconfig
index 163cfee7644c..5c7a87260fab 100644
--- a/arch/arm/configs/mx51_defconfig
+++ b/arch/arm/configs/mx51_defconfig
@@ -82,6 +82,7 @@ CONFIG_FEC=y
82CONFIG_INPUT_FF_MEMLESS=m 82CONFIG_INPUT_FF_MEMLESS=m
83# CONFIG_INPUT_MOUSEDEV_PSAUX is not set 83# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
84CONFIG_INPUT_EVDEV=y 84CONFIG_INPUT_EVDEV=y
85CONFIG_KEYBOARD_GPIO=y
85CONFIG_INPUT_EVBUG=m 86CONFIG_INPUT_EVBUG=m
86CONFIG_MOUSE_PS2=m 87CONFIG_MOUSE_PS2=m
87CONFIG_MOUSE_PS2_ELANTECH=y 88CONFIG_MOUSE_PS2_ELANTECH=y
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 6bcba48800fe..cc42d5fdee17 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -21,9 +21,6 @@
21#define __ASM_ARM_HARDWARE_L2X0_H 21#define __ASM_ARM_HARDWARE_L2X0_H
22 22
23#define L2X0_CACHE_ID 0x000 23#define L2X0_CACHE_ID 0x000
24#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
25#define L2X0_CACHE_ID_PART_L210 (1 << 6)
26#define L2X0_CACHE_ID_PART_L310 (3 << 6)
27#define L2X0_CACHE_TYPE 0x004 24#define L2X0_CACHE_TYPE 0x004
28#define L2X0_CTRL 0x100 25#define L2X0_CTRL 0x100
29#define L2X0_AUX_CTRL 0x104 26#define L2X0_AUX_CTRL 0x104
@@ -53,6 +50,16 @@
53#define L2X0_LINE_DATA 0xF10 50#define L2X0_LINE_DATA 0xF10
54#define L2X0_LINE_TAG 0xF30 51#define L2X0_LINE_TAG 0xF30
55#define L2X0_DEBUG_CTRL 0xF40 52#define L2X0_DEBUG_CTRL 0xF40
53#define L2X0_PREFETCH_CTRL 0xF60
54#define L2X0_POWER_CTRL 0xF80
55#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1)
56#define L2X0_STNDBY_MODE_EN (1 << 0)
57
58/* Registers shifts and masks */
59#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
60#define L2X0_CACHE_ID_PART_L210 (1 << 6)
61#define L2X0_CACHE_ID_PART_L310 (3 << 6)
62#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17)
56 63
57#ifndef __ASSEMBLY__ 64#ifndef __ASSEMBLY__
58extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); 65extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
diff --git a/arch/arm/include/asm/memblock.h b/arch/arm/include/asm/memblock.h
index fdbc43b2e6c0..b8da2e415e4e 100644
--- a/arch/arm/include/asm/memblock.h
+++ b/arch/arm/include/asm/memblock.h
@@ -1,13 +1,6 @@
1#ifndef _ASM_ARM_MEMBLOCK_H 1#ifndef _ASM_ARM_MEMBLOCK_H
2#define _ASM_ARM_MEMBLOCK_H 2#define _ASM_ARM_MEMBLOCK_H
3 3
4#ifdef CONFIG_MMU
5extern phys_addr_t lowmem_end_addr;
6#define MEMBLOCK_REAL_LIMIT lowmem_end_addr
7#else
8#define MEMBLOCK_REAL_LIMIT 0
9#endif
10
11struct meminfo; 4struct meminfo;
12struct machine_desc; 5struct machine_desc;
13 6
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index 25f76bae57ab..fc1900925275 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -25,6 +25,9 @@ struct outer_cache_fns {
25 void (*inv_range)(unsigned long, unsigned long); 25 void (*inv_range)(unsigned long, unsigned long);
26 void (*clean_range)(unsigned long, unsigned long); 26 void (*clean_range)(unsigned long, unsigned long);
27 void (*flush_range)(unsigned long, unsigned long); 27 void (*flush_range)(unsigned long, unsigned long);
28 void (*flush_all)(void);
29 void (*inv_all)(void);
30 void (*disable)(void);
28#ifdef CONFIG_OUTER_CACHE_SYNC 31#ifdef CONFIG_OUTER_CACHE_SYNC
29 void (*sync)(void); 32 void (*sync)(void);
30#endif 33#endif
@@ -50,6 +53,24 @@ static inline void outer_flush_range(unsigned long start, unsigned long end)
50 outer_cache.flush_range(start, end); 53 outer_cache.flush_range(start, end);
51} 54}
52 55
56static inline void outer_flush_all(void)
57{
58 if (outer_cache.flush_all)
59 outer_cache.flush_all();
60}
61
62static inline void outer_inv_all(void)
63{
64 if (outer_cache.inv_all)
65 outer_cache.inv_all();
66}
67
68static inline void outer_disable(void)
69{
70 if (outer_cache.disable)
71 outer_cache.disable();
72}
73
53#else 74#else
54 75
55static inline void outer_inv_range(unsigned long start, unsigned long end) 76static inline void outer_inv_range(unsigned long start, unsigned long end)
@@ -58,6 +79,9 @@ static inline void outer_clean_range(unsigned long start, unsigned long end)
58{ } 79{ }
59static inline void outer_flush_range(unsigned long start, unsigned long end) 80static inline void outer_flush_range(unsigned long start, unsigned long end)
60{ } 81{ }
82static inline void outer_flush_all(void) { }
83static inline void outer_inv_all(void) { }
84static inline void outer_disable(void) { }
61 85
62#endif 86#endif
63 87
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 1fc74cbd1a19..3a8fd5140d7a 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -78,7 +78,10 @@ void machine_kexec(struct kimage *image)
78 local_fiq_disable(); 78 local_fiq_disable();
79 setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/ 79 setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
80 flush_cache_all(); 80 flush_cache_all();
81 outer_flush_all();
82 outer_disable();
81 cpu_proc_fin(); 83 cpu_proc_fin();
84 outer_inv_all();
82 flush_cache_all(); 85 flush_cache_all();
83 cpu_reset(reboot_code_buffer_phys); 86 cpu_reset(reboot_code_buffer_phys);
84} 87}
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 1953e3d21abf..cead8893b46b 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -113,6 +113,7 @@ SECTIONS
113 *(.rodata.*) 113 *(.rodata.*)
114 *(.glue_7) 114 *(.glue_7)
115 *(.glue_7t) 115 *(.glue_7t)
116 . = ALIGN(4);
116 *(.got) /* Global offset table */ 117 *(.got) /* Global offset table */
117 ARM_CPU_KEEP(PROC_INFO) 118 ARM_CPU_KEEP(PROC_INFO)
118 } 119 }
diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c
index b8bbd31aa850..84a5ba03f1ba 100644
--- a/arch/arm/mach-imx/mach-mx27_3ds.c
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -23,16 +23,20 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/input/matrix_keypad.h> 25#include <linux/input/matrix_keypad.h>
26#include <linux/irq.h>
26#include <asm/mach-types.h> 27#include <asm/mach-types.h>
27#include <asm/mach/arch.h> 28#include <asm/mach/arch.h>
28#include <asm/mach/time.h> 29#include <asm/mach/time.h>
29#include <mach/hardware.h> 30#include <mach/hardware.h>
30#include <mach/common.h> 31#include <mach/common.h>
31#include <mach/iomux-mx27.h> 32#include <mach/iomux-mx27.h>
33#include <mach/mmc.h>
32 34
33#include "devices-imx27.h" 35#include "devices-imx27.h"
34#include "devices.h" 36#include "devices.h"
35 37
38#define SD1_EN_GPIO (GPIO_PORTB + 25)
39
36static const int mx27pdk_pins[] __initconst = { 40static const int mx27pdk_pins[] __initconst = {
37 /* UART1 */ 41 /* UART1 */
38 PE12_PF_UART1_TXD, 42 PE12_PF_UART1_TXD,
@@ -58,6 +62,14 @@ static const int mx27pdk_pins[] __initconst = {
58 PD15_AOUT_FEC_COL, 62 PD15_AOUT_FEC_COL,
59 PD16_AIN_FEC_TX_ER, 63 PD16_AIN_FEC_TX_ER,
60 PF23_AIN_FEC_TX_EN, 64 PF23_AIN_FEC_TX_EN,
65 /* SDHC1 */
66 PE18_PF_SD1_D0,
67 PE19_PF_SD1_D1,
68 PE20_PF_SD1_D2,
69 PE21_PF_SD1_D3,
70 PE22_PF_SD1_CMD,
71 PE23_PF_SD1_CLK,
72 SD1_EN_GPIO | GPIO_GPIO | GPIO_OUT,
61}; 73};
62 74
63static const struct imxuart_platform_data uart_pdata __initconst = { 75static const struct imxuart_platform_data uart_pdata __initconst = {
@@ -85,13 +97,39 @@ static struct matrix_keymap_data mx27_3ds_keymap_data = {
85 .keymap_size = ARRAY_SIZE(mx27_3ds_keymap), 97 .keymap_size = ARRAY_SIZE(mx27_3ds_keymap),
86}; 98};
87 99
100static int mx27_3ds_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
101 void *data)
102{
103 return request_irq(IRQ_GPIOB(26), detect_irq, IRQF_TRIGGER_FALLING |
104 IRQF_TRIGGER_RISING, "sdhc1-card-detect", data);
105}
106
107static void mx27_3ds_sdhc1_exit(struct device *dev, void *data)
108{
109 free_irq(IRQ_GPIOB(26), data);
110}
111
112static struct imxmmc_platform_data sdhc1_pdata = {
113 .init = mx27_3ds_sdhc1_init,
114 .exit = mx27_3ds_sdhc1_exit,
115};
116
117static void mx27_3ds_sdhc1_enable_level_translator(void)
118{
119 /* Turn on TXB0108 OE pin */
120 gpio_request(SD1_EN_GPIO, "sd1_enable");
121 gpio_direction_output(SD1_EN_GPIO, 1);
122}
123
88static void __init mx27pdk_init(void) 124static void __init mx27pdk_init(void)
89{ 125{
90 mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins), 126 mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
91 "mx27pdk"); 127 "mx27pdk");
128 mx27_3ds_sdhc1_enable_level_translator();
92 imx27_add_imx_uart0(&uart_pdata); 129 imx27_add_imx_uart0(&uart_pdata);
93 imx27_add_fec(NULL); 130 imx27_add_fec(NULL);
94 mxc_register_device(&imx_kpp_device, &mx27_3ds_keymap_data); 131 mxc_register_device(&imx_kpp_device, &mx27_3ds_keymap_data);
132 mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
95} 133}
96 134
97static void __init mx27pdk_timer_init(void) 135static void __init mx27pdk_timer_init(void)
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index babb22597163..e24e3d05397f 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -197,7 +197,7 @@ unsigned long ixp2000_gettimeoffset (void)
197 return offset / ticks_per_usec; 197 return offset / ticks_per_usec;
198} 198}
199 199
200static int ixp2000_timer_interrupt(int irq, void *dev_id) 200static irqreturn_t ixp2000_timer_interrupt(int irq, void *dev_id)
201{ 201{
202 /* clear timer 1 */ 202 /* clear timer 1 */
203 ixp2000_reg_wrb(IXP2000_T1_CLR, 1); 203 ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
diff --git a/arch/arm/mach-mx25/Kconfig b/arch/arm/mach-mx25/Kconfig
index aa57e35ce3cd..38ca09a5df9d 100644
--- a/arch/arm/mach-mx25/Kconfig
+++ b/arch/arm/mach-mx25/Kconfig
@@ -6,6 +6,7 @@ config MACH_MX25_3DS
6 bool "Support MX25PDK (3DS) Platform" 6 bool "Support MX25PDK (3DS) Platform"
7 select IMX_HAVE_PLATFORM_IMX_UART 7 select IMX_HAVE_PLATFORM_IMX_UART
8 select IMX_HAVE_PLATFORM_MXC_NAND 8 select IMX_HAVE_PLATFORM_MXC_NAND
9 select IMX_HAVE_PLATFORM_ESDHC
9 10
10config MACH_EUKREA_CPUIMX25 11config MACH_EUKREA_CPUIMX25
11 bool "Support Eukrea CPUIMX25 Platform" 12 bool "Support Eukrea CPUIMX25 Platform"
diff --git a/arch/arm/mach-mx25/mach-mx25_3ds.c b/arch/arm/mach-mx25/mach-mx25_3ds.c
index 80805107a73e..f8be1eb0c062 100644
--- a/arch/arm/mach-mx25/mach-mx25_3ds.c
+++ b/arch/arm/mach-mx25/mach-mx25_3ds.c
@@ -96,6 +96,14 @@ static struct pad_desc mx25pdk_pads[] = {
96 MX25_PAD_KPP_COL1__KPP_COL1, 96 MX25_PAD_KPP_COL1__KPP_COL1,
97 MX25_PAD_KPP_COL2__KPP_COL2, 97 MX25_PAD_KPP_COL2__KPP_COL2,
98 MX25_PAD_KPP_COL3__KPP_COL3, 98 MX25_PAD_KPP_COL3__KPP_COL3,
99
100 /* SD1 */
101 MX25_PAD_SD1_CMD__SD1_CMD,
102 MX25_PAD_SD1_CLK__SD1_CLK,
103 MX25_PAD_SD1_DATA0__SD1_DATA0,
104 MX25_PAD_SD1_DATA1__SD1_DATA1,
105 MX25_PAD_SD1_DATA2__SD1_DATA2,
106 MX25_PAD_SD1_DATA3__SD1_DATA3,
99}; 107};
100 108
101static const struct fec_platform_data mx25_fec_pdata __initconst = { 109static const struct fec_platform_data mx25_fec_pdata __initconst = {
@@ -193,6 +201,8 @@ static void __init mx25pdk_init(void)
193 mx25pdk_fec_reset(); 201 mx25pdk_fec_reset();
194 imx25_add_fec(&mx25_fec_pdata); 202 imx25_add_fec(&mx25_fec_pdata);
195 mxc_register_device(&mx25_kpp_device, &mx25pdk_keymap_data); 203 mxc_register_device(&mx25_kpp_device, &mx25pdk_keymap_data);
204
205 imx25_add_esdhc(0, NULL);
196} 206}
197 207
198static void __init mx25pdk_timer_init(void) 208static void __init mx25pdk_timer_init(void)
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
index 096fd33f8ab9..5000ac1f93e3 100644
--- a/arch/arm/mach-mx3/Kconfig
+++ b/arch/arm/mach-mx3/Kconfig
@@ -143,8 +143,10 @@ config MACH_ARMADILLO5X0
143config MACH_MX35_3DS 143config MACH_MX35_3DS
144 bool "Support MX35PDK platform" 144 bool "Support MX35PDK platform"
145 select ARCH_MX35 145 select ARCH_MX35
146 select MXC_DEBUG_BOARD
146 select IMX_HAVE_PLATFORM_IMX_UART 147 select IMX_HAVE_PLATFORM_IMX_UART
147 select IMX_HAVE_PLATFORM_MXC_NAND 148 select IMX_HAVE_PLATFORM_MXC_NAND
149 select IMX_HAVE_PLATFORM_ESDHC
148 default n 150 default n
149 help 151 help
150 Include support for MX35PDK platform. This includes specific 152 Include support for MX35PDK platform. This includes specific
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index f4dff11aaee7..d4da9496089a 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -72,24 +72,24 @@ struct platform_device mxc_w1_master_device = {
72#ifdef CONFIG_ARCH_MX31 72#ifdef CONFIG_ARCH_MX31
73static struct resource mxcsdhc0_resources[] = { 73static struct resource mxcsdhc0_resources[] = {
74 { 74 {
75 .start = MMC_SDHC1_BASE_ADDR, 75 .start = MX31_MMC_SDHC1_BASE_ADDR,
76 .end = MMC_SDHC1_BASE_ADDR + SZ_16K - 1, 76 .end = MX31_MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
77 .flags = IORESOURCE_MEM, 77 .flags = IORESOURCE_MEM,
78 }, { 78 }, {
79 .start = MXC_INT_MMC_SDHC1, 79 .start = MX31_INT_MMC_SDHC1,
80 .end = MXC_INT_MMC_SDHC1, 80 .end = MX31_INT_MMC_SDHC1,
81 .flags = IORESOURCE_IRQ, 81 .flags = IORESOURCE_IRQ,
82 }, 82 },
83}; 83};
84 84
85static struct resource mxcsdhc1_resources[] = { 85static struct resource mxcsdhc1_resources[] = {
86 { 86 {
87 .start = MMC_SDHC2_BASE_ADDR, 87 .start = MX31_MMC_SDHC2_BASE_ADDR,
88 .end = MMC_SDHC2_BASE_ADDR + SZ_16K - 1, 88 .end = MX31_MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
89 .flags = IORESOURCE_MEM, 89 .flags = IORESOURCE_MEM,
90 }, { 90 }, {
91 .start = MXC_INT_MMC_SDHC2, 91 .start = MX31_INT_MMC_SDHC2,
92 .end = MXC_INT_MMC_SDHC2, 92 .end = MX31_INT_MMC_SDHC2,
93 .flags = IORESOURCE_IRQ, 93 .flags = IORESOURCE_IRQ,
94 }, 94 },
95}; 95};
diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c
index 5c1d0e86c91e..0ad9e7821082 100644
--- a/arch/arm/mach-mx3/mach-mx31_3ds.c
+++ b/arch/arm/mach-mx3/mach-mx31_3ds.c
@@ -38,39 +38,9 @@
38#include "devices-imx31.h" 38#include "devices-imx31.h"
39#include "devices.h" 39#include "devices.h"
40 40
41/* Definitions for components on the Debug board */
42
43/* Base address of CPLD controller on the Debug board */
44#define DEBUG_BASE_ADDRESS CS5_IO_ADDRESS(MX3x_CS5_BASE_ADDR)
45
46/* LAN9217 ethernet base address */
47#define LAN9217_BASE_ADDR MX3x_CS5_BASE_ADDR
48
49/* CPLD config and interrupt base address */
50#define CPLD_ADDR (DEBUG_BASE_ADDRESS + 0x20000)
51
52/* status, interrupt */
53#define CPLD_INT_STATUS_REG (CPLD_ADDR + 0x10)
54#define CPLD_INT_MASK_REG (CPLD_ADDR + 0x38)
55#define CPLD_INT_RESET_REG (CPLD_ADDR + 0x20)
56/* magic word for debug CPLD */
57#define CPLD_MAGIC_NUMBER1_REG (CPLD_ADDR + 0x40)
58#define CPLD_MAGIC_NUMBER2_REG (CPLD_ADDR + 0x48)
59/* CPLD code version */
60#define CPLD_CODE_VER_REG (CPLD_ADDR + 0x50)
61/* magic word for debug CPLD */
62#define CPLD_MAGIC_NUMBER3_REG (CPLD_ADDR + 0x58)
63
64/* CPLD IRQ line for external uart, external ethernet etc */ 41/* CPLD IRQ line for external uart, external ethernet etc */
65#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1) 42#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
66 43
67#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
68#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
69
70#define EXPIO_INT_ENET (MXC_EXP_IO_BASE + 0)
71
72#define MXC_MAX_EXP_IO_LINES 16
73
74/* 44/*
75 * This file contains the board-specific initialization routines. 45 * This file contains the board-specific initialization routines.
76 */ 46 */
@@ -272,7 +242,7 @@ static void __init mxc_board_init(void)
272 imx31_add_imx_uart0(&uart_pdata); 242 imx31_add_imx_uart0(&uart_pdata);
273 imx31_add_mxc_nand(&mx31_3ds_nand_board_info); 243 imx31_add_mxc_nand(&mx31_3ds_nand_board_info);
274 244
275 imx31_add_spi_imx0(&spi1_pdata); 245 imx31_add_spi_imx1(&spi1_pdata);
276 spi_register_board_info(mx31_3ds_spi_devs, 246 spi_register_board_info(mx31_3ds_spi_devs,
277 ARRAY_SIZE(mx31_3ds_spi_devs)); 247 ARRAY_SIZE(mx31_3ds_spi_devs));
278 248
@@ -281,9 +251,9 @@ static void __init mxc_board_init(void)
281 mx31_3ds_usbotg_init(); 251 mx31_3ds_usbotg_init();
282 mxc_register_device(&mxc_otg_udc_device, &usbotg_pdata); 252 mxc_register_device(&mxc_otg_udc_device, &usbotg_pdata);
283 253
284 if (!mxc_expio_init(CS5_BASE_ADDR, EXPIO_PARENT_INT)) 254 if (mxc_expio_init(MX31_CS5_BASE_ADDR, EXPIO_PARENT_INT))
285 printk(KERN_WARNING "Init of the debugboard failed, all " 255 printk(KERN_WARNING "Init of the debug board failed, all "
286 "devices on the board are unusable.\n"); 256 "devices on the debug board are unusable.\n");
287} 257}
288 258
289static void __init mx31_3ds_timer_init(void) 259static void __init mx31_3ds_timer_init(void)
diff --git a/arch/arm/mach-mx3/mach-mx35_3ds.c b/arch/arm/mach-mx3/mach-mx35_3ds.c
index 05f628d90725..b66a75aa2e88 100644
--- a/arch/arm/mach-mx3/mach-mx35_3ds.c
+++ b/arch/arm/mach-mx3/mach-mx35_3ds.c
@@ -38,11 +38,15 @@
38#include <mach/hardware.h> 38#include <mach/hardware.h>
39#include <mach/common.h> 39#include <mach/common.h>
40#include <mach/iomux-mx35.h> 40#include <mach/iomux-mx35.h>
41#include <mach/irqs.h>
42#include <mach/3ds_debugboard.h>
41#include <mach/mxc_ehci.h> 43#include <mach/mxc_ehci.h>
42 44
43#include "devices-imx35.h" 45#include "devices-imx35.h"
44#include "devices.h" 46#include "devices.h"
45 47
48#define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTA + 1)
49
46static const struct imxuart_platform_data uart_pdata __initconst = { 50static const struct imxuart_platform_data uart_pdata __initconst = {
47 .flags = IMXUART_HAVE_RTSCTS, 51 .flags = IMXUART_HAVE_RTSCTS,
48}; 52};
@@ -108,6 +112,13 @@ static struct pad_desc mx35pdk_pads[] = {
108 /* USBH1 */ 112 /* USBH1 */
109 MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR, 113 MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR,
110 MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC, 114 MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC,
115 /* SDCARD */
116 MX35_PAD_SD1_CMD__ESDHC1_CMD,
117 MX35_PAD_SD1_CLK__ESDHC1_CLK,
118 MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
119 MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
120 MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
121 MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
111}; 122};
112 123
113/* OTG config */ 124/* OTG config */
@@ -140,6 +151,11 @@ static void __init mxc_board_init(void)
140 mxc_register_device(&mxc_usbh1, &usb_host_pdata); 151 mxc_register_device(&mxc_usbh1, &usb_host_pdata);
141 152
142 imx35_add_mxc_nand(&mx35pdk_nand_board_info); 153 imx35_add_mxc_nand(&mx35pdk_nand_board_info);
154 imx35_add_esdhc(0, NULL);
155
156 if (mxc_expio_init(MX35_CS5_BASE_ADDR, EXPIO_PARENT_INT))
157 pr_warn("Init of the debugboard failed, all "
158 "devices on the debugboard are unusable.\n");
143} 159}
144 160
145static void __init mx35pdk_timer_init(void) 161static void __init mx35pdk_timer_init(void)
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index a2df9ac37996..3ec910a7a182 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -6,6 +6,7 @@ config ARCH_MX51
6 select MXC_TZIC 6 select MXC_TZIC
7 select ARCH_MXC_IOMUX_V3 7 select ARCH_MXC_IOMUX_V3
8 select ARCH_MXC_AUDMUX_V2 8 select ARCH_MXC_AUDMUX_V2
9 select ARCH_HAS_CPUFREQ
9 10
10comment "MX5 platforms:" 11comment "MX5 platforms:"
11 12
@@ -13,6 +14,7 @@ config MACH_MX51_BABBAGE
13 bool "Support MX51 BABBAGE platforms" 14 bool "Support MX51 BABBAGE platforms"
14 select IMX_HAVE_PLATFORM_IMX_I2C 15 select IMX_HAVE_PLATFORM_IMX_I2C
15 select IMX_HAVE_PLATFORM_IMX_UART 16 select IMX_HAVE_PLATFORM_IMX_UART
17 select IMX_HAVE_PLATFORM_ESDHC
16 help 18 help
17 Include support for MX51 Babbage platform, also known as MX51EVK in 19 Include support for MX51 Babbage platform, also known as MX51EVK in
18 u-boot. This includes specific configurations for the board and its 20 u-boot. This includes specific configurations for the board and its
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
index 1769c161a60d..462f177eddfe 100644
--- a/arch/arm/mach-mx5/Makefile
+++ b/arch/arm/mach-mx5/Makefile
@@ -5,6 +5,7 @@
5# Object file lists. 5# Object file lists.
6obj-y := cpu.o mm.o clock-mx51.o devices.o 6obj-y := cpu.o mm.o clock-mx51.o devices.o
7 7
8obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o
8obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o 9obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
9obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o 10obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o
10obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o 11obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
index 0821fe9b3b27..acbe30df2e69 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. 2 * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com> 3 * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
4 * 4 *
5 * The code contained herein is licensed under the GNU General Public 5 * The code contained herein is licensed under the GNU General Public
@@ -18,6 +18,8 @@
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/fsl_devices.h> 19#include <linux/fsl_devices.h>
20#include <linux/fec.h> 20#include <linux/fec.h>
21#include <linux/gpio_keys.h>
22#include <linux/input.h>
21 23
22#include <mach/common.h> 24#include <mach/common.h>
23#include <mach/hardware.h> 25#include <mach/hardware.h>
@@ -32,11 +34,13 @@
32 34
33#include "devices-imx51.h" 35#include "devices-imx51.h"
34#include "devices.h" 36#include "devices.h"
37#include "cpu_op-mx51.h"
35 38
36#define BABBAGE_USB_HUB_RESET (0*32 + 7) /* GPIO_1_7 */ 39#define BABBAGE_USB_HUB_RESET (0*32 + 7) /* GPIO_1_7 */
37#define BABBAGE_USBH1_STP (0*32 + 27) /* GPIO_1_27 */ 40#define BABBAGE_USBH1_STP (0*32 + 27) /* GPIO_1_27 */
38#define BABBAGE_PHY_RESET (1*32 + 5) /* GPIO_2_5 */ 41#define BABBAGE_PHY_RESET (1*32 + 5) /* GPIO_2_5 */
39#define BABBAGE_FEC_PHY_RESET (1*32 + 14) /* GPIO_2_14 */ 42#define BABBAGE_FEC_PHY_RESET (1*32 + 14) /* GPIO_2_14 */
43#define BABBAGE_POWER_KEY (1*32 + 21) /* GPIO_2_21 */
40 44
41/* USB_CTRL_1 */ 45/* USB_CTRL_1 */
42#define MX51_USB_CTRL_1_OFFSET 0x10 46#define MX51_USB_CTRL_1_OFFSET 0x10
@@ -46,6 +50,21 @@
46#define MX51_USB_PLL_DIV_19_2_MHZ 0x01 50#define MX51_USB_PLL_DIV_19_2_MHZ 0x01
47#define MX51_USB_PLL_DIV_24_MHZ 0x02 51#define MX51_USB_PLL_DIV_24_MHZ 0x02
48 52
53static struct gpio_keys_button babbage_buttons[] = {
54 {
55 .gpio = BABBAGE_POWER_KEY,
56 .code = BTN_0,
57 .desc = "PWR",
58 .active_low = 1,
59 .wakeup = 1,
60 },
61};
62
63static const struct gpio_keys_platform_data imx_button_data __initconst = {
64 .buttons = babbage_buttons,
65 .nbuttons = ARRAY_SIZE(babbage_buttons),
66};
67
49static struct pad_desc mx51babbage_pads[] = { 68static struct pad_desc mx51babbage_pads[] = {
50 /* UART1 */ 69 /* UART1 */
51 MX51_PAD_UART1_RXD__UART1_RXD, 70 MX51_PAD_UART1_RXD__UART1_RXD,
@@ -112,6 +131,22 @@ static struct pad_desc mx51babbage_pads[] = {
112 131
113 /* FEC PHY reset line */ 132 /* FEC PHY reset line */
114 MX51_PAD_EIM_A20__GPIO_2_14, 133 MX51_PAD_EIM_A20__GPIO_2_14,
134
135 /* SD 1 */
136 MX51_PAD_SD1_CMD__SD1_CMD,
137 MX51_PAD_SD1_CLK__SD1_CLK,
138 MX51_PAD_SD1_DATA0__SD1_DATA0,
139 MX51_PAD_SD1_DATA1__SD1_DATA1,
140 MX51_PAD_SD1_DATA2__SD1_DATA2,
141 MX51_PAD_SD1_DATA3__SD1_DATA3,
142
143 /* SD 2 */
144 MX51_PAD_SD2_CMD__SD2_CMD,
145 MX51_PAD_SD2_CLK__SD2_CLK,
146 MX51_PAD_SD2_DATA0__SD2_DATA0,
147 MX51_PAD_SD2_DATA1__SD2_DATA1,
148 MX51_PAD_SD2_DATA2__SD2_DATA2,
149 MX51_PAD_SD2_DATA3__SD2_DATA3,
115}; 150};
116 151
117/* Serial ports */ 152/* Serial ports */
@@ -281,13 +316,22 @@ __setup("otg_mode=", babbage_otg_mode);
281static void __init mxc_board_init(void) 316static void __init mxc_board_init(void)
282{ 317{
283 struct pad_desc usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP; 318 struct pad_desc usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP;
319 struct pad_desc power_key = MX51_PAD_EIM_A27__GPIO_2_21;
284 320
321#if defined(CONFIG_CPU_FREQ_IMX)
322 get_cpu_op = mx51_get_cpu_op;
323#endif
285 mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads, 324 mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
286 ARRAY_SIZE(mx51babbage_pads)); 325 ARRAY_SIZE(mx51babbage_pads));
287 mxc_init_imx_uart(); 326 mxc_init_imx_uart();
288 babbage_fec_reset(); 327 babbage_fec_reset();
289 imx51_add_fec(NULL); 328 imx51_add_fec(NULL);
290 329
330 /* Set the PAD settings for the pwr key. */
331 power_key.pad_ctrl = MX51_GPIO_PAD_CTRL_2;
332 mxc_iomux_v3_setup_pad(&power_key);
333 imx51_add_gpio_keys(&imx_button_data);
334
291 imx51_add_imx_i2c(0, &babbage_i2c_data); 335 imx51_add_imx_i2c(0, &babbage_i2c_data);
292 imx51_add_imx_i2c(1, &babbage_i2c_data); 336 imx51_add_imx_i2c(1, &babbage_i2c_data);
293 mxc_register_device(&mxc_hsi2c_device, &babbage_hsi2c_data); 337 mxc_register_device(&mxc_hsi2c_device, &babbage_hsi2c_data);
@@ -304,6 +348,9 @@ static void __init mxc_board_init(void)
304 /* setback USBH1_STP to be function */ 348 /* setback USBH1_STP to be function */
305 mxc_iomux_v3_setup_pad(&usbh1stp); 349 mxc_iomux_v3_setup_pad(&usbh1stp);
306 babbage_usbhub_reset(); 350 babbage_usbhub_reset();
351
352 imx51_add_esdhc(0, NULL);
353 imx51_add_esdhc(1, NULL);
307} 354}
308 355
309static void __init mx51_babbage_timer_init(void) 356static void __init mx51_babbage_timer_init(void)
diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c
index f2aae92cf0e2..8ac36d882927 100644
--- a/arch/arm/mach-mx5/clock-mx51.c
+++ b/arch/arm/mach-mx5/clock-mx51.c
@@ -362,7 +362,7 @@ static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
362 return 0; 362 return 0;
363} 363}
364 364
365static unsigned long clk_arm_get_rate(struct clk *clk) 365static unsigned long clk_cpu_get_rate(struct clk *clk)
366{ 366{
367 u32 cacrr, div; 367 u32 cacrr, div;
368 unsigned long parent_rate; 368 unsigned long parent_rate;
@@ -374,6 +374,22 @@ static unsigned long clk_arm_get_rate(struct clk *clk)
374 return parent_rate / div; 374 return parent_rate / div;
375} 375}
376 376
377static int clk_cpu_set_rate(struct clk *clk, unsigned long rate)
378{
379 u32 reg, cpu_podf;
380 unsigned long parent_rate;
381
382 parent_rate = clk_get_rate(clk->parent);
383 cpu_podf = parent_rate / rate - 1;
384 /* use post divider to change freq */
385 reg = __raw_readl(MXC_CCM_CACRR);
386 reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK;
387 reg |= cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET;
388 __raw_writel(reg, MXC_CCM_CACRR);
389
390 return 0;
391}
392
377static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent) 393static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
378{ 394{
379 u32 reg, mux; 395 u32 reg, mux;
@@ -736,7 +752,8 @@ static struct clk periph_apm_clk = {
736 752
737static struct clk cpu_clk = { 753static struct clk cpu_clk = {
738 .parent = &pll1_sw_clk, 754 .parent = &pll1_sw_clk,
739 .get_rate = clk_arm_get_rate, 755 .get_rate = clk_cpu_get_rate,
756 .set_rate = clk_cpu_set_rate,
740}; 757};
741 758
742static struct clk ahb_clk = { 759static struct clk ahb_clk = {
@@ -1064,6 +1081,7 @@ static struct clk_lookup lookups[] = {
1064 _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk) 1081 _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk)
1065 _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) 1082 _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
1066 _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk) 1083 _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
1084 _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
1067}; 1085};
1068 1086
1069static void clk_tree_init(void) 1087static void clk_tree_init(void)
diff --git a/arch/arm/mach-mx5/cpu_op-mx51.c b/arch/arm/mach-mx5/cpu_op-mx51.c
new file mode 100644
index 000000000000..9d34c3d4c024
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu_op-mx51.c
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
5/*
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14#include <linux/types.h>
15#include <mach/hardware.h>
16#include <linux/kernel.h>
17
18static struct cpu_op mx51_cpu_op[] = {
19 {
20 .cpu_rate = 160000000,},
21 {
22 .cpu_rate = 800000000,},
23};
24
25struct cpu_op *mx51_get_cpu_op(int *op)
26{
27 *op = ARRAY_SIZE(mx51_cpu_op);
28 return mx51_cpu_op;
29}
diff --git a/arch/arm/mach-mx5/cpu_op-mx51.h b/arch/arm/mach-mx5/cpu_op-mx51.h
new file mode 100644
index 000000000000..97477fecb469
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu_op-mx51.h
@@ -0,0 +1,14 @@
1/*
2 * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
5/*
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14extern struct cpu_op *mx51_get_cpu_op(int *op);
diff --git a/arch/arm/mach-mx5/devices-imx51.h b/arch/arm/mach-mx5/devices-imx51.h
index 5cc910e60538..8c50cb5d05f5 100644
--- a/arch/arm/mach-mx5/devices-imx51.h
+++ b/arch/arm/mach-mx5/devices-imx51.h
@@ -13,6 +13,8 @@ extern const struct imx_fec_data imx51_fec_data __initconst;
13#define imx51_add_fec(pdata) \ 13#define imx51_add_fec(pdata) \
14 imx_add_fec(&imx51_fec_data, pdata) 14 imx_add_fec(&imx51_fec_data, pdata)
15 15
16#define imx51_add_gpio_keys(pdata) imx_add_gpio_keys(pdata)
17
16extern const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst; 18extern const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst;
17#define imx51_add_imx_i2c(id, pdata) \ 19#define imx51_add_imx_i2c(id, pdata) \
18 imx_add_imx_i2c(&imx51_imx_i2c_data[id], pdata) 20 imx_add_imx_i2c(&imx51_imx_i2c_data[id], pdata)
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 923f9f5f91ce..2f895553e6a8 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -44,6 +44,13 @@ void __init gic_init_irq(void)
44} 44}
45 45
46#ifdef CONFIG_CACHE_L2X0 46#ifdef CONFIG_CACHE_L2X0
47
48static void omap4_l2x0_disable(void)
49{
50 /* Disable PL310 L2 Cache controller */
51 omap_smc1(0x102, 0x0);
52}
53
47static int __init omap_l2_cache_init(void) 54static int __init omap_l2_cache_init(void)
48{ 55{
49 /* 56 /*
@@ -70,6 +77,12 @@ static int __init omap_l2_cache_init(void)
70 else 77 else
71 l2x0_init(l2cache_base, 0x0e070000, 0xc0000fff); 78 l2x0_init(l2cache_base, 0x0e070000, 0xc0000fff);
72 79
80 /*
81 * Override default outer_cache.disable with a OMAP4
82 * specific one
83 */
84 outer_cache.disable = omap4_l2x0_disable;
85
73 return 0; 86 return 0;
74} 87}
75early_initcall(omap_l2_cache_init); 88early_initcall(omap_l2_cache_init);
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio.h b/arch/arm/mach-s3c2410/include/mach/gpio.h
index b649bf2ccd5c..f7f6b07df30e 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio.h
@@ -22,6 +22,8 @@
22 22
23#ifdef CONFIG_CPU_S3C244X 23#ifdef CONFIG_CPU_S3C244X
24#define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA) 24#define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
25#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
26#define ARCH_NR_GPIOS (32 * 12 + CONFIG_S3C24XX_GPIO_EXTRA)
25#else 27#else
26#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA) 28#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA)
27#endif 29#endif
@@ -30,8 +32,10 @@
30#include <mach/gpio-nrs.h> 32#include <mach/gpio-nrs.h>
31#include <mach/gpio-fns.h> 33#include <mach/gpio-fns.h>
32 34
33#ifdef CONFIG_CPU_S3C24XX 35#ifdef CONFIG_CPU_S3C244X
34#define S3C_GPIO_END (S3C2410_GPIO_BANKJ + 32) 36#define S3C_GPIO_END (S3C2410_GPJ(0) + 32)
37#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
38#define S3C_GPIO_END (S3C2410_GPM(0) + 32)
35#else 39#else
36#define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32) 40#define S3C_GPIO_END (S3C2410_GPH(0) + 32)
37#endif 41#endif
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
index 08ab9dfb6ae6..101aeea22310 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
@@ -118,6 +118,8 @@
118#define S3C2443_SCLKCON_UARTCLK (1<<8) 118#define S3C2443_SCLKCON_UARTCLK (1<<8)
119#define S3C2443_SCLKCON_USBHOST (1<<1) 119#define S3C2443_SCLKCON_USBHOST (1<<1)
120 120
121#define S3C2443_PWRCFG_SLEEP (1<<15)
122
121#include <asm/div64.h> 123#include <asm/div64.h>
122 124
123static inline unsigned int 125static inline unsigned int
diff --git a/arch/arm/mach-s3c2410/include/mach/vmalloc.h b/arch/arm/mach-s3c2410/include/mach/vmalloc.h
index 54297eb0bf5e..7a311e8dddba 100644
--- a/arch/arm/mach-s3c2410/include/mach/vmalloc.h
+++ b/arch/arm/mach-s3c2410/include/mach/vmalloc.h
@@ -15,6 +15,6 @@
15#ifndef __ASM_ARCH_VMALLOC_H 15#ifndef __ASM_ARCH_VMALLOC_H
16#define __ASM_ARCH_VMALLOC_H 16#define __ASM_ARCH_VMALLOC_H
17 17
18#define VMALLOC_END 0xE0000000UL 18#define VMALLOC_END 0xF6000000UL
19 19
20#endif /* __ASM_ARCH_VMALLOC_H */ 20#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index bef39f77729d..4c6df51ddf33 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -51,6 +51,7 @@
51#include <plat/clock.h> 51#include <plat/clock.h>
52#include <plat/pm.h> 52#include <plat/pm.h>
53#include <plat/pll.h> 53#include <plat/pll.h>
54#include <plat/nand-core.h>
54 55
55#ifndef CONFIG_CPU_S3C2412_ONLY 56#ifndef CONFIG_CPU_S3C2412_ONLY
56void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; 57void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
@@ -92,7 +93,7 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
92 /* rename devices that are s3c2412/s3c2413 specific */ 93 /* rename devices that are s3c2412/s3c2413 specific */
93 s3c_device_sdi.name = "s3c2412-sdi"; 94 s3c_device_sdi.name = "s3c2412-sdi";
94 s3c_device_lcd.name = "s3c2412-lcd"; 95 s3c_device_lcd.name = "s3c2412-lcd";
95 s3c_device_nand.name = "s3c2412-nand"; 96 s3c_nand_setname("s3c2412-nand");
96 97
97 /* alter IRQ of SDI controller */ 98 /* alter IRQ of SDI controller */
98 99
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
index 657e4fe17f39..87b9c9f003bd 100644
--- a/arch/arm/mach-s3c2416/Kconfig
+++ b/arch/arm/mach-s3c2416/Kconfig
@@ -25,6 +25,11 @@ config S3C2416_DMA
25 help 25 help
26 Internal config node for S3C2416 DMA support 26 Internal config node for S3C2416 DMA support
27 27
28config S3C2416_PM
29 bool
30 help
31 Internal config node to apply S3C2416 power management
32
28menu "S3C2416 Machines" 33menu "S3C2416 Machines"
29 34
30config MACH_SMDK2416 35config MACH_SMDK2416
@@ -33,6 +38,7 @@ config MACH_SMDK2416
33 select S3C_DEV_FB 38 select S3C_DEV_FB
34 select S3C_DEV_HSMMC 39 select S3C_DEV_HSMMC
35 select S3C_DEV_HSMMC1 40 select S3C_DEV_HSMMC1
41 select S3C2416_PM if PM
36 help 42 help
37 Say Y here if you are using an SMDK2416 43 Say Y here if you are using an SMDK2416
38 44
diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile
index 6c12c7bf40ad..ef038d62ffdb 100644
--- a/arch/arm/mach-s3c2416/Makefile
+++ b/arch/arm/mach-s3c2416/Makefile
@@ -11,7 +11,7 @@ obj- :=
11 11
12obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o 12obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o
13obj-$(CONFIG_CPU_S3C2416) += irq.o 13obj-$(CONFIG_CPU_S3C2416) += irq.o
14 14obj-$(CONFIG_S3C2416_PM) += pm.o
15#obj-$(CONFIG_S3C2416_DMA) += dma.o 15#obj-$(CONFIG_S3C2416_DMA) += dma.o
16 16
17# Machine support 17# Machine support
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
index 89f521d59d06..084d121f368c 100644
--- a/arch/arm/mach-s3c2416/irq.c
+++ b/arch/arm/mach-s3c2416/irq.c
@@ -243,6 +243,8 @@ static int __init s3c2416_irq_add(struct sys_device *sysdev)
243 243
244static struct sysdev_driver s3c2416_irq_driver = { 244static struct sysdev_driver s3c2416_irq_driver = {
245 .add = s3c2416_irq_add, 245 .add = s3c2416_irq_add,
246 .suspend = s3c24xx_irq_suspend,
247 .resume = s3c24xx_irq_resume,
246}; 248};
247 249
248static int __init s3c2416_irq_init(void) 250static int __init s3c2416_irq_init(void)
diff --git a/arch/arm/mach-s3c2416/pm.c b/arch/arm/mach-s3c2416/pm.c
new file mode 100644
index 000000000000..4a04205b04d5
--- /dev/null
+++ b/arch/arm/mach-s3c2416/pm.c
@@ -0,0 +1,84 @@
1/* linux/arch/arm/mach-s3c2416/pm.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S3C2416 - PM support (Based on Ben Dooks' S3C2412 PM support)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/sysdev.h>
14#include <linux/io.h>
15
16#include <asm/cacheflush.h>
17
18#include <mach/regs-power.h>
19#include <mach/regs-s3c2443-clock.h>
20
21#include <plat/cpu.h>
22#include <plat/pm.h>
23
24extern void s3c2412_sleep_enter(void);
25
26static void s3c2416_cpu_suspend(void)
27{
28 flush_cache_all();
29
30 /* enable wakeup sources regardless of battery state */
31 __raw_writel(S3C2443_PWRCFG_SLEEP, S3C2443_PWRCFG);
32
33 /* set the mode as sleep, 2BED represents "Go to BED" */
34 __raw_writel(0x2BED, S3C2443_PWRMODE);
35
36 s3c2412_sleep_enter();
37}
38
39static void s3c2416_pm_prepare(void)
40{
41 /*
42 * write the magic value u-boot uses to check for resume into
43 * the INFORM0 register, and ensure INFORM1 is set to the
44 * correct address to resume from.
45 */
46 __raw_writel(0x2BED, S3C2412_INFORM0);
47 __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
48}
49
50static int s3c2416_pm_add(struct sys_device *sysdev)
51{
52 pm_cpu_prep = s3c2416_pm_prepare;
53 pm_cpu_sleep = s3c2416_cpu_suspend;
54
55 return 0;
56}
57
58static int s3c2416_pm_suspend(struct sys_device *dev, pm_message_t state)
59{
60 return 0;
61}
62
63static int s3c2416_pm_resume(struct sys_device *dev)
64{
65 /* unset the return-from-sleep amd inform flags */
66 __raw_writel(0x0, S3C2443_PWRMODE);
67 __raw_writel(0x0, S3C2412_INFORM0);
68 __raw_writel(0x0, S3C2412_INFORM1);
69
70 return 0;
71}
72
73static struct sysdev_driver s3c2416_pm_driver = {
74 .add = s3c2416_pm_add,
75 .suspend = s3c2416_pm_suspend,
76 .resume = s3c2416_pm_resume,
77};
78
79static __init int s3c2416_pm_init(void)
80{
81 return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_pm_driver);
82}
83
84arch_initcall(s3c2416_pm_init);
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
index bc30245e133b..63f39cdc0972 100644
--- a/arch/arm/mach-s3c2416/s3c2416.c
+++ b/arch/arm/mach-s3c2416/s3c2416.c
@@ -56,6 +56,7 @@
56 56
57#include <plat/iic-core.h> 57#include <plat/iic-core.h>
58#include <plat/fb-core.h> 58#include <plat/fb-core.h>
59#include <plat/nand-core.h>
59 60
60static struct map_desc s3c2416_iodesc[] __initdata = { 61static struct map_desc s3c2416_iodesc[] __initdata = {
61 IODESC_ENT(WATCHDOG), 62 IODESC_ENT(WATCHDOG),
@@ -100,7 +101,7 @@ void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
100{ 101{
101 s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no); 102 s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
102 103
103 s3c_device_nand.name = "s3c2416-nand"; 104 s3c_nand_setname("s3c2412-nand");
104} 105}
105 106
106/* s3c2416_map_io 107/* s3c2416_map_io
diff --git a/arch/arm/mach-s3c2440/s3c244x.c b/arch/arm/mach-s3c2440/s3c244x.c
index 5e4a97e76533..90c1707b9c95 100644
--- a/arch/arm/mach-s3c2440/s3c244x.c
+++ b/arch/arm/mach-s3c2440/s3c244x.c
@@ -44,6 +44,7 @@
44#include <plat/cpu.h> 44#include <plat/cpu.h>
45#include <plat/pm.h> 45#include <plat/pm.h>
46#include <plat/pll.h> 46#include <plat/pll.h>
47#include <plat/nand-core.h>
47 48
48static struct map_desc s3c244x_iodesc[] __initdata = { 49static struct map_desc s3c244x_iodesc[] __initdata = {
49 IODESC_ENT(CLKPWR), 50 IODESC_ENT(CLKPWR),
@@ -68,7 +69,7 @@ void __init s3c244x_map_io(void)
68 69
69 s3c_device_sdi.name = "s3c2440-sdi"; 70 s3c_device_sdi.name = "s3c2440-sdi";
70 s3c_device_i2c0.name = "s3c2440-i2c"; 71 s3c_device_i2c0.name = "s3c2440-i2c";
71 s3c_device_nand.name = "s3c2440-nand"; 72 s3c_nand_setname("s3c2440-nand");
72 s3c_device_ts.name = "s3c2440-ts"; 73 s3c_device_ts.name = "s3c2440-ts";
73 s3c_device_usbgadget.name = "s3c2440-usbgadget"; 74 s3c_device_usbgadget.name = "s3c2440-usbgadget";
74} 75}
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
index 839b6b2ced74..33d18dd1ebd5 100644
--- a/arch/arm/mach-s3c2443/s3c2443.c
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -36,6 +36,7 @@
36#include <plat/devs.h> 36#include <plat/devs.h>
37#include <plat/cpu.h> 37#include <plat/cpu.h>
38#include <plat/fb-core.h> 38#include <plat/fb-core.h>
39#include <plat/nand-core.h>
39 40
40static struct map_desc s3c2443_iodesc[] __initdata = { 41static struct map_desc s3c2443_iodesc[] __initdata = {
41 IODESC_ENT(WATCHDOG), 42 IODESC_ENT(WATCHDOG),
@@ -62,7 +63,7 @@ int __init s3c2443_init(void)
62 63
63 s3c24xx_reset_hook = s3c2443_hard_reset; 64 s3c24xx_reset_hook = s3c2443_hard_reset;
64 65
65 s3c_device_nand.name = "s3c2412-nand"; 66 s3c_nand_setname("s3c2412-nand");
66 s3c_fb_setname("s3c2443-fb"); 67 s3c_fb_setname("s3c2443-fb");
67 68
68 /* change WDT IRQ number */ 69 /* change WDT IRQ number */
diff --git a/arch/arm/mach-s3c24a0/include/mach/vmalloc.h b/arch/arm/mach-s3c24a0/include/mach/vmalloc.h
index 914656820794..6480b15277f3 100644
--- a/arch/arm/mach-s3c24a0/include/mach/vmalloc.h
+++ b/arch/arm/mach-s3c24a0/include/mach/vmalloc.h
@@ -12,6 +12,6 @@
12#ifndef __ASM_ARCH_VMALLOC_H 12#ifndef __ASM_ARCH_VMALLOC_H
13#define __ASM_ARCH_VMALLOC_H 13#define __ASM_ARCH_VMALLOC_H
14 14
15#define VMALLOC_END (0xe0000000UL) 15#define VMALLOC_END 0xF6000000UL
16 16
17#endif /* __ASM_ARCH_VMALLOC_H */ 17#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index 546db5cb8929..1ca7bdc6485c 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -98,12 +98,33 @@ config MACH_ANW6410
98 help 98 help
99 Machine support for the A&W6410 99 Machine support for the A&W6410
100 100
101config MACH_MINI6410
102 bool "MINI6410"
103 select CPU_S3C6410
104 select S3C_DEV_HSMMC
105 select S3C_DEV_HSMMC1
106 select S3C64XX_SETUP_SDHCI
107 select S3C_DEV_USB_HOST
108 select S3C_DEV_NAND
109 select S3C_DEV_FB
110 select S3C64XX_SETUP_FB_24BPP
111 select SAMSUNG_DEV_ADC
112 select SAMSUNG_DEV_TS
113 help
114 Machine support for the FriendlyARM MINI6410
115
101config MACH_REAL6410 116config MACH_REAL6410
102 bool "REAL6410" 117 bool "REAL6410"
103 select CPU_S3C6410 118 select CPU_S3C6410
104 select S3C_DEV_HSMMC 119 select S3C_DEV_HSMMC
105 select S3C_DEV_HSMMC1 120 select S3C_DEV_HSMMC1
106 select S3C64XX_SETUP_SDHCI 121 select S3C64XX_SETUP_SDHCI
122 select S3C_DEV_FB
123 select S3C64XX_SETUP_FB_24BPP
124 select S3C_DEV_NAND
125 select SAMSUNG_DEV_ADC
126 select SAMSUNG_DEV_TS
127 select S3C_DEV_USB_HOST
107 help 128 help
108 Machine support for the CoreWind REAL6410 129 Machine support for the CoreWind REAL6410
109 130
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
index 90221a2e0c55..4657363f0674 100644
--- a/arch/arm/mach-s3c64xx/Makefile
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o
53obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o 53obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o
54obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o 54obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o
55obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o 55obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o
56obj-$(CONFIG_MACH_MINI6410) += mach-mini6410.o
56obj-$(CONFIG_MACH_NCP) += mach-ncp.o 57obj-$(CONFIG_MACH_NCP) += mach-ncp.o
57obj-$(CONFIG_MACH_HMT) += mach-hmt.o 58obj-$(CONFIG_MACH_HMT) += mach-hmt.o
58obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o 59obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
index 3838335f125b..76426a32c013 100644
--- a/arch/arm/mach-s3c64xx/dev-audio.c
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -22,27 +22,16 @@
22#include <plat/audio.h> 22#include <plat/audio.h>
23#include <plat/gpio-cfg.h> 23#include <plat/gpio-cfg.h>
24 24
25#include <mach/gpio-bank-c.h>
26#include <mach/gpio-bank-d.h>
27#include <mach/gpio-bank-e.h>
28#include <mach/gpio-bank-h.h>
29
30static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) 25static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
31{ 26{
27 unsigned int base;
28
32 switch (pdev->id) { 29 switch (pdev->id) {
33 case 0: 30 case 0:
34 s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); 31 base = S3C64XX_GPD(0);
35 s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK);
36 s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_I2S0_LRCLK);
37 s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_I2S0_DI);
38 s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_I2S0_D0);
39 break; 32 break;
40 case 1: 33 case 1:
41 s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK); 34 base = S3C64XX_GPE(0);
42 s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_I2S1_CDCLK);
43 s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK);
44 s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI);
45 s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0);
46 break; 35 break;
47 default: 36 default:
48 printk(KERN_DEBUG "Invalid I2S Controller number: %d\n", 37 printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
@@ -50,18 +39,17 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
50 return -EINVAL; 39 return -EINVAL;
51 } 40 }
52 41
42 s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
43
53 return 0; 44 return 0;
54} 45}
55 46
56static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev) 47static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
57{ 48{
58 s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_I2S_V40_DO0); 49 s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
59 s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_I2S_V40_DO1); 50 s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
60 s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_I2S_V40_DO2); 51 s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
61 s3c_gpio_cfgpin(S3C64XX_GPH(6), S3C64XX_GPH6_I2S_V40_BCLK); 52 s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
62 s3c_gpio_cfgpin(S3C64XX_GPH(7), S3C64XX_GPH7_I2S_V40_CDCLK);
63 s3c_gpio_cfgpin(S3C64XX_GPH(8), S3C64XX_GPH8_I2S_V40_LRCLK);
64 s3c_gpio_cfgpin(S3C64XX_GPH(9), S3C64XX_GPH9_I2S_V40_DI);
65 53
66 return 0; 54 return 0;
67} 55}
@@ -170,20 +158,14 @@ EXPORT_SYMBOL(s3c64xx_device_iisv4);
170 158
171static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev) 159static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
172{ 160{
161 unsigned int base;
162
173 switch (pdev->id) { 163 switch (pdev->id) {
174 case 0: 164 case 0:
175 s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_PCM0_SCLK); 165 base = S3C64XX_GPD(0);
176 s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_PCM0_EXTCLK);
177 s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_PCM0_FSYNC);
178 s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_PCM0_SIN);
179 s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_PCM0_SOUT);
180 break; 166 break;
181 case 1: 167 case 1:
182 s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_PCM1_SCLK); 168 base = S3C64XX_GPE(0);
183 s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_PCM1_EXTCLK);
184 s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_PCM1_FSYNC);
185 s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_PCM1_SIN);
186 s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_PCM1_SOUT);
187 break; 169 break;
188 default: 170 default:
189 printk(KERN_DEBUG "Invalid PCM Controller number: %d\n", 171 printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
@@ -191,6 +173,7 @@ static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
191 return -EINVAL; 173 return -EINVAL;
192 } 174 }
193 175
176 s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
194 return 0; 177 return 0;
195} 178}
196 179
@@ -264,24 +247,12 @@ EXPORT_SYMBOL(s3c64xx_device_pcm1);
264 247
265static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev) 248static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
266{ 249{
267 s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_AC97_BITCLK); 250 return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
268 s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_AC97_nRESET);
269 s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_AC97_SYNC);
270 s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_AC97_SDI);
271 s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_AC97_SDO);
272
273 return 0;
274} 251}
275 252
276static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev) 253static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
277{ 254{
278 s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_AC97_BITCLK); 255 return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
279 s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_AC97_nRESET);
280 s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_AC97_SYNC);
281 s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_AC97_SDI);
282 s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_AC97_SDO);
283
284 return 0;
285} 256}
286 257
287static struct resource s3c64xx_ac97_resource[] = { 258static struct resource s3c64xx_ac97_resource[] = {
diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c
index 300dee4a667b..fd99a82e82c4 100644
--- a/arch/arm/mach-s3c64xx/gpiolib.c
+++ b/arch/arm/mach-s3c64xx/gpiolib.c
@@ -195,11 +195,6 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
195 .get_pull = s3c_gpio_getpull_updown, 195 .get_pull = s3c_gpio_getpull_updown,
196}; 196};
197 197
198int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin)
199{
200 return IRQ_EINT(0) + pin;
201}
202
203static struct s3c_gpio_chip gpio_2bit[] = { 198static struct s3c_gpio_chip gpio_2bit[] = {
204 { 199 {
205 .base = S3C64XX_GPF_BASE, 200 .base = S3C64XX_GPF_BASE,
@@ -227,12 +222,13 @@ static struct s3c_gpio_chip gpio_2bit[] = {
227 }, 222 },
228 }, { 223 }, {
229 .base = S3C64XX_GPN_BASE, 224 .base = S3C64XX_GPN_BASE,
225 .irq_base = IRQ_EINT(0),
230 .config = &gpio_2bit_cfg_eint10, 226 .config = &gpio_2bit_cfg_eint10,
231 .chip = { 227 .chip = {
232 .base = S3C64XX_GPN(0), 228 .base = S3C64XX_GPN(0),
233 .ngpio = S3C64XX_GPIO_N_NR, 229 .ngpio = S3C64XX_GPIO_N_NR,
234 .label = "GPN", 230 .label = "GPN",
235 .to_irq = s3c64xx_gpio2int_gpn, 231 .to_irq = samsung_gpiolib_to_irq,
236 }, 232 },
237 }, { 233 }, {
238 .base = S3C64XX_GPO_BASE, 234 .base = S3C64XX_GPO_BASE,
diff --git a/arch/arm/mach-s3c64xx/include/mach/vmalloc.h b/arch/arm/mach-s3c64xx/include/mach/vmalloc.h
index bc0e91389864..23f75e556a30 100644
--- a/arch/arm/mach-s3c64xx/include/mach/vmalloc.h
+++ b/arch/arm/mach-s3c64xx/include/mach/vmalloc.h
@@ -15,6 +15,6 @@
15#ifndef __ASM_ARCH_VMALLOC_H 15#ifndef __ASM_ARCH_VMALLOC_H
16#define __ASM_ARCH_VMALLOC_H 16#define __ASM_ARCH_VMALLOC_H
17 17
18#define VMALLOC_END 0xE0000000UL 18#define VMALLOC_END 0xF6000000UL
19 19
20#endif /* __ASM_ARCH_VMALLOC_H */ 20#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
new file mode 100644
index 000000000000..249c62956471
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -0,0 +1,357 @@
1/* linux/arch/arm/mach-s3c64xx/mach-mini6410.c
2 *
3 * Copyright 2010 Darius Augulis <augulis.darius@gmail.com>
4 * Copyright 2008 Openmoko, Inc.
5 * Copyright 2008 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 * http://armlinux.simtec.co.uk/
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13*/
14
15#include <linux/init.h>
16#include <linux/interrupt.h>
17#include <linux/fb.h>
18#include <linux/gpio.h>
19#include <linux/kernel.h>
20#include <linux/list.h>
21#include <linux/dm9000.h>
22#include <linux/mtd/mtd.h>
23#include <linux/mtd/partitions.h>
24#include <linux/serial_core.h>
25#include <linux/types.h>
26
27#include <asm/mach-types.h>
28#include <asm/mach/arch.h>
29#include <asm/mach/map.h>
30
31#include <mach/map.h>
32#include <mach/regs-fb.h>
33#include <mach/regs-gpio.h>
34#include <mach/regs-modem.h>
35#include <mach/regs-srom.h>
36#include <mach/s3c6410.h>
37
38#include <plat/adc.h>
39#include <plat/cpu.h>
40#include <plat/devs.h>
41#include <plat/fb.h>
42#include <plat/nand.h>
43#include <plat/regs-serial.h>
44#include <plat/ts.h>
45
46#include <video/platform_lcd.h>
47
48#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
49#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
50#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
51
52static struct s3c2410_uartcfg mini6410_uartcfgs[] __initdata = {
53 [0] = {
54 .hwport = 0,
55 .flags = 0,
56 .ucon = UCON,
57 .ulcon = ULCON,
58 .ufcon = UFCON,
59 },
60 [1] = {
61 .hwport = 1,
62 .flags = 0,
63 .ucon = UCON,
64 .ulcon = ULCON,
65 .ufcon = UFCON,
66 },
67 [2] = {
68 .hwport = 2,
69 .flags = 0,
70 .ucon = UCON,
71 .ulcon = ULCON,
72 .ufcon = UFCON,
73 },
74 [3] = {
75 .hwport = 3,
76 .flags = 0,
77 .ucon = UCON,
78 .ulcon = ULCON,
79 .ufcon = UFCON,
80 },
81};
82
83/* DM9000AEP 10/100 ethernet controller */
84
85static struct resource mini6410_dm9k_resource[] = {
86 [0] = {
87 .start = S3C64XX_PA_XM0CSN1,
88 .end = S3C64XX_PA_XM0CSN1 + 1,
89 .flags = IORESOURCE_MEM
90 },
91 [1] = {
92 .start = S3C64XX_PA_XM0CSN1 + 4,
93 .end = S3C64XX_PA_XM0CSN1 + 5,
94 .flags = IORESOURCE_MEM
95 },
96 [2] = {
97 .start = S3C_EINT(7),
98 .end = S3C_EINT(7),
99 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL
100 }
101};
102
103static struct dm9000_plat_data mini6410_dm9k_pdata = {
104 .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
105};
106
107static struct platform_device mini6410_device_eth = {
108 .name = "dm9000",
109 .id = -1,
110 .num_resources = ARRAY_SIZE(mini6410_dm9k_resource),
111 .resource = mini6410_dm9k_resource,
112 .dev = {
113 .platform_data = &mini6410_dm9k_pdata,
114 },
115};
116
117static struct mtd_partition mini6410_nand_part[] = {
118 [0] = {
119 .name = "uboot",
120 .size = SZ_1M,
121 .offset = 0,
122 },
123 [1] = {
124 .name = "kernel",
125 .size = SZ_2M,
126 .offset = SZ_1M,
127 },
128 [2] = {
129 .name = "rootfs",
130 .size = MTDPART_SIZ_FULL,
131 .offset = SZ_1M + SZ_2M,
132 },
133};
134
135static struct s3c2410_nand_set mini6410_nand_sets[] = {
136 [0] = {
137 .name = "nand",
138 .nr_chips = 1,
139 .nr_partitions = ARRAY_SIZE(mini6410_nand_part),
140 .partitions = mini6410_nand_part,
141 },
142};
143
144static struct s3c2410_platform_nand mini6410_nand_info = {
145 .tacls = 25,
146 .twrph0 = 55,
147 .twrph1 = 40,
148 .nr_sets = ARRAY_SIZE(mini6410_nand_sets),
149 .sets = mini6410_nand_sets,
150};
151
152static struct s3c_fb_pd_win mini6410_fb_win[] = {
153 {
154 .win_mode = { /* 4.3" 480x272 */
155 .left_margin = 3,
156 .right_margin = 2,
157 .upper_margin = 1,
158 .lower_margin = 1,
159 .hsync_len = 40,
160 .vsync_len = 1,
161 .xres = 480,
162 .yres = 272,
163 },
164 .max_bpp = 32,
165 .default_bpp = 16,
166 }, {
167 .win_mode = { /* 7.0" 800x480 */
168 .left_margin = 8,
169 .right_margin = 13,
170 .upper_margin = 7,
171 .lower_margin = 5,
172 .hsync_len = 3,
173 .vsync_len = 1,
174 .xres = 800,
175 .yres = 480,
176 },
177 .max_bpp = 32,
178 .default_bpp = 16,
179 },
180};
181
182static struct s3c_fb_platdata mini6410_lcd_pdata __initdata = {
183 .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
184 .win[0] = &mini6410_fb_win[0],
185 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
186 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
187};
188
189static void mini6410_lcd_power_set(struct plat_lcd_data *pd,
190 unsigned int power)
191{
192 if (power)
193 gpio_direction_output(S3C64XX_GPE(0), 1);
194 else
195 gpio_direction_output(S3C64XX_GPE(0), 0);
196}
197
198static struct plat_lcd_data mini6410_lcd_power_data = {
199 .set_power = mini6410_lcd_power_set,
200};
201
202static struct platform_device mini6410_lcd_powerdev = {
203 .name = "platform-lcd",
204 .dev.parent = &s3c_device_fb.dev,
205 .dev.platform_data = &mini6410_lcd_power_data,
206};
207
208static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
209 .delay = 10000,
210 .presc = 49,
211 .oversampling_shift = 2,
212};
213
214static struct platform_device *mini6410_devices[] __initdata = {
215 &mini6410_device_eth,
216 &s3c_device_hsmmc0,
217 &s3c_device_hsmmc1,
218 &s3c_device_ohci,
219 &s3c_device_nand,
220 &s3c_device_fb,
221 &mini6410_lcd_powerdev,
222 &s3c_device_adc,
223 &s3c_device_ts,
224};
225
226static void __init mini6410_map_io(void)
227{
228 u32 tmp;
229
230 s3c64xx_init_io(NULL, 0);
231 s3c24xx_init_clocks(12000000);
232 s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs));
233
234 /* set the LCD type */
235 tmp = __raw_readl(S3C64XX_SPCON);
236 tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
237 tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
238 __raw_writel(tmp, S3C64XX_SPCON);
239
240 /* remove the LCD bypass */
241 tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
242 tmp &= ~MIFPCON_LCD_BYPASS;
243 __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
244}
245
246/*
247 * mini6410_features string
248 *
249 * 0-9 LCD configuration
250 *
251 */
252static char mini6410_features_str[12] __initdata = "0";
253
254static int __init mini6410_features_setup(char *str)
255{
256 if (str)
257 strlcpy(mini6410_features_str, str,
258 sizeof(mini6410_features_str));
259 return 1;
260}
261
262__setup("mini6410=", mini6410_features_setup);
263
264#define FEATURE_SCREEN (1 << 0)
265
266struct mini6410_features_t {
267 int done;
268 int lcd_index;
269};
270
271static void mini6410_parse_features(
272 struct mini6410_features_t *features,
273 const char *features_str)
274{
275 const char *fp = features_str;
276
277 features->done = 0;
278 features->lcd_index = 0;
279
280 while (*fp) {
281 char f = *fp++;
282
283 switch (f) {
284 case '0'...'9': /* tft screen */
285 if (features->done & FEATURE_SCREEN) {
286 printk(KERN_INFO "MINI6410: '%c' ignored, "
287 "screen type already set\n", f);
288 } else {
289 int li = f - '0';
290 if (li >= ARRAY_SIZE(mini6410_fb_win))
291 printk(KERN_INFO "MINI6410: '%c' out "
292 "of range LCD mode\n", f);
293 else {
294 features->lcd_index = li;
295 }
296 }
297 features->done |= FEATURE_SCREEN;
298 break;
299 }
300 }
301}
302
303static void __init mini6410_machine_init(void)
304{
305 u32 cs1;
306 struct mini6410_features_t features = { 0 };
307
308 printk(KERN_INFO "MINI6410: Option string mini6410=%s\n",
309 mini6410_features_str);
310
311 /* Parse the feature string */
312 mini6410_parse_features(&features, mini6410_features_str);
313
314 mini6410_lcd_pdata.win[0] = &mini6410_fb_win[features.lcd_index];
315
316 printk(KERN_INFO "MINI6410: selected LCD display is %dx%d\n",
317 mini6410_lcd_pdata.win[0]->win_mode.xres,
318 mini6410_lcd_pdata.win[0]->win_mode.yres);
319
320 s3c_nand_set_platdata(&mini6410_nand_info);
321 s3c_fb_set_platdata(&mini6410_lcd_pdata);
322 s3c24xx_ts_set_platdata(&s3c_ts_platform);
323
324 /* configure nCS1 width to 16 bits */
325
326 cs1 = __raw_readl(S3C64XX_SROM_BW) &
327 ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
328 cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
329 (1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
330 (1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
331 S3C64XX_SROM_BW__NCS1__SHIFT;
332 __raw_writel(cs1, S3C64XX_SROM_BW);
333
334 /* set timing for nCS1 suitable for ethernet chip */
335
336 __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
337 (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
338 (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
339 (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
340 (13 << S3C64XX_SROM_BCX__TACC__SHIFT) |
341 (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
342 (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
343
344 gpio_request(S3C64XX_GPF(15), "LCD power");
345 gpio_request(S3C64XX_GPE(0), "LCD power");
346
347 platform_add_devices(mini6410_devices, ARRAY_SIZE(mini6410_devices));
348}
349
350MACHINE_START(MINI6410, "MINI6410")
351 /* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
352 .boot_params = S3C64XX_PA_SDRAM + 0x100,
353 .init_irq = s3c6410_init_irq,
354 .map_io = mini6410_map_io,
355 .init_machine = mini6410_machine_init,
356 .timer = &s3c24xx_timer,
357MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c
index 4b4475da8ec6..f9ef9b5c5f5a 100644
--- a/arch/arm/mach-s3c64xx/mach-real6410.c
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -12,23 +12,39 @@
12 * 12 *
13*/ 13*/
14 14
15#include <linux/kernel.h> 15#include <linux/init.h>
16#include <linux/types.h>
17#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/fb.h>
18#include <linux/gpio.h>
19#include <linux/kernel.h>
18#include <linux/list.h> 20#include <linux/list.h>
19#include <linux/init.h>
20#include <linux/dm9000.h> 21#include <linux/dm9000.h>
21#include <linux/serial_core.h> 22#include <linux/mtd/mtd.h>
23#include <linux/mtd/partitions.h>
22#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/serial_core.h>
26#include <linux/types.h>
27
23#include <asm/mach-types.h> 28#include <asm/mach-types.h>
24#include <asm/mach/arch.h> 29#include <asm/mach/arch.h>
25#include <asm/mach/map.h> 30#include <asm/mach/map.h>
31
26#include <mach/map.h> 32#include <mach/map.h>
27#include <mach/s3c6410.h> 33#include <mach/regs-fb.h>
34#include <mach/regs-gpio.h>
35#include <mach/regs-modem.h>
28#include <mach/regs-srom.h> 36#include <mach/regs-srom.h>
37#include <mach/s3c6410.h>
38
39#include <plat/adc.h>
29#include <plat/cpu.h> 40#include <plat/cpu.h>
30#include <plat/devs.h> 41#include <plat/devs.h>
42#include <plat/fb.h>
43#include <plat/nand.h>
31#include <plat/regs-serial.h> 44#include <plat/regs-serial.h>
45#include <plat/ts.h>
46
47#include <video/platform_lcd.h>
32 48
33#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK) 49#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
34#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) 50#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
@@ -99,22 +115,192 @@ static struct platform_device real6410_device_eth = {
99 }, 115 },
100}; 116};
101 117
118static struct s3c_fb_pd_win real6410_fb_win[] = {
119 {
120 .win_mode = { /* 4.3" 480x272 */
121 .left_margin = 3,
122 .right_margin = 2,
123 .upper_margin = 1,
124 .lower_margin = 1,
125 .hsync_len = 40,
126 .vsync_len = 1,
127 .xres = 480,
128 .yres = 272,
129 },
130 .max_bpp = 32,
131 .default_bpp = 16,
132 }, {
133 .win_mode = { /* 7.0" 800x480 */
134 .left_margin = 8,
135 .right_margin = 13,
136 .upper_margin = 7,
137 .lower_margin = 5,
138 .hsync_len = 3,
139 .vsync_len = 1,
140 .xres = 800,
141 .yres = 480,
142 },
143 .max_bpp = 32,
144 .default_bpp = 16,
145 },
146};
147
148static struct s3c_fb_platdata real6410_lcd_pdata __initdata = {
149 .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
150 .win[0] = &real6410_fb_win[0],
151 .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
152 .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
153};
154
155static struct mtd_partition real6410_nand_part[] = {
156 [0] = {
157 .name = "uboot",
158 .size = SZ_1M,
159 .offset = 0,
160 },
161 [1] = {
162 .name = "kernel",
163 .size = SZ_2M,
164 .offset = SZ_1M,
165 },
166 [2] = {
167 .name = "rootfs",
168 .size = MTDPART_SIZ_FULL,
169 .offset = SZ_1M + SZ_2M,
170 },
171};
172
173static struct s3c2410_nand_set real6410_nand_sets[] = {
174 [0] = {
175 .name = "nand",
176 .nr_chips = 1,
177 .nr_partitions = ARRAY_SIZE(real6410_nand_part),
178 .partitions = real6410_nand_part,
179 },
180};
181
182static struct s3c2410_platform_nand real6410_nand_info = {
183 .tacls = 25,
184 .twrph0 = 55,
185 .twrph1 = 40,
186 .nr_sets = ARRAY_SIZE(real6410_nand_sets),
187 .sets = real6410_nand_sets,
188};
189
102static struct platform_device *real6410_devices[] __initdata = { 190static struct platform_device *real6410_devices[] __initdata = {
103 &real6410_device_eth, 191 &real6410_device_eth,
104 &s3c_device_hsmmc0, 192 &s3c_device_hsmmc0,
105 &s3c_device_hsmmc1, 193 &s3c_device_hsmmc1,
194 &s3c_device_fb,
195 &s3c_device_nand,
196 &s3c_device_adc,
197 &s3c_device_ts,
198 &s3c_device_ohci,
199};
200
201static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
202 .delay = 10000,
203 .presc = 49,
204 .oversampling_shift = 2,
106}; 205};
107 206
108static void __init real6410_map_io(void) 207static void __init real6410_map_io(void)
109{ 208{
209 u32 tmp;
210
110 s3c64xx_init_io(NULL, 0); 211 s3c64xx_init_io(NULL, 0);
111 s3c24xx_init_clocks(12000000); 212 s3c24xx_init_clocks(12000000);
112 s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs)); 213 s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs));
214
215 /* set the LCD type */
216 tmp = __raw_readl(S3C64XX_SPCON);
217 tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
218 tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
219 __raw_writel(tmp, S3C64XX_SPCON);
220
221 /* remove the LCD bypass */
222 tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
223 tmp &= ~MIFPCON_LCD_BYPASS;
224 __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
225}
226
227/*
228 * real6410_features string
229 *
230 * 0-9 LCD configuration
231 *
232 */
233static char real6410_features_str[12] __initdata = "0";
234
235static int __init real6410_features_setup(char *str)
236{
237 if (str)
238 strlcpy(real6410_features_str, str,
239 sizeof(real6410_features_str));
240 return 1;
241}
242
243__setup("real6410=", real6410_features_setup);
244
245#define FEATURE_SCREEN (1 << 0)
246
247struct real6410_features_t {
248 int done;
249 int lcd_index;
250};
251
252static void real6410_parse_features(
253 struct real6410_features_t *features,
254 const char *features_str)
255{
256 const char *fp = features_str;
257
258 features->done = 0;
259 features->lcd_index = 0;
260
261 while (*fp) {
262 char f = *fp++;
263
264 switch (f) {
265 case '0'...'9': /* tft screen */
266 if (features->done & FEATURE_SCREEN) {
267 printk(KERN_INFO "REAL6410: '%c' ignored, "
268 "screen type already set\n", f);
269 } else {
270 int li = f - '0';
271 if (li >= ARRAY_SIZE(real6410_fb_win))
272 printk(KERN_INFO "REAL6410: '%c' out "
273 "of range LCD mode\n", f);
274 else {
275 features->lcd_index = li;
276 }
277 }
278 features->done |= FEATURE_SCREEN;
279 break;
280 }
281 }
113} 282}
114 283
115static void __init real6410_machine_init(void) 284static void __init real6410_machine_init(void)
116{ 285{
117 u32 cs1; 286 u32 cs1;
287 struct real6410_features_t features = { 0 };
288
289 printk(KERN_INFO "REAL6410: Option string real6410=%s\n",
290 real6410_features_str);
291
292 /* Parse the feature string */
293 real6410_parse_features(&features, real6410_features_str);
294
295 real6410_lcd_pdata.win[0] = &real6410_fb_win[features.lcd_index];
296
297 printk(KERN_INFO "REAL6410: selected LCD display is %dx%d\n",
298 real6410_lcd_pdata.win[0]->win_mode.xres,
299 real6410_lcd_pdata.win[0]->win_mode.yres);
300
301 s3c_fb_set_platdata(&real6410_lcd_pdata);
302 s3c_nand_set_platdata(&real6410_nand_info);
303 s3c24xx_ts_set_platdata(&s3c_ts_platform);
118 304
119 /* configure nCS1 width to 16 bits */ 305 /* configure nCS1 width to 16 bits */
120 306
@@ -136,6 +322,8 @@ static void __init real6410_machine_init(void)
136 (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) | 322 (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
137 (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1); 323 (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
138 324
325 gpio_request(S3C64XX_GPF(15), "LCD power");
326
139 platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices)); 327 platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices));
140} 328}
141 329
diff --git a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
index 000736877df2..8f3091182f9c 100644
--- a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
+++ b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
@@ -23,15 +23,6 @@
23 23
24extern void s3c64xx_fb_gpio_setup_24bpp(void) 24extern void s3c64xx_fb_gpio_setup_24bpp(void)
25{ 25{
26 unsigned int gpio; 26 s3c_gpio_cfgrange_nopull(S3C64XX_GPI(0), 16, S3C_GPIO_SFN(2));
27 27 s3c_gpio_cfgrange_nopull(S3C64XX_GPJ(0), 12, S3C_GPIO_SFN(2));
28 for (gpio = S3C64XX_GPI(0); gpio <= S3C64XX_GPI(15); gpio++) {
29 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
30 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
31 }
32
33 for (gpio = S3C64XX_GPJ(0); gpio <= S3C64XX_GPJ(11); gpio++) {
34 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
35 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
36 }
37} 28}
diff --git a/arch/arm/mach-s3c64xx/setup-ide.c b/arch/arm/mach-s3c64xx/setup-ide.c
index c12c315f33bc..41b425602d88 100644
--- a/arch/arm/mach-s3c64xx/setup-ide.c
+++ b/arch/arm/mach-s3c64xx/setup-ide.c
@@ -17,11 +17,11 @@
17#include <mach/map.h> 17#include <mach/map.h>
18#include <mach/regs-clock.h> 18#include <mach/regs-clock.h>
19#include <plat/gpio-cfg.h> 19#include <plat/gpio-cfg.h>
20#include <plat/ata.h>
20 21
21void s3c64xx_ide_setup_gpio(void) 22void s3c64xx_ide_setup_gpio(void)
22{ 23{
23 u32 reg; 24 u32 reg;
24 u32 gpio = 0;
25 25
26 reg = readl(S3C_MEM_SYS_CFG) & (~0x3f); 26 reg = readl(S3C_MEM_SYS_CFG) & (~0x3f);
27 27
@@ -32,15 +32,12 @@ void s3c64xx_ide_setup_gpio(void)
32 s3c_gpio_cfgpin(S3C64XX_GPB(4), S3C_GPIO_SFN(4)); 32 s3c_gpio_cfgpin(S3C64XX_GPB(4), S3C_GPIO_SFN(4));
33 33
34 /* Set XhiDATA[15:0] pins as CF Data[15:0] */ 34 /* Set XhiDATA[15:0] pins as CF Data[15:0] */
35 for (gpio = S3C64XX_GPK(0); gpio <= S3C64XX_GPK(15); gpio++) 35 s3c_gpio_cfgpin_range(S3C64XX_GPK(0), 16, S3C_GPIO_SFN(5));
36 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(5));
37 36
38 /* Set XhiADDR[2:0] pins as CF ADDR[2:0] */ 37 /* Set XhiADDR[2:0] pins as CF ADDR[2:0] */
39 for (gpio = S3C64XX_GPL(0); gpio <= S3C64XX_GPL(2); gpio++) 38 s3c_gpio_cfgpin_range(S3C64XX_GPL(0), 3, S3C_GPIO_SFN(6));
40 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
41 39
42 /* Set Xhi ctrl pins as CF ctrl pins(IORDY, IOWR, IORD, CE[0:1]) */ 40 /* Set Xhi ctrl pins as CF ctrl pins(IORDY, IOWR, IORD, CE[0:1]) */
43 s3c_gpio_cfgpin(S3C64XX_GPM(5), S3C_GPIO_SFN(1)); 41 s3c_gpio_cfgpin(S3C64XX_GPM(5), S3C_GPIO_SFN(1));
44 for (gpio = S3C64XX_GPM(0); gpio <= S3C64XX_GPM(4); gpio++) 42 s3c_gpio_cfgpin_range(S3C64XX_GPM(0), 5, S3C_GPIO_SFN(6));
45 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
46} 43}
diff --git a/arch/arm/mach-s3c64xx/setup-keypad.c b/arch/arm/mach-s3c64xx/setup-keypad.c
index abc34e4e1a93..f8ed0d22db70 100644
--- a/arch/arm/mach-s3c64xx/setup-keypad.c
+++ b/arch/arm/mach-s3c64xx/setup-keypad.c
@@ -12,23 +12,13 @@
12 12
13#include <linux/gpio.h> 13#include <linux/gpio.h>
14#include <plat/gpio-cfg.h> 14#include <plat/gpio-cfg.h>
15#include <plat/keypad.h>
15 16
16void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) 17void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
17{ 18{
18 unsigned int gpio;
19 unsigned int end;
20
21 /* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */ 19 /* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */
22 end = S3C64XX_GPK(8 + rows); 20 s3c_gpio_cfgrange_nopull(S3C64XX_GPK(8), 8 + rows, S3C_GPIO_SFN(3));
23 for (gpio = S3C64XX_GPK(8); gpio < end; gpio++) {
24 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
25 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
26 }
27 21
28 /* Set all the necessary GPL pins to special-function 3: KP_COL[x] */ 22 /* Set all the necessary GPL pins to special-function 3: KP_COL[x] */
29 end = S3C64XX_GPL(0 + cols); 23 s3c_gpio_cfgrange_nopull(S3C64XX_GPL(0), cols, S3C_GPIO_SFN(3));
30 for (gpio = S3C64XX_GPL(0); gpio < end; gpio++) {
31 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
32 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
33 }
34} 24}
diff --git a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
index 322359591374..6eac071afae2 100644
--- a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
@@ -24,16 +24,9 @@
24void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) 24void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
25{ 25{
26 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 26 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
27 unsigned int gpio;
28 unsigned int end;
29 27
30 end = S3C64XX_GPG(2 + width); 28 /* Set all the necessary GPG pins to special-function 2 */
31 29 s3c_gpio_cfgrange_nopull(S3C64XX_GPG(0), 2 + width, S3C_GPIO_SFN(2));
32 /* Set all the necessary GPG pins to special-function 0 */
33 for (gpio = S3C64XX_GPG(0); gpio < end; gpio++) {
34 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
35 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
36 }
37 30
38 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 31 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
39 s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); 32 s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
@@ -44,16 +37,9 @@ void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
44void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) 37void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
45{ 38{
46 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 39 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
47 unsigned int gpio;
48 unsigned int end;
49 40
50 end = S3C64XX_GPH(2 + width); 41 /* Set all the necessary GPH pins to special-function 2 */
51 42 s3c_gpio_cfgrange_nopull(S3C64XX_GPH(0), 2 + width, S3C_GPIO_SFN(2));
52 /* Set all the necessary GPG pins to special-function 0 */
53 for (gpio = S3C64XX_GPH(0); gpio < end; gpio++) {
54 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
55 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
56 }
57 43
58 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 44 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
59 s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); 45 s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
@@ -63,20 +49,9 @@ void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
63 49
64void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) 50void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
65{ 51{
66 unsigned int gpio; 52 /* Set all the necessary GPH pins to special-function 3 */
67 unsigned int end; 53 s3c_gpio_cfgrange_nopull(S3C64XX_GPH(6), width, S3C_GPIO_SFN(3));
68 54
69 end = S3C64XX_GPH(6 + width); 55 /* Set all the necessary GPC pins to special-function 3 */
70 56 s3c_gpio_cfgrange_nopull(S3C64XX_GPC(4), 2, S3C_GPIO_SFN(3));
71 /* Set all the necessary GPH pins to special-function 1 */
72 for (gpio = S3C64XX_GPH(6); gpio < end; gpio++) {
73 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
74 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
75 }
76
77 /* Set all the necessary GPC pins to special-function 1 */
78 for (gpio = S3C64XX_GPC(4); gpio < S3C64XX_GPC(6); gpio++) {
79 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
80 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
81 }
82} 57}
diff --git a/arch/arm/mach-s5p6442/Kconfig b/arch/arm/mach-s5p6442/Kconfig
index 0fda0a5df968..33569e4007c4 100644
--- a/arch/arm/mach-s5p6442/Kconfig
+++ b/arch/arm/mach-s5p6442/Kconfig
@@ -11,7 +11,6 @@ if ARCH_S5P6442
11 11
12config CPU_S5P6442 12config CPU_S5P6442
13 bool 13 bool
14 select PLAT_S5P
15 select S3C_PL330_DMA 14 select S3C_PL330_DMA
16 help 15 help
17 Enable S5P6442 CPU support 16 Enable S5P6442 CPU support
diff --git a/arch/arm/mach-s5p6442/clock.c b/arch/arm/mach-s5p6442/clock.c
index dcd20f17212a..16d6e7e61b50 100644
--- a/arch/arm/mach-s5p6442/clock.c
+++ b/arch/arm/mach-s5p6442/clock.c
@@ -192,6 +192,11 @@ static struct clk clk_pclkd1 = {
192 .parent = &clk_hclkd1, 192 .parent = &clk_hclkd1,
193}; 193};
194 194
195int s5p6442_clk_ip0_ctrl(struct clk *clk, int enable)
196{
197 return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
198}
199
195int s5p6442_clk_ip3_ctrl(struct clk *clk, int enable) 200int s5p6442_clk_ip3_ctrl(struct clk *clk, int enable)
196{ 201{
197 return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); 202 return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
@@ -335,6 +340,16 @@ void __init_or_cpufreq s5p6442_setup_clocks(void)
335 clk_pclkd1.rate = pclkd1; 340 clk_pclkd1.rate = pclkd1;
336} 341}
337 342
343static struct clk init_clocks_disable[] = {
344 {
345 .name = "pdma",
346 .id = -1,
347 .parent = &clk_pclkd1,
348 .enable = s5p6442_clk_ip0_ctrl,
349 .ctrlbit = (1 << 3),
350 },
351};
352
338static struct clk init_clocks[] = { 353static struct clk init_clocks[] = {
339 { 354 {
340 .name = "systimer", 355 .name = "systimer",
@@ -393,10 +408,23 @@ static struct clk *clks[] __initdata = {
393 408
394void __init s5p6442_register_clocks(void) 409void __init s5p6442_register_clocks(void)
395{ 410{
411 struct clk *clkptr;
412 int i, ret;
413
396 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); 414 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
397 415
398 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 416 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
399 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 417 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
400 418
419 clkptr = init_clocks_disable;
420 for (i = 0; i < ARRAY_SIZE(init_clocks_disable); i++, clkptr++) {
421 ret = s3c24xx_register_clock(clkptr);
422 if (ret < 0) {
423 printk(KERN_ERR "Fail to register clock %s (%d)\n",
424 clkptr->name, ret);
425 } else
426 (clkptr->enable)(clkptr, 0);
427 }
428
401 s3c_pwmclk_init(); 429 s3c_pwmclk_init();
402} 430}
diff --git a/arch/arm/mach-s5p6442/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c
index 7a4e34720b7b..3462197ff352 100644
--- a/arch/arm/mach-s5p6442/dev-audio.c
+++ b/arch/arm/mach-s5p6442/dev-audio.c
@@ -21,22 +21,16 @@
21 21
22static int s5p6442_cfg_i2s(struct platform_device *pdev) 22static int s5p6442_cfg_i2s(struct platform_device *pdev)
23{ 23{
24 unsigned int base;
25
24 /* configure GPIO for i2s port */ 26 /* configure GPIO for i2s port */
25 switch (pdev->id) { 27 switch (pdev->id) {
26 case 1: 28 case 1:
27 s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(2)); 29 base = S5P6442_GPC1(0);
28 s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(2));
29 s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(2));
30 s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(2));
31 s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(2));
32 break; 30 break;
33 31
34 case -1: 32 case -1:
35 s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(2)); 33 base = S5P6442_GPC0(0);
36 s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(2));
37 s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(2));
38 s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(2));
39 s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(2));
40 break; 34 break;
41 35
42 default: 36 default:
@@ -44,6 +38,7 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
44 return -EINVAL; 38 return -EINVAL;
45 } 39 }
46 40
41 s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
47 return 0; 42 return 0;
48} 43}
49 44
@@ -111,21 +106,15 @@ struct platform_device s5p6442_device_iis1 = {
111 106
112static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev) 107static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
113{ 108{
109 unsigned int base;
110
114 switch (pdev->id) { 111 switch (pdev->id) {
115 case 0: 112 case 0:
116 s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(3)); 113 base = S5P6442_GPC0(0);
117 s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(3));
118 s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(3));
119 s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(3));
120 s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(3));
121 break; 114 break;
122 115
123 case 1: 116 case 1:
124 s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(3)); 117 base = S5P6442_GPC1(0);
125 s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(3));
126 s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(3));
127 s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(3));
128 s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(3));
129 break; 118 break;
130 119
131 default: 120 default:
@@ -133,6 +122,7 @@ static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
133 return -EINVAL; 122 return -EINVAL;
134 } 123 }
135 124
125 s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
136 return 0; 126 return 0;
137} 127}
138 128
diff --git a/arch/arm/mach-s5p6442/dev-spi.c b/arch/arm/mach-s5p6442/dev-spi.c
index e894651a88bd..cce8c2470709 100644
--- a/arch/arm/mach-s5p6442/dev-spi.c
+++ b/arch/arm/mach-s5p6442/dev-spi.c
@@ -38,11 +38,9 @@ static int s5p6442_spi_cfg_gpio(struct platform_device *pdev)
38 switch (pdev->id) { 38 switch (pdev->id) {
39 case 0: 39 case 0:
40 s3c_gpio_cfgpin(S5P6442_GPB(0), S3C_GPIO_SFN(2)); 40 s3c_gpio_cfgpin(S5P6442_GPB(0), S3C_GPIO_SFN(2));
41 s3c_gpio_cfgpin(S5P6442_GPB(2), S3C_GPIO_SFN(2));
42 s3c_gpio_cfgpin(S5P6442_GPB(3), S3C_GPIO_SFN(2));
43 s3c_gpio_setpull(S5P6442_GPB(0), S3C_GPIO_PULL_UP); 41 s3c_gpio_setpull(S5P6442_GPB(0), S3C_GPIO_PULL_UP);
44 s3c_gpio_setpull(S5P6442_GPB(2), S3C_GPIO_PULL_UP); 42 s3c_gpio_cfgall_range(S5P6442_GPB(2), 2,
45 s3c_gpio_setpull(S5P6442_GPB(3), S3C_GPIO_PULL_UP); 43 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
46 break; 44 break;
47 45
48 default: 46 default:
diff --git a/arch/arm/mach-s5p6442/dma.c b/arch/arm/mach-s5p6442/dma.c
index ad4f8704b93d..7dfb13654f8a 100644
--- a/arch/arm/mach-s5p6442/dma.c
+++ b/arch/arm/mach-s5p6442/dma.c
@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5p6442_pdma_pdata = {
82 82
83static struct platform_device s5p6442_device_pdma = { 83static struct platform_device s5p6442_device_pdma = {
84 .name = "s3c-pl330", 84 .name = "s3c-pl330",
85 .id = 1, 85 .id = -1,
86 .num_resources = ARRAY_SIZE(s5p6442_pdma_resource), 86 .num_resources = ARRAY_SIZE(s5p6442_pdma_resource),
87 .resource = s5p6442_pdma_resource, 87 .resource = s5p6442_pdma_resource,
88 .dev = { 88 .dev = {
diff --git a/arch/arm/mach-s5p6442/include/mach/regs-clock.h b/arch/arm/mach-s5p6442/include/mach/regs-clock.h
index d8360b5d4ece..00828a336991 100644
--- a/arch/arm/mach-s5p6442/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5p6442/include/mach/regs-clock.h
@@ -46,6 +46,7 @@
46#define S5P_CLK_DIV5 S5P_CLKREG(0x314) 46#define S5P_CLK_DIV5 S5P_CLKREG(0x314)
47#define S5P_CLK_DIV6 S5P_CLKREG(0x318) 47#define S5P_CLK_DIV6 S5P_CLKREG(0x318)
48 48
49#define S5P_CLKGATE_IP0 S5P_CLKREG(0x460)
49#define S5P_CLKGATE_IP3 S5P_CLKREG(0x46C) 50#define S5P_CLKGATE_IP3 S5P_CLKREG(0x46C)
50 51
51/* CLK_OUT */ 52/* CLK_OUT */
diff --git a/arch/arm/mach-s5p6442/include/mach/vmalloc.h b/arch/arm/mach-s5p6442/include/mach/vmalloc.h
index f5c83f02c18e..4aa55e55ac47 100644
--- a/arch/arm/mach-s5p6442/include/mach/vmalloc.h
+++ b/arch/arm/mach-s5p6442/include/mach/vmalloc.h
@@ -12,6 +12,6 @@
12#ifndef __ASM_ARCH_VMALLOC_H 12#ifndef __ASM_ARCH_VMALLOC_H
13#define __ASM_ARCH_VMALLOC_H 13#define __ASM_ARCH_VMALLOC_H
14 14
15#define VMALLOC_END 0xE0000000UL 15#define VMALLOC_END 0xF6000000UL
16 16
17#endif /* __ASM_ARCH_VMALLOC_H */ 17#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index fbcae9352022..164d2783d381 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -9,14 +9,12 @@ if ARCH_S5P64X0
9 9
10config CPU_S5P6440 10config CPU_S5P6440
11 bool 11 bool
12 select PLAT_S5P
13 select S3C_PL330_DMA 12 select S3C_PL330_DMA
14 help 13 help
15 Enable S5P6440 CPU support 14 Enable S5P6440 CPU support
16 15
17config CPU_S5P6450 16config CPU_S5P6450
18 bool 17 bool
19 select PLAT_S5P
20 select S3C_PL330_DMA 18 select S3C_PL330_DMA
21 help 19 help
22 Enable S5P6450 CPU support 20 Enable S5P6450 CPU support
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index f93dcd8b4d6a..e4883dc1c8d7 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -79,13 +79,16 @@ static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
79 __raw_writel(epll_con, S5P64X0_EPLL_CON); 79 __raw_writel(epll_con, S5P64X0_EPLL_CON);
80 __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K); 80 __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
81 81
82 printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
83 clk->rate, rate);
84
82 clk->rate = rate; 85 clk->rate = rate;
83 86
84 return 0; 87 return 0;
85} 88}
86 89
87static struct clk_ops s5p6440_epll_ops = { 90static struct clk_ops s5p6440_epll_ops = {
88 .get_rate = s5p64x0_epll_get_rate, 91 .get_rate = s5p_epll_get_rate,
89 .set_rate = s5p6440_epll_set_rate, 92 .set_rate = s5p6440_epll_set_rate,
90}; 93};
91 94
@@ -150,6 +153,12 @@ static struct clk init_clocks_disable[] = {
150 .enable = s5p64x0_hclk0_ctrl, 153 .enable = s5p64x0_hclk0_ctrl,
151 .ctrlbit = (1 << 8), 154 .ctrlbit = (1 << 8),
152 }, { 155 }, {
156 .name = "pdma",
157 .id = -1,
158 .parent = &clk_hclk_low.clk,
159 .enable = s5p64x0_hclk0_ctrl,
160 .ctrlbit = (1 << 12),
161 }, {
153 .name = "hsmmc", 162 .name = "hsmmc",
154 .id = 0, 163 .id = 0,
155 .parent = &clk_hclk_low.clk, 164 .parent = &clk_hclk_low.clk,
@@ -331,12 +340,6 @@ static struct clk init_clocks[] = {
331 .enable = s5p64x0_hclk0_ctrl, 340 .enable = s5p64x0_hclk0_ctrl,
332 .ctrlbit = (1 << 21), 341 .ctrlbit = (1 << 21),
333 }, { 342 }, {
334 .name = "dma",
335 .id = -1,
336 .parent = &clk_hclk_low.clk,
337 .enable = s5p64x0_hclk0_ctrl,
338 .ctrlbit = (1 << 12),
339 }, {
340 .name = "uart", 343 .name = "uart",
341 .id = 0, 344 .id = 0,
342 .parent = &clk_pclk_low.clk, 345 .parent = &clk_pclk_low.clk,
@@ -548,7 +551,7 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
548 551
549 /* Set S5P6440 functions for clk_fout_epll */ 552 /* Set S5P6440 functions for clk_fout_epll */
550 553
551 clk_fout_epll.enable = s5p64x0_epll_enable; 554 clk_fout_epll.enable = s5p_epll_enable;
552 clk_fout_epll.ops = &s5p6440_epll_ops; 555 clk_fout_epll.ops = &s5p6440_epll_ops;
553 556
554 clk_48m.enable = s5p64x0_clk48m_ctrl; 557 clk_48m.enable = s5p64x0_clk48m_ctrl;
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index f9afb05b217c..7dbf3c968f53 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -80,13 +80,16 @@ static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate)
80 __raw_writel(epll_con, S5P64X0_EPLL_CON); 80 __raw_writel(epll_con, S5P64X0_EPLL_CON);
81 __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K); 81 __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
82 82
83 printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
84 clk->rate, rate);
85
83 clk->rate = rate; 86 clk->rate = rate;
84 87
85 return 0; 88 return 0;
86} 89}
87 90
88static struct clk_ops s5p6450_epll_ops = { 91static struct clk_ops s5p6450_epll_ops = {
89 .get_rate = s5p64x0_epll_get_rate, 92 .get_rate = s5p_epll_get_rate,
90 .set_rate = s5p6450_epll_set_rate, 93 .set_rate = s5p6450_epll_set_rate,
91}; 94};
92 95
@@ -186,6 +189,12 @@ static struct clk init_clocks_disable[] = {
186 .enable = s5p64x0_hclk0_ctrl, 189 .enable = s5p64x0_hclk0_ctrl,
187 .ctrlbit = (1 << 3), 190 .ctrlbit = (1 << 3),
188 }, { 191 }, {
192 .name = "pdma",
193 .id = -1,
194 .parent = &clk_hclk_low.clk,
195 .enable = s5p64x0_hclk0_ctrl,
196 .ctrlbit = (1 << 12),
197 }, {
189 .name = "hsmmc", 198 .name = "hsmmc",
190 .id = 0, 199 .id = 0,
191 .parent = &clk_hclk_low.clk, 200 .parent = &clk_hclk_low.clk,
@@ -283,12 +292,6 @@ static struct clk init_clocks[] = {
283 .enable = s5p64x0_hclk0_ctrl, 292 .enable = s5p64x0_hclk0_ctrl,
284 .ctrlbit = (1 << 21), 293 .ctrlbit = (1 << 21),
285 }, { 294 }, {
286 .name = "dma",
287 .id = -1,
288 .parent = &clk_hclk_low.clk,
289 .enable = s5p64x0_hclk0_ctrl,
290 .ctrlbit = (1 << 12),
291 }, {
292 .name = "uart", 295 .name = "uart",
293 .id = 0, 296 .id = 0,
294 .parent = &clk_pclk_low.clk, 297 .parent = &clk_pclk_low.clk,
@@ -581,7 +584,7 @@ void __init_or_cpufreq s5p6450_setup_clocks(void)
581 584
582 /* Set S5P6450 functions for clk_fout_epll */ 585 /* Set S5P6450 functions for clk_fout_epll */
583 586
584 clk_fout_epll.enable = s5p64x0_epll_enable; 587 clk_fout_epll.enable = s5p_epll_enable;
585 clk_fout_epll.ops = &s5p6450_epll_ops; 588 clk_fout_epll.ops = &s5p6450_epll_ops;
586 589
587 clk_48m.enable = s5p64x0_clk48m_ctrl; 590 clk_48m.enable = s5p64x0_clk48m_ctrl;
diff --git a/arch/arm/mach-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c
index 523ba8039ac2..b52c6e2f37a6 100644
--- a/arch/arm/mach-s5p64x0/clock.c
+++ b/arch/arm/mach-s5p64x0/clock.c
@@ -73,24 +73,6 @@ static const u32 clock_table[][3] = {
73 {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)}, 73 {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
74}; 74};
75 75
76int s5p64x0_epll_enable(struct clk *clk, int enable)
77{
78 unsigned int ctrlbit = clk->ctrlbit;
79 unsigned int epll_con = __raw_readl(S5P64X0_EPLL_CON) & ~ctrlbit;
80
81 if (enable)
82 __raw_writel(epll_con | ctrlbit, S5P64X0_EPLL_CON);
83 else
84 __raw_writel(epll_con, S5P64X0_EPLL_CON);
85
86 return 0;
87}
88
89unsigned long s5p64x0_epll_get_rate(struct clk *clk)
90{
91 return clk->rate;
92}
93
94unsigned long s5p64x0_armclk_get_rate(struct clk *clk) 76unsigned long s5p64x0_armclk_get_rate(struct clk *clk)
95{ 77{
96 unsigned long rate = clk_get_rate(clk->parent); 78 unsigned long rate = clk_get_rate(clk->parent);
diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c
index fa097bd68ca4..396bacc0a39a 100644
--- a/arch/arm/mach-s5p64x0/dev-audio.c
+++ b/arch/arm/mach-s5p64x0/dev-audio.c
@@ -24,13 +24,8 @@ static int s5p6440_cfg_i2s(struct platform_device *pdev)
24 /* configure GPIO for i2s port */ 24 /* configure GPIO for i2s port */
25 switch (pdev->id) { 25 switch (pdev->id) {
26 case -1: 26 case -1:
27 s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5)); 27 s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5));
28 s3c_gpio_cfgpin(S5P6440_GPR(5), S3C_GPIO_SFN(5)); 28 s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5));
29 s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(5));
30 s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(5));
31 s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(5));
32 s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(5));
33 s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(5));
34 break; 29 break;
35 30
36 default: 31 default:
@@ -47,13 +42,9 @@ static int s5p6450_cfg_i2s(struct platform_device *pdev)
47 switch (pdev->id) { 42 switch (pdev->id) {
48 case -1: 43 case -1:
49 s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5)); 44 s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5));
50 s3c_gpio_cfgpin(S5P6450_GPR(4), S3C_GPIO_SFN(5)); 45 s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5));
51 s3c_gpio_cfgpin(S5P6450_GPR(5), S3C_GPIO_SFN(5)); 46 s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5));
52 s3c_gpio_cfgpin(S5P6450_GPR(6), S3C_GPIO_SFN(5)); 47
53 s3c_gpio_cfgpin(S5P6450_GPR(7), S3C_GPIO_SFN(5));
54 s3c_gpio_cfgpin(S5P6450_GPR(8), S3C_GPIO_SFN(5));
55 s3c_gpio_cfgpin(S5P6450_GPR(13), S3C_GPIO_SFN(5));
56 s3c_gpio_cfgpin(S5P6450_GPR(14), S3C_GPIO_SFN(5));
57 break; 48 break;
58 49
59 default: 50 default:
@@ -116,11 +107,8 @@ static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev)
116{ 107{
117 switch (pdev->id) { 108 switch (pdev->id) {
118 case 0: 109 case 0:
119 s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2)); 110 s3c_gpio_cfgpin_range(S5P6440_GPR(6), 3, S3C_GPIO_SFN(2));
120 s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(2)); 111 s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(2));
121 s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(2));
122 s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(2));
123 s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(2));
124 break; 112 break;
125 113
126 default: 114 default:
diff --git a/arch/arm/mach-s5p64x0/dev-spi.c b/arch/arm/mach-s5p64x0/dev-spi.c
index 5b69ec4c8af3..e78ee18c76e3 100644
--- a/arch/arm/mach-s5p64x0/dev-spi.c
+++ b/arch/arm/mach-s5p64x0/dev-spi.c
@@ -39,23 +39,15 @@ static char *s5p64x0_spi_src_clks[] = {
39 */ 39 */
40static int s5p6440_spi_cfg_gpio(struct platform_device *pdev) 40static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
41{ 41{
42 unsigned int base;
43
42 switch (pdev->id) { 44 switch (pdev->id) {
43 case 0: 45 case 0:
44 s3c_gpio_cfgpin(S5P6440_GPC(0), S3C_GPIO_SFN(2)); 46 base = S5P6440_GPC(0);
45 s3c_gpio_cfgpin(S5P6440_GPC(1), S3C_GPIO_SFN(2));
46 s3c_gpio_cfgpin(S5P6440_GPC(2), S3C_GPIO_SFN(2));
47 s3c_gpio_setpull(S5P6440_GPC(0), S3C_GPIO_PULL_UP);
48 s3c_gpio_setpull(S5P6440_GPC(1), S3C_GPIO_PULL_UP);
49 s3c_gpio_setpull(S5P6440_GPC(2), S3C_GPIO_PULL_UP);
50 break; 47 break;
51 48
52 case 1: 49 case 1:
53 s3c_gpio_cfgpin(S5P6440_GPC(4), S3C_GPIO_SFN(2)); 50 base = S5P6440_GPC(4);
54 s3c_gpio_cfgpin(S5P6440_GPC(5), S3C_GPIO_SFN(2));
55 s3c_gpio_cfgpin(S5P6440_GPC(6), S3C_GPIO_SFN(2));
56 s3c_gpio_setpull(S5P6440_GPC(4), S3C_GPIO_PULL_UP);
57 s3c_gpio_setpull(S5P6440_GPC(5), S3C_GPIO_PULL_UP);
58 s3c_gpio_setpull(S5P6440_GPC(6), S3C_GPIO_PULL_UP);
59 break; 51 break;
60 52
61 default: 53 default:
@@ -63,28 +55,23 @@ static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
63 return -EINVAL; 55 return -EINVAL;
64 } 56 }
65 57
58 s3c_gpio_cfgall_range(base, 3,
59 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
60
66 return 0; 61 return 0;
67} 62}
68 63
69static int s5p6450_spi_cfg_gpio(struct platform_device *pdev) 64static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
70{ 65{
66 unsigned int base;
67
71 switch (pdev->id) { 68 switch (pdev->id) {
72 case 0: 69 case 0:
73 s3c_gpio_cfgpin(S5P6450_GPC(0), S3C_GPIO_SFN(2)); 70 base = S5P6450_GPC(0);
74 s3c_gpio_cfgpin(S5P6450_GPC(1), S3C_GPIO_SFN(2));
75 s3c_gpio_cfgpin(S5P6450_GPC(2), S3C_GPIO_SFN(2));
76 s3c_gpio_setpull(S5P6450_GPC(0), S3C_GPIO_PULL_UP);
77 s3c_gpio_setpull(S5P6450_GPC(1), S3C_GPIO_PULL_UP);
78 s3c_gpio_setpull(S5P6450_GPC(2), S3C_GPIO_PULL_UP);
79 break; 71 break;
80 72
81 case 1: 73 case 1:
82 s3c_gpio_cfgpin(S5P6450_GPC(4), S3C_GPIO_SFN(2)); 74 base = S5P6450_GPC(4);
83 s3c_gpio_cfgpin(S5P6450_GPC(5), S3C_GPIO_SFN(2));
84 s3c_gpio_cfgpin(S5P6450_GPC(6), S3C_GPIO_SFN(2));
85 s3c_gpio_setpull(S5P6450_GPC(4), S3C_GPIO_PULL_UP);
86 s3c_gpio_setpull(S5P6450_GPC(5), S3C_GPIO_PULL_UP);
87 s3c_gpio_setpull(S5P6450_GPC(6), S3C_GPIO_PULL_UP);
88 break; 75 break;
89 76
90 default: 77 default:
@@ -92,6 +79,9 @@ static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
92 return -EINVAL; 79 return -EINVAL;
93 } 80 }
94 81
82 s3c_gpio_cfgall_range(base, 3,
83 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
84
95 return 0; 85 return 0;
96} 86}
97 87
diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c
index 29a8c2410049..d7ad944b3475 100644
--- a/arch/arm/mach-s5p64x0/dma.c
+++ b/arch/arm/mach-s5p64x0/dma.c
@@ -122,7 +122,7 @@ static struct s3c_pl330_platdata s5p6450_pdma_pdata = {
122 122
123static struct platform_device s5p64x0_device_pdma = { 123static struct platform_device s5p64x0_device_pdma = {
124 .name = "s3c-pl330", 124 .name = "s3c-pl330",
125 .id = 0, 125 .id = -1,
126 .num_resources = ARRAY_SIZE(s5p64x0_pdma_resource), 126 .num_resources = ARRAY_SIZE(s5p64x0_pdma_resource),
127 .resource = s5p64x0_pdma_resource, 127 .resource = s5p64x0_pdma_resource,
128 .dev = { 128 .dev = {
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
index 58e1bc813804..a133f22fa155 100644
--- a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
@@ -60,4 +60,6 @@
60#define ARM_DIV_RATIO_SHIFT 0 60#define ARM_DIV_RATIO_SHIFT 0
61#define ARM_DIV_MASK (0xF << ARM_DIV_RATIO_SHIFT) 61#define ARM_DIV_MASK (0xF << ARM_DIV_RATIO_SHIFT)
62 62
63#define S5P_EPLL_CON S5P64X0_EPLL_CON
64
63#endif /* __ASM_ARCH_REGS_CLOCK_H */ 65#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/vmalloc.h b/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
index 97a9df38f1cf..38dcc71a03cc 100644
--- a/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
+++ b/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
@@ -15,6 +15,6 @@
15#ifndef __ASM_ARCH_VMALLOC_H 15#ifndef __ASM_ARCH_VMALLOC_H
16#define __ASM_ARCH_VMALLOC_H 16#define __ASM_ARCH_VMALLOC_H
17 17
18#define VMALLOC_END 0xE0000000UL 18#define VMALLOC_END 0xF6000000UL
19 19
20#endif /* __ASM_ARCH_VMALLOC_H */ 20#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5p64x0/setup-i2c0.c b/arch/arm/mach-s5p64x0/setup-i2c0.c
index dc4cc65a5019..46b463917c54 100644
--- a/arch/arm/mach-s5p64x0/setup-i2c0.c
+++ b/arch/arm/mach-s5p64x0/setup-i2c0.c
@@ -25,18 +25,14 @@ struct platform_device; /* don't need the contents */
25 25
26void s5p6440_i2c0_cfg_gpio(struct platform_device *dev) 26void s5p6440_i2c0_cfg_gpio(struct platform_device *dev)
27{ 27{
28 s3c_gpio_cfgpin(S5P6440_GPB(5), S3C_GPIO_SFN(2)); 28 s3c_gpio_cfgall_range(S5P6440_GPB(5), 2,
29 s3c_gpio_setpull(S5P6440_GPB(5), S3C_GPIO_PULL_UP); 29 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
30 s3c_gpio_cfgpin(S5P6440_GPB(6), S3C_GPIO_SFN(2));
31 s3c_gpio_setpull(S5P6440_GPB(6), S3C_GPIO_PULL_UP);
32} 30}
33 31
34void s5p6450_i2c0_cfg_gpio(struct platform_device *dev) 32void s5p6450_i2c0_cfg_gpio(struct platform_device *dev)
35{ 33{
36 s3c_gpio_cfgpin(S5P6450_GPB(5), S3C_GPIO_SFN(2)); 34 s3c_gpio_cfgall_range(S5P6450_GPB(5), 2,
37 s3c_gpio_setpull(S5P6450_GPB(5), S3C_GPIO_PULL_UP); 35 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
38 s3c_gpio_cfgpin(S5P6450_GPB(6), S3C_GPIO_SFN(2));
39 s3c_gpio_setpull(S5P6450_GPB(6), S3C_GPIO_PULL_UP);
40} 36}
41 37
42void s3c_i2c0_cfg_gpio(struct platform_device *dev) { } 38void s3c_i2c0_cfg_gpio(struct platform_device *dev) { }
diff --git a/arch/arm/mach-s5p64x0/setup-i2c1.c b/arch/arm/mach-s5p64x0/setup-i2c1.c
index 2edd7912f8e4..6ad3b986021c 100644
--- a/arch/arm/mach-s5p64x0/setup-i2c1.c
+++ b/arch/arm/mach-s5p64x0/setup-i2c1.c
@@ -25,18 +25,14 @@ struct platform_device; /* don't need the contents */
25 25
26void s5p6440_i2c1_cfg_gpio(struct platform_device *dev) 26void s5p6440_i2c1_cfg_gpio(struct platform_device *dev)
27{ 27{
28 s3c_gpio_cfgpin(S5P6440_GPR(9), S3C_GPIO_SFN(6)); 28 s3c_gpio_cfgall_range(S5P6440_GPR(9), 2,
29 s3c_gpio_setpull(S5P6440_GPR(9), S3C_GPIO_PULL_UP); 29 S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
30 s3c_gpio_cfgpin(S5P6440_GPR(10), S3C_GPIO_SFN(6));
31 s3c_gpio_setpull(S5P6440_GPR(10), S3C_GPIO_PULL_UP);
32} 30}
33 31
34void s5p6450_i2c1_cfg_gpio(struct platform_device *dev) 32void s5p6450_i2c1_cfg_gpio(struct platform_device *dev)
35{ 33{
36 s3c_gpio_cfgpin(S5P6450_GPR(9), S3C_GPIO_SFN(6)); 34 s3c_gpio_cfgall_range(S5P6450_GPR(9), 2,
37 s3c_gpio_setpull(S5P6450_GPR(9), S3C_GPIO_PULL_UP); 35 S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
38 s3c_gpio_cfgpin(S5P6450_GPR(10), S3C_GPIO_SFN(6));
39 s3c_gpio_setpull(S5P6450_GPR(10), S3C_GPIO_PULL_UP);
40} 36}
41 37
42void s3c_i2c1_cfg_gpio(struct platform_device *dev) { } 38void s3c_i2c1_cfg_gpio(struct platform_device *dev) { }
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 77ae4bfb74ba..b8fbf2fcba6f 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -9,7 +9,6 @@ if ARCH_S5PC100
9 9
10config CPU_S5PC100 10config CPU_S5PC100
11 bool 11 bool
12 select PLAT_S5P
13 select S5P_EXT_INT 12 select S5P_EXT_INT
14 select S3C_PL330_DMA 13 select S3C_PL330_DMA
15 help 14 help
diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile
index a021ed1fb4b6..eecab57d2e5d 100644
--- a/arch/arm/mach-s5pc100/Makefile
+++ b/arch/arm/mach-s5pc100/Makefile
@@ -11,7 +11,7 @@ obj- :=
11 11
12# Core support for S5PC100 system 12# Core support for S5PC100 system
13 13
14obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o gpiolib.o irq-gpio.o 14obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o gpiolib.o
15obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o 15obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o
16obj-$(CONFIG_CPU_S5PC100) += dma.o 16obj-$(CONFIG_CPU_S5PC100) += dma.o
17 17
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index 084abd13b0a5..2d4a761a5163 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -273,24 +273,6 @@ static struct clksrc_clk clk_div_hdmi = {
273 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 }, 273 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 },
274}; 274};
275 275
276static int s5pc100_epll_enable(struct clk *clk, int enable)
277{
278 unsigned int ctrlbit = clk->ctrlbit;
279 unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
280
281 if (enable)
282 __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
283 else
284 __raw_writel(epll_con, S5P_EPLL_CON);
285
286 return 0;
287}
288
289static unsigned long s5pc100_epll_get_rate(struct clk *clk)
290{
291 return clk->rate;
292}
293
294static u32 epll_div[][4] = { 276static u32 epll_div[][4] = {
295 { 32750000, 131, 3, 4 }, 277 { 32750000, 131, 3, 4 },
296 { 32768000, 131, 3, 4 }, 278 { 32768000, 131, 3, 4 },
@@ -341,13 +323,16 @@ static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate)
341 323
342 __raw_writel(epll_con, S5P_EPLL_CON); 324 __raw_writel(epll_con, S5P_EPLL_CON);
343 325
326 printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
327 clk->rate, rate);
328
344 clk->rate = rate; 329 clk->rate = rate;
345 330
346 return 0; 331 return 0;
347} 332}
348 333
349static struct clk_ops s5pc100_epll_ops = { 334static struct clk_ops s5pc100_epll_ops = {
350 .get_rate = s5pc100_epll_get_rate, 335 .get_rate = s5p_epll_get_rate,
351 .set_rate = s5pc100_epll_set_rate, 336 .set_rate = s5pc100_epll_set_rate,
352}; 337};
353 338
@@ -691,55 +676,55 @@ static struct clk init_clocks_disable[] = {
691 }, { 676 }, {
692 .name = "iis", 677 .name = "iis",
693 .id = 0, 678 .id = 0,
694 .parent = &clk_div_d1_bus.clk, 679 .parent = &clk_div_pclkd1.clk,
695 .enable = s5pc100_d1_5_ctrl, 680 .enable = s5pc100_d1_5_ctrl,
696 .ctrlbit = (1 << 0), 681 .ctrlbit = (1 << 0),
697 }, { 682 }, {
698 .name = "iis", 683 .name = "iis",
699 .id = 1, 684 .id = 1,
700 .parent = &clk_div_d1_bus.clk, 685 .parent = &clk_div_pclkd1.clk,
701 .enable = s5pc100_d1_5_ctrl, 686 .enable = s5pc100_d1_5_ctrl,
702 .ctrlbit = (1 << 1), 687 .ctrlbit = (1 << 1),
703 }, { 688 }, {
704 .name = "iis", 689 .name = "iis",
705 .id = 2, 690 .id = 2,
706 .parent = &clk_div_d1_bus.clk, 691 .parent = &clk_div_pclkd1.clk,
707 .enable = s5pc100_d1_5_ctrl, 692 .enable = s5pc100_d1_5_ctrl,
708 .ctrlbit = (1 << 2), 693 .ctrlbit = (1 << 2),
709 }, { 694 }, {
710 .name = "ac97", 695 .name = "ac97",
711 .id = -1, 696 .id = -1,
712 .parent = &clk_div_d1_bus.clk, 697 .parent = &clk_div_pclkd1.clk,
713 .enable = s5pc100_d1_5_ctrl, 698 .enable = s5pc100_d1_5_ctrl,
714 .ctrlbit = (1 << 3), 699 .ctrlbit = (1 << 3),
715 }, { 700 }, {
716 .name = "pcm", 701 .name = "pcm",
717 .id = 0, 702 .id = 0,
718 .parent = &clk_div_d1_bus.clk, 703 .parent = &clk_div_pclkd1.clk,
719 .enable = s5pc100_d1_5_ctrl, 704 .enable = s5pc100_d1_5_ctrl,
720 .ctrlbit = (1 << 4), 705 .ctrlbit = (1 << 4),
721 }, { 706 }, {
722 .name = "pcm", 707 .name = "pcm",
723 .id = 1, 708 .id = 1,
724 .parent = &clk_div_d1_bus.clk, 709 .parent = &clk_div_pclkd1.clk,
725 .enable = s5pc100_d1_5_ctrl, 710 .enable = s5pc100_d1_5_ctrl,
726 .ctrlbit = (1 << 5), 711 .ctrlbit = (1 << 5),
727 }, { 712 }, {
728 .name = "spdif", 713 .name = "spdif",
729 .id = -1, 714 .id = -1,
730 .parent = &clk_div_d1_bus.clk, 715 .parent = &clk_div_pclkd1.clk,
731 .enable = s5pc100_d1_5_ctrl, 716 .enable = s5pc100_d1_5_ctrl,
732 .ctrlbit = (1 << 6), 717 .ctrlbit = (1 << 6),
733 }, { 718 }, {
734 .name = "adc", 719 .name = "adc",
735 .id = -1, 720 .id = -1,
736 .parent = &clk_div_d1_bus.clk, 721 .parent = &clk_div_pclkd1.clk,
737 .enable = s5pc100_d1_5_ctrl, 722 .enable = s5pc100_d1_5_ctrl,
738 .ctrlbit = (1 << 7), 723 .ctrlbit = (1 << 7),
739 }, { 724 }, {
740 .name = "keypad", 725 .name = "keypad",
741 .id = -1, 726 .id = -1,
742 .parent = &clk_div_d1_bus.clk, 727 .parent = &clk_div_pclkd1.clk,
743 .enable = s5pc100_d1_5_ctrl, 728 .enable = s5pc100_d1_5_ctrl,
744 .ctrlbit = (1 << 8), 729 .ctrlbit = (1 << 8),
745 }, { 730 }, {
@@ -848,6 +833,18 @@ struct clksrc_sources clk_src_group3 = {
848 .nr_sources = ARRAY_SIZE(clk_src_group3_list), 833 .nr_sources = ARRAY_SIZE(clk_src_group3_list),
849}; 834};
850 835
836static struct clksrc_clk clk_sclk_audio0 = {
837 .clk = {
838 .name = "sclk_audio",
839 .id = 0,
840 .ctrlbit = (1 << 8),
841 .enable = s5pc100_sclk1_ctrl,
842 },
843 .sources = &clk_src_group3,
844 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 },
845 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
846};
847
851static struct clk *clk_src_group4_list[] = { 848static struct clk *clk_src_group4_list[] = {
852 [0] = &clk_mout_epll.clk, 849 [0] = &clk_mout_epll.clk,
853 [1] = &clk_div_mpll.clk, 850 [1] = &clk_div_mpll.clk,
@@ -862,6 +859,18 @@ struct clksrc_sources clk_src_group4 = {
862 .nr_sources = ARRAY_SIZE(clk_src_group4_list), 859 .nr_sources = ARRAY_SIZE(clk_src_group4_list),
863}; 860};
864 861
862static struct clksrc_clk clk_sclk_audio1 = {
863 .clk = {
864 .name = "sclk_audio",
865 .id = 1,
866 .ctrlbit = (1 << 9),
867 .enable = s5pc100_sclk1_ctrl,
868 },
869 .sources = &clk_src_group4,
870 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 },
871 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
872};
873
865static struct clk *clk_src_group5_list[] = { 874static struct clk *clk_src_group5_list[] = {
866 [0] = &clk_mout_epll.clk, 875 [0] = &clk_mout_epll.clk,
867 [1] = &clk_div_mpll.clk, 876 [1] = &clk_div_mpll.clk,
@@ -875,6 +884,18 @@ struct clksrc_sources clk_src_group5 = {
875 .nr_sources = ARRAY_SIZE(clk_src_group5_list), 884 .nr_sources = ARRAY_SIZE(clk_src_group5_list),
876}; 885};
877 886
887static struct clksrc_clk clk_sclk_audio2 = {
888 .clk = {
889 .name = "sclk_audio",
890 .id = 2,
891 .ctrlbit = (1 << 10),
892 .enable = s5pc100_sclk1_ctrl,
893 },
894 .sources = &clk_src_group5,
895 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 },
896 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
897};
898
878static struct clk *clk_src_group6_list[] = { 899static struct clk *clk_src_group6_list[] = {
879 [0] = &s5p_clk_27m, 900 [0] = &s5p_clk_27m,
880 [1] = &clk_vclk54m, 901 [1] = &clk_vclk54m,
@@ -944,6 +965,64 @@ struct clksrc_sources clk_src_pwi = {
944 .nr_sources = ARRAY_SIZE(clk_src_pwi_list), 965 .nr_sources = ARRAY_SIZE(clk_src_pwi_list),
945}; 966};
946 967
968static struct clk *clk_sclk_spdif_list[] = {
969 [0] = &clk_sclk_audio0.clk,
970 [1] = &clk_sclk_audio1.clk,
971 [2] = &clk_sclk_audio2.clk,
972};
973
974struct clksrc_sources clk_src_sclk_spdif = {
975 .sources = clk_sclk_spdif_list,
976 .nr_sources = ARRAY_SIZE(clk_sclk_spdif_list),
977};
978
979static int s5pc100_spdif_set_rate(struct clk *clk, unsigned long rate)
980{
981 struct clk *pclk;
982 int ret;
983
984 pclk = clk_get_parent(clk);
985 if (IS_ERR(pclk))
986 return -EINVAL;
987
988 ret = pclk->ops->set_rate(pclk, rate);
989 clk_put(pclk);
990
991 return ret;
992}
993
994static unsigned long s5pc100_spdif_get_rate(struct clk *clk)
995{
996 struct clk *pclk;
997 int rate;
998
999 pclk = clk_get_parent(clk);
1000 if (IS_ERR(pclk))
1001 return -EINVAL;
1002
1003 rate = pclk->ops->get_rate(clk);
1004 clk_put(pclk);
1005
1006 return rate;
1007}
1008
1009static struct clk_ops s5pc100_sclk_spdif_ops = {
1010 .set_rate = s5pc100_spdif_set_rate,
1011 .get_rate = s5pc100_spdif_get_rate,
1012};
1013
1014static struct clksrc_clk clk_sclk_spdif = {
1015 .clk = {
1016 .name = "sclk_spdif",
1017 .id = -1,
1018 .ctrlbit = (1 << 11),
1019 .enable = s5pc100_sclk1_ctrl,
1020 .ops = &s5pc100_sclk_spdif_ops,
1021 },
1022 .sources = &clk_src_sclk_spdif,
1023 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 24, .size = 2 },
1024};
1025
947static struct clksrc_clk clksrcs[] = { 1026static struct clksrc_clk clksrcs[] = {
948 { 1027 {
949 .clk = { 1028 .clk = {
@@ -1001,39 +1080,6 @@ static struct clksrc_clk clksrcs[] = {
1001 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 }, 1080 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 },
1002 }, { 1081 }, {
1003 .clk = { 1082 .clk = {
1004 .name = "sclk_audio",
1005 .id = 0,
1006 .ctrlbit = (1 << 8),
1007 .enable = s5pc100_sclk1_ctrl,
1008
1009 },
1010 .sources = &clk_src_group3,
1011 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 },
1012 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
1013 }, {
1014 .clk = {
1015 .name = "sclk_audio",
1016 .id = 1,
1017 .ctrlbit = (1 << 9),
1018 .enable = s5pc100_sclk1_ctrl,
1019
1020 },
1021 .sources = &clk_src_group4,
1022 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 },
1023 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
1024 }, {
1025 .clk = {
1026 .name = "sclk_audio",
1027 .id = 2,
1028 .ctrlbit = (1 << 10),
1029 .enable = s5pc100_sclk1_ctrl,
1030
1031 },
1032 .sources = &clk_src_group5,
1033 .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 },
1034 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
1035 }, {
1036 .clk = {
1037 .name = "sclk_lcd", 1083 .name = "sclk_lcd",
1038 .id = -1, 1084 .id = -1,
1039 .ctrlbit = (1 << 0), 1085 .ctrlbit = (1 << 0),
@@ -1179,6 +1225,10 @@ static struct clksrc_clk *sysclks[] = {
1179 &clk_div_pclkd1, 1225 &clk_div_pclkd1,
1180 &clk_div_cam, 1226 &clk_div_cam,
1181 &clk_div_hdmi, 1227 &clk_div_hdmi,
1228 &clk_sclk_audio0,
1229 &clk_sclk_audio1,
1230 &clk_sclk_audio2,
1231 &clk_sclk_spdif,
1182}; 1232};
1183 1233
1184void __init_or_cpufreq s5pc100_setup_clocks(void) 1234void __init_or_cpufreq s5pc100_setup_clocks(void)
@@ -1196,7 +1246,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
1196 unsigned int ptr; 1246 unsigned int ptr;
1197 1247
1198 /* Set S5PC100 functions for clk_fout_epll */ 1248 /* Set S5PC100 functions for clk_fout_epll */
1199 clk_fout_epll.enable = s5pc100_epll_enable; 1249 clk_fout_epll.enable = s5p_epll_enable;
1200 clk_fout_epll.ops = &s5pc100_epll_ops; 1250 clk_fout_epll.ops = &s5pc100_epll_ops;
1201 1251
1202 printk(KERN_DEBUG "%s: registering clocks\n", __func__); 1252 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
diff --git a/arch/arm/mach-s5pc100/dev-audio.c b/arch/arm/mach-s5pc100/dev-audio.c
index a699ed6acc23..564e195ec493 100644
--- a/arch/arm/mach-s5pc100/dev-audio.c
+++ b/arch/arm/mach-s5pc100/dev-audio.c
@@ -24,19 +24,11 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
24 /* configure GPIO for i2s port */ 24 /* configure GPIO for i2s port */
25 switch (pdev->id) { 25 switch (pdev->id) {
26 case 1: 26 case 1:
27 s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(2)); 27 s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2));
28 s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(2));
29 s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(2));
30 s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(2));
31 s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(2));
32 break; 28 break;
33 29
34 case 2: 30 case 2:
35 s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(4)); 31 s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4));
36 s3c_gpio_cfgpin(S5PC100_GPG3(1), S3C_GPIO_SFN(4));
37 s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(4));
38 s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(4));
39 s3c_gpio_cfgpin(S5PC100_GPG3(4), S3C_GPIO_SFN(4));
40 break; 32 break;
41 33
42 case -1: /* Dedicated pins */ 34 case -1: /* Dedicated pins */
@@ -144,19 +136,11 @@ static int s5pc100_pcm_cfg_gpio(struct platform_device *pdev)
144{ 136{
145 switch (pdev->id) { 137 switch (pdev->id) {
146 case 0: 138 case 0:
147 s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(5)); 139 s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(5));
148 s3c_gpio_cfgpin(S5PC100_GPG3(1), S3C_GPIO_SFN(5));
149 s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(5));
150 s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(5));
151 s3c_gpio_cfgpin(S5PC100_GPG3(4), S3C_GPIO_SFN(5));
152 break; 140 break;
153 141
154 case 1: 142 case 1:
155 s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(3)); 143 s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(3));
156 s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(3));
157 s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(3));
158 s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(3));
159 s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(3));
160 break; 144 break;
161 145
162 default: 146 default:
@@ -231,13 +215,7 @@ struct platform_device s5pc100_device_pcm1 = {
231 215
232static int s5pc100_ac97_cfg_gpio(struct platform_device *pdev) 216static int s5pc100_ac97_cfg_gpio(struct platform_device *pdev)
233{ 217{
234 s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(4)); 218 return s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(4));
235 s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(4));
236 s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(4));
237 s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(4));
238 s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(4));
239
240 return 0;
241} 219}
242 220
243static struct resource s5pc100_ac97_resource[] = { 221static struct resource s5pc100_ac97_resource[] = {
@@ -285,3 +263,57 @@ struct platform_device s5pc100_device_ac97 = {
285 .coherent_dma_mask = DMA_BIT_MASK(32), 263 .coherent_dma_mask = DMA_BIT_MASK(32),
286 }, 264 },
287}; 265};
266
267/* S/PDIF Controller platform_device */
268static int s5pc100_spdif_cfg_gpd(struct platform_device *pdev)
269{
270 s3c_gpio_cfgpin_range(S5PC100_GPD(5), 2, S3C_GPIO_SFN(3));
271
272 return 0;
273}
274
275static int s5pc100_spdif_cfg_gpg3(struct platform_device *pdev)
276{
277 s3c_gpio_cfgpin_range(S5PC100_GPG3(5), 2, S3C_GPIO_SFN(3));
278
279 return 0;
280}
281
282static struct resource s5pc100_spdif_resource[] = {
283 [0] = {
284 .start = S5PC100_PA_SPDIF,
285 .end = S5PC100_PA_SPDIF + 0x100 - 1,
286 .flags = IORESOURCE_MEM,
287 },
288 [1] = {
289 .start = DMACH_SPDIF,
290 .end = DMACH_SPDIF,
291 .flags = IORESOURCE_DMA,
292 },
293};
294
295static struct s3c_audio_pdata s5p_spdif_pdata = {
296 .cfg_gpio = s5pc100_spdif_cfg_gpd,
297};
298
299static u64 s5pc100_spdif_dmamask = DMA_BIT_MASK(32);
300
301struct platform_device s5pc100_device_spdif = {
302 .name = "samsung-spdif",
303 .id = -1,
304 .num_resources = ARRAY_SIZE(s5pc100_spdif_resource),
305 .resource = s5pc100_spdif_resource,
306 .dev = {
307 .platform_data = &s5p_spdif_pdata,
308 .dma_mask = &s5pc100_spdif_dmamask,
309 .coherent_dma_mask = DMA_BIT_MASK(32),
310 },
311};
312
313void __init s5pc100_spdif_setup_gpio(int gpio)
314{
315 if (gpio == S5PC100_SPDIF_GPD)
316 s5p_spdif_pdata.cfg_gpio = s5pc100_spdif_cfg_gpd;
317 else
318 s5p_spdif_pdata.cfg_gpio = s5pc100_spdif_cfg_gpg3;
319}
diff --git a/arch/arm/mach-s5pc100/dev-spi.c b/arch/arm/mach-s5pc100/dev-spi.c
index a0ef7c302c16..57b19794d9bb 100644
--- a/arch/arm/mach-s5pc100/dev-spi.c
+++ b/arch/arm/mach-s5pc100/dev-spi.c
@@ -38,30 +38,20 @@ static int s5pc100_spi_cfg_gpio(struct platform_device *pdev)
38{ 38{
39 switch (pdev->id) { 39 switch (pdev->id) {
40 case 0: 40 case 0:
41 s3c_gpio_cfgpin(S5PC100_GPB(0), S3C_GPIO_SFN(2)); 41 s3c_gpio_cfgall_range(S5PC100_GPB(0), 3,
42 s3c_gpio_cfgpin(S5PC100_GPB(1), S3C_GPIO_SFN(2)); 42 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
43 s3c_gpio_cfgpin(S5PC100_GPB(2), S3C_GPIO_SFN(2));
44 s3c_gpio_setpull(S5PC100_GPB(0), S3C_GPIO_PULL_UP);
45 s3c_gpio_setpull(S5PC100_GPB(1), S3C_GPIO_PULL_UP);
46 s3c_gpio_setpull(S5PC100_GPB(2), S3C_GPIO_PULL_UP);
47 break; 43 break;
48 44
49 case 1: 45 case 1:
50 s3c_gpio_cfgpin(S5PC100_GPB(4), S3C_GPIO_SFN(2)); 46 s3c_gpio_cfgall_range(S5PC100_GPB(4), 3,
51 s3c_gpio_cfgpin(S5PC100_GPB(5), S3C_GPIO_SFN(2)); 47 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
52 s3c_gpio_cfgpin(S5PC100_GPB(6), S3C_GPIO_SFN(2));
53 s3c_gpio_setpull(S5PC100_GPB(4), S3C_GPIO_PULL_UP);
54 s3c_gpio_setpull(S5PC100_GPB(5), S3C_GPIO_PULL_UP);
55 s3c_gpio_setpull(S5PC100_GPB(6), S3C_GPIO_PULL_UP);
56 break; 48 break;
57 49
58 case 2: 50 case 2:
59 s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3)); 51 s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3));
60 s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(3));
61 s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(3));
62 s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP); 52 s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP);
63 s3c_gpio_setpull(S5PC100_GPG3(2), S3C_GPIO_PULL_UP); 53 s3c_gpio_cfgall_range(S5PC100_GPB(2), 2,
64 s3c_gpio_setpull(S5PC100_GPG3(3), S3C_GPIO_PULL_UP); 54 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
65 break; 55 break;
66 56
67 default: 57 default:
diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c
index 0f5517571e2c..bf4cd0fb97c6 100644
--- a/arch/arm/mach-s5pc100/dma.c
+++ b/arch/arm/mach-s5pc100/dma.c
@@ -81,7 +81,7 @@ static struct s3c_pl330_platdata s5pc100_pdma0_pdata = {
81 81
82static struct platform_device s5pc100_device_pdma0 = { 82static struct platform_device s5pc100_device_pdma0 = {
83 .name = "s3c-pl330", 83 .name = "s3c-pl330",
84 .id = 1, 84 .id = 0,
85 .num_resources = ARRAY_SIZE(s5pc100_pdma0_resource), 85 .num_resources = ARRAY_SIZE(s5pc100_pdma0_resource),
86 .resource = s5pc100_pdma0_resource, 86 .resource = s5pc100_pdma0_resource,
87 .dev = { 87 .dev = {
@@ -143,7 +143,7 @@ static struct s3c_pl330_platdata s5pc100_pdma1_pdata = {
143 143
144static struct platform_device s5pc100_device_pdma1 = { 144static struct platform_device s5pc100_device_pdma1 = {
145 .name = "s3c-pl330", 145 .name = "s3c-pl330",
146 .id = 2, 146 .id = 1,
147 .num_resources = ARRAY_SIZE(s5pc100_pdma1_resource), 147 .num_resources = ARRAY_SIZE(s5pc100_pdma1_resource),
148 .resource = s5pc100_pdma1_resource, 148 .resource = s5pc100_pdma1_resource,
149 .dev = { 149 .dev = {
diff --git a/arch/arm/mach-s5pc100/gpiolib.c b/arch/arm/mach-s5pc100/gpiolib.c
index 0fab7f2cd8bf..20856eb7dd51 100644
--- a/arch/arm/mach-s5pc100/gpiolib.c
+++ b/arch/arm/mach-s5pc100/gpiolib.c
@@ -1,5 +1,7 @@
1/* 1/* linux/arch/arm/mach-s5pc100/gpiolib.c
2 * arch/arm/plat-s5pc100/gpiolib.c 2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
3 * 5 *
4 * Copyright 2009 Samsung Electronics Co 6 * Copyright 2009 Samsung Electronics Co
5 * Kyungmin Park <kyungmin.park@samsung.com> 7 * Kyungmin Park <kyungmin.park@samsung.com>
@@ -61,30 +63,6 @@
61 * L3 8 4Bit None 63 * L3 8 4Bit None
62 */ 64 */
63 65
64static int s5pc100_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
65{
66 return S3C_IRQ_GPIO(chip->base + offset);
67}
68
69static int s5pc100_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
70{
71 int base;
72
73 base = chip->base - S5PC100_GPH0(0);
74 if (base == 0)
75 return IRQ_EINT(offset);
76 base = chip->base - S5PC100_GPH1(0);
77 if (base == 0)
78 return IRQ_EINT(8 + offset);
79 base = chip->base - S5PC100_GPH2(0);
80 if (base == 0)
81 return IRQ_EINT(16 + offset);
82 base = chip->base - S5PC100_GPH3(0);
83 if (base == 0)
84 return IRQ_EINT(24 + offset);
85 return -EINVAL;
86}
87
88static struct s3c_gpio_cfg gpio_cfg = { 66static struct s3c_gpio_cfg gpio_cfg = {
89 .set_config = s3c_gpio_setcfg_s3c64xx_4bit, 67 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
90 .set_pull = s3c_gpio_setpull_updown, 68 .set_pull = s3c_gpio_setpull_updown,
@@ -104,209 +82,150 @@ static struct s3c_gpio_cfg gpio_cfg_noint = {
104 .get_pull = s3c_gpio_getpull_updown, 82 .get_pull = s3c_gpio_getpull_updown,
105}; 83};
106 84
85/*
86 * GPIO bank's base address given the index of the bank in the
87 * list of all gpio banks.
88 */
89#define S5PC100_BANK_BASE(bank_nr) (S5P_VA_GPIO + ((bank_nr) * 0x20))
90
91/*
92 * Following are the gpio banks in S5PC100.
93 *
94 * The 'config' member when left to NULL, is initialized to the default
95 * structure gpio_cfg in the init function below.
96 *
97 * The 'base' member is also initialized in the init function below.
98 * Note: The initialization of 'base' member of s3c_gpio_chip structure
99 * uses the above macro and depends on the banks being listed in order here.
100 */
107static struct s3c_gpio_chip s5pc100_gpio_chips[] = { 101static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
108 { 102 {
109 .base = S5PC100_GPA0_BASE,
110 .config = &gpio_cfg,
111 .chip = { 103 .chip = {
112 .base = S5PC100_GPA0(0), 104 .base = S5PC100_GPA0(0),
113 .ngpio = S5PC100_GPIO_A0_NR, 105 .ngpio = S5PC100_GPIO_A0_NR,
114 .label = "GPA0", 106 .label = "GPA0",
115 }, 107 },
116 }, { 108 }, {
117 .base = S5PC100_GPA1_BASE,
118 .config = &gpio_cfg,
119 .chip = { 109 .chip = {
120 .base = S5PC100_GPA1(0), 110 .base = S5PC100_GPA1(0),
121 .ngpio = S5PC100_GPIO_A1_NR, 111 .ngpio = S5PC100_GPIO_A1_NR,
122 .label = "GPA1", 112 .label = "GPA1",
123 }, 113 },
124 }, { 114 }, {
125 .base = S5PC100_GPB_BASE,
126 .config = &gpio_cfg,
127 .chip = { 115 .chip = {
128 .base = S5PC100_GPB(0), 116 .base = S5PC100_GPB(0),
129 .ngpio = S5PC100_GPIO_B_NR, 117 .ngpio = S5PC100_GPIO_B_NR,
130 .label = "GPB", 118 .label = "GPB",
131 }, 119 },
132 }, { 120 }, {
133 .base = S5PC100_GPC_BASE,
134 .config = &gpio_cfg,
135 .chip = { 121 .chip = {
136 .base = S5PC100_GPC(0), 122 .base = S5PC100_GPC(0),
137 .ngpio = S5PC100_GPIO_C_NR, 123 .ngpio = S5PC100_GPIO_C_NR,
138 .label = "GPC", 124 .label = "GPC",
139 }, 125 },
140 }, { 126 }, {
141 .base = S5PC100_GPD_BASE,
142 .config = &gpio_cfg,
143 .chip = { 127 .chip = {
144 .base = S5PC100_GPD(0), 128 .base = S5PC100_GPD(0),
145 .ngpio = S5PC100_GPIO_D_NR, 129 .ngpio = S5PC100_GPIO_D_NR,
146 .label = "GPD", 130 .label = "GPD",
147 }, 131 },
148 }, { 132 }, {
149 .base = S5PC100_GPE0_BASE,
150 .config = &gpio_cfg,
151 .chip = { 133 .chip = {
152 .base = S5PC100_GPE0(0), 134 .base = S5PC100_GPE0(0),
153 .ngpio = S5PC100_GPIO_E0_NR, 135 .ngpio = S5PC100_GPIO_E0_NR,
154 .label = "GPE0", 136 .label = "GPE0",
155 }, 137 },
156 }, { 138 }, {
157 .base = S5PC100_GPE1_BASE,
158 .config = &gpio_cfg,
159 .chip = { 139 .chip = {
160 .base = S5PC100_GPE1(0), 140 .base = S5PC100_GPE1(0),
161 .ngpio = S5PC100_GPIO_E1_NR, 141 .ngpio = S5PC100_GPIO_E1_NR,
162 .label = "GPE1", 142 .label = "GPE1",
163 }, 143 },
164 }, { 144 }, {
165 .base = S5PC100_GPF0_BASE,
166 .config = &gpio_cfg,
167 .chip = { 145 .chip = {
168 .base = S5PC100_GPF0(0), 146 .base = S5PC100_GPF0(0),
169 .ngpio = S5PC100_GPIO_F0_NR, 147 .ngpio = S5PC100_GPIO_F0_NR,
170 .label = "GPF0", 148 .label = "GPF0",
171 }, 149 },
172 }, { 150 }, {
173 .base = S5PC100_GPF1_BASE,
174 .config = &gpio_cfg,
175 .chip = { 151 .chip = {
176 .base = S5PC100_GPF1(0), 152 .base = S5PC100_GPF1(0),
177 .ngpio = S5PC100_GPIO_F1_NR, 153 .ngpio = S5PC100_GPIO_F1_NR,
178 .label = "GPF1", 154 .label = "GPF1",
179 }, 155 },
180 }, { 156 }, {
181 .base = S5PC100_GPF2_BASE,
182 .config = &gpio_cfg,
183 .chip = { 157 .chip = {
184 .base = S5PC100_GPF2(0), 158 .base = S5PC100_GPF2(0),
185 .ngpio = S5PC100_GPIO_F2_NR, 159 .ngpio = S5PC100_GPIO_F2_NR,
186 .label = "GPF2", 160 .label = "GPF2",
187 }, 161 },
188 }, { 162 }, {
189 .base = S5PC100_GPF3_BASE,
190 .config = &gpio_cfg,
191 .chip = { 163 .chip = {
192 .base = S5PC100_GPF3(0), 164 .base = S5PC100_GPF3(0),
193 .ngpio = S5PC100_GPIO_F3_NR, 165 .ngpio = S5PC100_GPIO_F3_NR,
194 .label = "GPF3", 166 .label = "GPF3",
195 }, 167 },
196 }, { 168 }, {
197 .base = S5PC100_GPG0_BASE,
198 .config = &gpio_cfg,
199 .chip = { 169 .chip = {
200 .base = S5PC100_GPG0(0), 170 .base = S5PC100_GPG0(0),
201 .ngpio = S5PC100_GPIO_G0_NR, 171 .ngpio = S5PC100_GPIO_G0_NR,
202 .label = "GPG0", 172 .label = "GPG0",
203 }, 173 },
204 }, { 174 }, {
205 .base = S5PC100_GPG1_BASE,
206 .config = &gpio_cfg,
207 .chip = { 175 .chip = {
208 .base = S5PC100_GPG1(0), 176 .base = S5PC100_GPG1(0),
209 .ngpio = S5PC100_GPIO_G1_NR, 177 .ngpio = S5PC100_GPIO_G1_NR,
210 .label = "GPG1", 178 .label = "GPG1",
211 }, 179 },
212 }, { 180 }, {
213 .base = S5PC100_GPG2_BASE,
214 .config = &gpio_cfg,
215 .chip = { 181 .chip = {
216 .base = S5PC100_GPG2(0), 182 .base = S5PC100_GPG2(0),
217 .ngpio = S5PC100_GPIO_G2_NR, 183 .ngpio = S5PC100_GPIO_G2_NR,
218 .label = "GPG2", 184 .label = "GPG2",
219 }, 185 },
220 }, { 186 }, {
221 .base = S5PC100_GPG3_BASE,
222 .config = &gpio_cfg,
223 .chip = { 187 .chip = {
224 .base = S5PC100_GPG3(0), 188 .base = S5PC100_GPG3(0),
225 .ngpio = S5PC100_GPIO_G3_NR, 189 .ngpio = S5PC100_GPIO_G3_NR,
226 .label = "GPG3", 190 .label = "GPG3",
227 }, 191 },
228 }, { 192 }, {
229 .base = S5PC100_GPH0_BASE,
230 .config = &gpio_cfg_eint,
231 .chip = {
232 .base = S5PC100_GPH0(0),
233 .ngpio = S5PC100_GPIO_H0_NR,
234 .label = "GPH0",
235 },
236 }, {
237 .base = S5PC100_GPH1_BASE,
238 .config = &gpio_cfg_eint,
239 .chip = {
240 .base = S5PC100_GPH1(0),
241 .ngpio = S5PC100_GPIO_H1_NR,
242 .label = "GPH1",
243 },
244 }, {
245 .base = S5PC100_GPH2_BASE,
246 .config = &gpio_cfg_eint,
247 .chip = {
248 .base = S5PC100_GPH2(0),
249 .ngpio = S5PC100_GPIO_H2_NR,
250 .label = "GPH2",
251 },
252 }, {
253 .base = S5PC100_GPH3_BASE,
254 .config = &gpio_cfg_eint,
255 .chip = {
256 .base = S5PC100_GPH3(0),
257 .ngpio = S5PC100_GPIO_H3_NR,
258 .label = "GPH3",
259 },
260 }, {
261 .base = S5PC100_GPI_BASE,
262 .config = &gpio_cfg,
263 .chip = { 193 .chip = {
264 .base = S5PC100_GPI(0), 194 .base = S5PC100_GPI(0),
265 .ngpio = S5PC100_GPIO_I_NR, 195 .ngpio = S5PC100_GPIO_I_NR,
266 .label = "GPI", 196 .label = "GPI",
267 }, 197 },
268 }, { 198 }, {
269 .base = S5PC100_GPJ0_BASE,
270 .config = &gpio_cfg,
271 .chip = { 199 .chip = {
272 .base = S5PC100_GPJ0(0), 200 .base = S5PC100_GPJ0(0),
273 .ngpio = S5PC100_GPIO_J0_NR, 201 .ngpio = S5PC100_GPIO_J0_NR,
274 .label = "GPJ0", 202 .label = "GPJ0",
275 }, 203 },
276 }, { 204 }, {
277 .base = S5PC100_GPJ1_BASE,
278 .config = &gpio_cfg,
279 .chip = { 205 .chip = {
280 .base = S5PC100_GPJ1(0), 206 .base = S5PC100_GPJ1(0),
281 .ngpio = S5PC100_GPIO_J1_NR, 207 .ngpio = S5PC100_GPIO_J1_NR,
282 .label = "GPJ1", 208 .label = "GPJ1",
283 }, 209 },
284 }, { 210 }, {
285 .base = S5PC100_GPJ2_BASE,
286 .config = &gpio_cfg,
287 .chip = { 211 .chip = {
288 .base = S5PC100_GPJ2(0), 212 .base = S5PC100_GPJ2(0),
289 .ngpio = S5PC100_GPIO_J2_NR, 213 .ngpio = S5PC100_GPIO_J2_NR,
290 .label = "GPJ2", 214 .label = "GPJ2",
291 }, 215 },
292 }, { 216 }, {
293 .base = S5PC100_GPJ3_BASE,
294 .config = &gpio_cfg,
295 .chip = { 217 .chip = {
296 .base = S5PC100_GPJ3(0), 218 .base = S5PC100_GPJ3(0),
297 .ngpio = S5PC100_GPIO_J3_NR, 219 .ngpio = S5PC100_GPIO_J3_NR,
298 .label = "GPJ3", 220 .label = "GPJ3",
299 }, 221 },
300 }, { 222 }, {
301 .base = S5PC100_GPJ4_BASE,
302 .config = &gpio_cfg,
303 .chip = { 223 .chip = {
304 .base = S5PC100_GPJ4(0), 224 .base = S5PC100_GPJ4(0),
305 .ngpio = S5PC100_GPIO_J4_NR, 225 .ngpio = S5PC100_GPIO_J4_NR,
306 .label = "GPJ4", 226 .label = "GPJ4",
307 }, 227 },
308 }, { 228 }, {
309 .base = S5PC100_GPK0_BASE,
310 .config = &gpio_cfg_noint, 229 .config = &gpio_cfg_noint,
311 .chip = { 230 .chip = {
312 .base = S5PC100_GPK0(0), 231 .base = S5PC100_GPK0(0),
@@ -314,7 +233,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
314 .label = "GPK0", 233 .label = "GPK0",
315 }, 234 },
316 }, { 235 }, {
317 .base = S5PC100_GPK1_BASE,
318 .config = &gpio_cfg_noint, 236 .config = &gpio_cfg_noint,
319 .chip = { 237 .chip = {
320 .base = S5PC100_GPK1(0), 238 .base = S5PC100_GPK1(0),
@@ -322,7 +240,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
322 .label = "GPK1", 240 .label = "GPK1",
323 }, 241 },
324 }, { 242 }, {
325 .base = S5PC100_GPK2_BASE,
326 .config = &gpio_cfg_noint, 243 .config = &gpio_cfg_noint,
327 .chip = { 244 .chip = {
328 .base = S5PC100_GPK2(0), 245 .base = S5PC100_GPK2(0),
@@ -330,7 +247,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
330 .label = "GPK2", 247 .label = "GPK2",
331 }, 248 },
332 }, { 249 }, {
333 .base = S5PC100_GPK3_BASE,
334 .config = &gpio_cfg_noint, 250 .config = &gpio_cfg_noint,
335 .chip = { 251 .chip = {
336 .base = S5PC100_GPK3(0), 252 .base = S5PC100_GPK3(0),
@@ -338,7 +254,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
338 .label = "GPK3", 254 .label = "GPK3",
339 }, 255 },
340 }, { 256 }, {
341 .base = S5PC100_GPL0_BASE,
342 .config = &gpio_cfg_noint, 257 .config = &gpio_cfg_noint,
343 .chip = { 258 .chip = {
344 .base = S5PC100_GPL0(0), 259 .base = S5PC100_GPL0(0),
@@ -346,7 +261,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
346 .label = "GPL0", 261 .label = "GPL0",
347 }, 262 },
348 }, { 263 }, {
349 .base = S5PC100_GPL1_BASE,
350 .config = &gpio_cfg_noint, 264 .config = &gpio_cfg_noint,
351 .chip = { 265 .chip = {
352 .base = S5PC100_GPL1(0), 266 .base = S5PC100_GPL1(0),
@@ -354,7 +268,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
354 .label = "GPL1", 268 .label = "GPL1",
355 }, 269 },
356 }, { 270 }, {
357 .base = S5PC100_GPL2_BASE,
358 .config = &gpio_cfg_noint, 271 .config = &gpio_cfg_noint,
359 .chip = { 272 .chip = {
360 .base = S5PC100_GPL2(0), 273 .base = S5PC100_GPL2(0),
@@ -362,7 +275,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
362 .label = "GPL2", 275 .label = "GPL2",
363 }, 276 },
364 }, { 277 }, {
365 .base = S5PC100_GPL3_BASE,
366 .config = &gpio_cfg_noint, 278 .config = &gpio_cfg_noint,
367 .chip = { 279 .chip = {
368 .base = S5PC100_GPL3(0), 280 .base = S5PC100_GPL3(0),
@@ -370,56 +282,72 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
370 .label = "GPL3", 282 .label = "GPL3",
371 }, 283 },
372 }, { 284 }, {
373 .base = S5PC100_GPL4_BASE,
374 .config = &gpio_cfg_noint, 285 .config = &gpio_cfg_noint,
375 .chip = { 286 .chip = {
376 .base = S5PC100_GPL4(0), 287 .base = S5PC100_GPL4(0),
377 .ngpio = S5PC100_GPIO_L4_NR, 288 .ngpio = S5PC100_GPIO_L4_NR,
378 .label = "GPL4", 289 .label = "GPL4",
379 }, 290 },
291 }, {
292 .base = (S5P_VA_GPIO + 0xC00),
293 .config = &gpio_cfg_eint,
294 .irq_base = IRQ_EINT(0),
295 .chip = {
296 .base = S5PC100_GPH0(0),
297 .ngpio = S5PC100_GPIO_H0_NR,
298 .label = "GPH0",
299 .to_irq = samsung_gpiolib_to_irq,
300 },
301 }, {
302 .base = (S5P_VA_GPIO + 0xC20),
303 .config = &gpio_cfg_eint,
304 .irq_base = IRQ_EINT(8),
305 .chip = {
306 .base = S5PC100_GPH1(0),
307 .ngpio = S5PC100_GPIO_H1_NR,
308 .label = "GPH1",
309 .to_irq = samsung_gpiolib_to_irq,
310 },
311 }, {
312 .base = (S5P_VA_GPIO + 0xC40),
313 .config = &gpio_cfg_eint,
314 .irq_base = IRQ_EINT(16),
315 .chip = {
316 .base = S5PC100_GPH2(0),
317 .ngpio = S5PC100_GPIO_H2_NR,
318 .label = "GPH2",
319 .to_irq = samsung_gpiolib_to_irq,
320 },
321 }, {
322 .base = (S5P_VA_GPIO + 0xC60),
323 .config = &gpio_cfg_eint,
324 .irq_base = IRQ_EINT(24),
325 .chip = {
326 .base = S5PC100_GPH3(0),
327 .ngpio = S5PC100_GPIO_H3_NR,
328 .label = "GPH3",
329 .to_irq = samsung_gpiolib_to_irq,
330 },
380 }, 331 },
381}; 332};
382 333
383/* FIXME move from irq-gpio.c */ 334static __init int s5pc100_gpiolib_init(void)
384extern struct irq_chip s5pc100_gpioint;
385extern void s5pc100_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc);
386
387static __init void s5pc100_gpiolib_link(struct s3c_gpio_chip *chip)
388{ 335{
389 /* Interrupt */ 336 struct s3c_gpio_chip *chip = s5pc100_gpio_chips;
390 if (chip->config == &gpio_cfg) { 337 int nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
391 int i, irq; 338 int gpioint_group = 0;
392 339 int i;
393 chip->chip.to_irq = s5pc100_gpiolib_to_irq;
394 340
395 for (i = 0; i < chip->chip.ngpio; i++) { 341 for (i = 0; i < nr_chips; i++, chip++) {
396 irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i; 342 if (chip->config == NULL) {
397 set_irq_chip(irq, &s5pc100_gpioint); 343 chip->config = &gpio_cfg;
398 set_irq_data(irq, &chip->chip); 344 chip->group = gpioint_group++;
399 set_irq_handler(irq, handle_level_irq);
400 set_irq_flags(irq, IRQF_VALID);
401 } 345 }
402 } else if (chip->config == &gpio_cfg_eint) { 346 if (chip->base == NULL)
403 chip->chip.to_irq = s5pc100_gpiolib_to_eint; 347 chip->base = S5PC100_BANK_BASE(i);
404 } 348 }
405}
406
407static __init int s5pc100_gpiolib_init(void)
408{
409 struct s3c_gpio_chip *chip;
410 int nr_chips;
411
412 chip = s5pc100_gpio_chips;
413 nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
414
415 for (; nr_chips > 0; nr_chips--, chip++)
416 s5pc100_gpiolib_link(chip);
417
418 samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips,
419 ARRAY_SIZE(s5pc100_gpio_chips));
420 349
421 /* Interrupt */ 350 samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips);
422 set_irq_chained_handler(IRQ_GPIOINT, s5pc100_irq_gpioint_handler);
423 351
424 return 0; 352 return 0;
425} 353}
diff --git a/arch/arm/mach-s5pc100/include/mach/gpio.h b/arch/arm/mach-s5pc100/include/mach/gpio.h
index 71ae1f52df1d..29a8a12d9b4f 100644
--- a/arch/arm/mach-s5pc100/include/mach/gpio.h
+++ b/arch/arm/mach-s5pc100/include/mach/gpio.h
@@ -146,13 +146,6 @@ enum s5p_gpio_number {
146/* define the number of gpios we need to the one after the MP04() range */ 146/* define the number of gpios we need to the one after the MP04() range */
147#define ARCH_NR_GPIOS (S5PC100_GPIO_END + 1) 147#define ARCH_NR_GPIOS (S5PC100_GPIO_END + 1)
148 148
149#define EINT_MODE S3C_GPIO_SFN(0x2)
150
151#define EINT_GPIO_0(x) S5PC100_GPH0(x)
152#define EINT_GPIO_1(x) S5PC100_GPH1(x)
153#define EINT_GPIO_2(x) S5PC100_GPH2(x)
154#define EINT_GPIO_3(x) S5PC100_GPH3(x)
155
156#include <asm-generic/gpio.h> 149#include <asm-generic/gpio.h>
157 150
158#endif /* __ASM_ARCH_GPIO_H */ 151#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
index 06513e647242..d2eb4757381f 100644
--- a/arch/arm/mach-s5pc100/include/mach/irqs.h
+++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
@@ -48,8 +48,8 @@
48#define IRQ_SPI1 S5P_IRQ_VIC1(16) 48#define IRQ_SPI1 S5P_IRQ_VIC1(16)
49#define IRQ_SPI2 S5P_IRQ_VIC1(17) 49#define IRQ_SPI2 S5P_IRQ_VIC1(17)
50#define IRQ_IRDA S5P_IRQ_VIC1(18) 50#define IRQ_IRDA S5P_IRQ_VIC1(18)
51#define IRQ_CAN0 S5P_IRQ_VIC1(19) 51#define IRQ_IIC2 S5P_IRQ_VIC1(19)
52#define IRQ_CAN1 S5P_IRQ_VIC1(20) 52#define IRQ_IIC3 S5P_IRQ_VIC1(20)
53#define IRQ_HSIRX S5P_IRQ_VIC1(21) 53#define IRQ_HSIRX S5P_IRQ_VIC1(21)
54#define IRQ_HSITX S5P_IRQ_VIC1(22) 54#define IRQ_HSITX S5P_IRQ_VIC1(22)
55#define IRQ_UHOST S5P_IRQ_VIC1(23) 55#define IRQ_UHOST S5P_IRQ_VIC1(23)
@@ -100,11 +100,12 @@
100#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) 100#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
101#define S5P_EINT_BASE2 (IRQ_VIC_END + 1) 101#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
102 102
103#define S3C_IRQ_GPIO_BASE (IRQ_EINT(31) + 1) 103/* GPIO interrupt */
104#define S3C_IRQ_GPIO(x) (S3C_IRQ_GPIO_BASE + (x)) 104#define S5P_GPIOINT_BASE (IRQ_EINT(31) + 1)
105#define S5P_GPIOINT_GROUP_MAXNR 21
105 106
106/* Until MP04 Groups -> 40 (exactly 39) Groups * 8 ~= 320 GPIOs */ 107/* Set the default NR_IRQS */
107#define NR_IRQS (S3C_IRQ_GPIO(320) + 1) 108#define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
108 109
109/* Compatibility */ 110/* Compatibility */
110#define IRQ_LCD_FIFO IRQ_LCD0 111#define IRQ_LCD_FIFO IRQ_LCD0
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
index 8751ef4a6804..32e9cab5c864 100644
--- a/arch/arm/mach-s5pc100/include/mach/map.h
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -110,6 +110,8 @@
110#define S5PC100_PA_PCM0 0xF2400000 110#define S5PC100_PA_PCM0 0xF2400000
111#define S5PC100_PA_PCM1 0xF2500000 111#define S5PC100_PA_PCM1 0xF2500000
112 112
113#define S5PC100_PA_SPDIF 0xF2600000
114
113#define S5PC100_PA_TSADC (0xF3000000) 115#define S5PC100_PA_TSADC (0xF3000000)
114 116
115/* KEYPAD */ 117/* KEYPAD */
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-gpio.h b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h
index dd6295e1251d..0bf73209ec7b 100644
--- a/arch/arm/mach-s5pc100/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h
@@ -11,43 +11,6 @@
11 11
12#include <mach/map.h> 12#include <mach/map.h>
13 13
14/* S5PC100 */
15#define S5PC100_GPIO_BASE S5P_VA_GPIO
16#define S5PC100_GPA0_BASE (S5PC100_GPIO_BASE + 0x0000)
17#define S5PC100_GPA1_BASE (S5PC100_GPIO_BASE + 0x0020)
18#define S5PC100_GPB_BASE (S5PC100_GPIO_BASE + 0x0040)
19#define S5PC100_GPC_BASE (S5PC100_GPIO_BASE + 0x0060)
20#define S5PC100_GPD_BASE (S5PC100_GPIO_BASE + 0x0080)
21#define S5PC100_GPE0_BASE (S5PC100_GPIO_BASE + 0x00A0)
22#define S5PC100_GPE1_BASE (S5PC100_GPIO_BASE + 0x00C0)
23#define S5PC100_GPF0_BASE (S5PC100_GPIO_BASE + 0x00E0)
24#define S5PC100_GPF1_BASE (S5PC100_GPIO_BASE + 0x0100)
25#define S5PC100_GPF2_BASE (S5PC100_GPIO_BASE + 0x0120)
26#define S5PC100_GPF3_BASE (S5PC100_GPIO_BASE + 0x0140)
27#define S5PC100_GPG0_BASE (S5PC100_GPIO_BASE + 0x0160)
28#define S5PC100_GPG1_BASE (S5PC100_GPIO_BASE + 0x0180)
29#define S5PC100_GPG2_BASE (S5PC100_GPIO_BASE + 0x01A0)
30#define S5PC100_GPG3_BASE (S5PC100_GPIO_BASE + 0x01C0)
31#define S5PC100_GPH0_BASE (S5PC100_GPIO_BASE + 0x0C00)
32#define S5PC100_GPH1_BASE (S5PC100_GPIO_BASE + 0x0C20)
33#define S5PC100_GPH2_BASE (S5PC100_GPIO_BASE + 0x0C40)
34#define S5PC100_GPH3_BASE (S5PC100_GPIO_BASE + 0x0C60)
35#define S5PC100_GPI_BASE (S5PC100_GPIO_BASE + 0x01E0)
36#define S5PC100_GPJ0_BASE (S5PC100_GPIO_BASE + 0x0200)
37#define S5PC100_GPJ1_BASE (S5PC100_GPIO_BASE + 0x0220)
38#define S5PC100_GPJ2_BASE (S5PC100_GPIO_BASE + 0x0240)
39#define S5PC100_GPJ3_BASE (S5PC100_GPIO_BASE + 0x0260)
40#define S5PC100_GPJ4_BASE (S5PC100_GPIO_BASE + 0x0280)
41#define S5PC100_GPK0_BASE (S5PC100_GPIO_BASE + 0x02A0)
42#define S5PC100_GPK1_BASE (S5PC100_GPIO_BASE + 0x02C0)
43#define S5PC100_GPK2_BASE (S5PC100_GPIO_BASE + 0x02E0)
44#define S5PC100_GPK3_BASE (S5PC100_GPIO_BASE + 0x0300)
45#define S5PC100_GPL0_BASE (S5PC100_GPIO_BASE + 0x0320)
46#define S5PC100_GPL1_BASE (S5PC100_GPIO_BASE + 0x0340)
47#define S5PC100_GPL2_BASE (S5PC100_GPIO_BASE + 0x0360)
48#define S5PC100_GPL3_BASE (S5PC100_GPIO_BASE + 0x0380)
49#define S5PC100_GPL4_BASE (S5PC100_GPIO_BASE + 0x03A0)
50
51#define S5PC100EINT30CON (S5P_VA_GPIO + 0xE00) 14#define S5PC100EINT30CON (S5P_VA_GPIO + 0xE00)
52#define S5P_EINT_CON(x) (S5PC100EINT30CON + ((x) * 0x4)) 15#define S5P_EINT_CON(x) (S5PC100EINT30CON + ((x) * 0x4))
53 16
@@ -64,12 +27,12 @@
64 27
65#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) 28#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
66 29
67/* values for S5P_EXTINT0 */ 30#define EINT_MODE S3C_GPIO_SFN(0x2)
68#define S5P_EXTINT_LOWLEV (0x00) 31
69#define S5P_EXTINT_HILEV (0x01) 32#define EINT_GPIO_0(x) S5PC100_GPH0(x)
70#define S5P_EXTINT_FALLEDGE (0x02) 33#define EINT_GPIO_1(x) S5PC100_GPH1(x)
71#define S5P_EXTINT_RISEEDGE (0x03) 34#define EINT_GPIO_2(x) S5PC100_GPH2(x)
72#define S5P_EXTINT_BOTHEDGE (0x04) 35#define EINT_GPIO_3(x) S5PC100_GPH3(x)
73 36
74#endif /* __ASM_MACH_S5PC100_REGS_GPIO_H */ 37#endif /* __ASM_MACH_S5PC100_REGS_GPIO_H */
75 38
diff --git a/arch/arm/mach-s5pc100/include/mach/vmalloc.h b/arch/arm/mach-s5pc100/include/mach/vmalloc.h
index be9df79903ed..44c8e5726d9d 100644
--- a/arch/arm/mach-s5pc100/include/mach/vmalloc.h
+++ b/arch/arm/mach-s5pc100/include/mach/vmalloc.h
@@ -12,6 +12,6 @@
12#ifndef __ASM_ARCH_VMALLOC_H 12#ifndef __ASM_ARCH_VMALLOC_H
13#define __ASM_ARCH_VMALLOC_H 13#define __ASM_ARCH_VMALLOC_H
14 14
15#define VMALLOC_END (0xe0000000UL) 15#define VMALLOC_END 0xF6000000UL
16 16
17#endif /* __ASM_ARCH_VMALLOC_H */ 17#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pc100/irq-gpio.c b/arch/arm/mach-s5pc100/irq-gpio.c
deleted file mode 100644
index 2bf86c18bc73..000000000000
--- a/arch/arm/mach-s5pc100/irq-gpio.c
+++ /dev/null
@@ -1,266 +0,0 @@
1/*
2 * arch/arm/mach-s5pc100/irq-gpio.c
3 *
4 * Copyright (C) 2009 Samsung Electronics
5 *
6 * S5PC100 - Interrupt handling for IRQ_GPIO${group}(x)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/io.h>
17#include <linux/gpio.h>
18
19#include <mach/map.h>
20#include <plat/gpio-cfg.h>
21
22#define S5P_GPIOREG(x) (S5P_VA_GPIO + (x))
23
24#define CON_OFFSET 0x700
25#define MASK_OFFSET 0x900
26#define PEND_OFFSET 0xA00
27#define CON_OFFSET_2 0xE00
28#define MASK_OFFSET_2 0xF00
29#define PEND_OFFSET_2 0xF40
30
31#define GPIOINT_LEVEL_LOW 0x0
32#define GPIOINT_LEVEL_HIGH 0x1
33#define GPIOINT_EDGE_FALLING 0x2
34#define GPIOINT_EDGE_RISING 0x3
35#define GPIOINT_EDGE_BOTH 0x4
36
37static int group_to_con_offset(int group)
38{
39 return group << 2;
40}
41
42static int group_to_mask_offset(int group)
43{
44 return group << 2;
45}
46
47static int group_to_pend_offset(int group)
48{
49 return group << 2;
50}
51
52static int s5pc100_get_start(unsigned int group)
53{
54 switch (group) {
55 case 0: return S5PC100_GPIO_A0_START;
56 case 1: return S5PC100_GPIO_A1_START;
57 case 2: return S5PC100_GPIO_B_START;
58 case 3: return S5PC100_GPIO_C_START;
59 case 4: return S5PC100_GPIO_D_START;
60 case 5: return S5PC100_GPIO_E0_START;
61 case 6: return S5PC100_GPIO_E1_START;
62 case 7: return S5PC100_GPIO_F0_START;
63 case 8: return S5PC100_GPIO_F1_START;
64 case 9: return S5PC100_GPIO_F2_START;
65 case 10: return S5PC100_GPIO_F3_START;
66 case 11: return S5PC100_GPIO_G0_START;
67 case 12: return S5PC100_GPIO_G1_START;
68 case 13: return S5PC100_GPIO_G2_START;
69 case 14: return S5PC100_GPIO_G3_START;
70 case 15: return S5PC100_GPIO_I_START;
71 case 16: return S5PC100_GPIO_J0_START;
72 case 17: return S5PC100_GPIO_J1_START;
73 case 18: return S5PC100_GPIO_J2_START;
74 case 19: return S5PC100_GPIO_J3_START;
75 case 20: return S5PC100_GPIO_J4_START;
76 default:
77 BUG();
78 }
79
80 return -EINVAL;
81}
82
83static int s5pc100_get_group(unsigned int irq)
84{
85 irq -= S3C_IRQ_GPIO(0);
86
87 switch (irq) {
88 case S5PC100_GPIO_A0_START ... S5PC100_GPIO_A1_START - 1:
89 return 0;
90 case S5PC100_GPIO_A1_START ... S5PC100_GPIO_B_START - 1:
91 return 1;
92 case S5PC100_GPIO_B_START ... S5PC100_GPIO_C_START - 1:
93 return 2;
94 case S5PC100_GPIO_C_START ... S5PC100_GPIO_D_START - 1:
95 return 3;
96 case S5PC100_GPIO_D_START ... S5PC100_GPIO_E0_START - 1:
97 return 4;
98 case S5PC100_GPIO_E0_START ... S5PC100_GPIO_E1_START - 1:
99 return 5;
100 case S5PC100_GPIO_E1_START ... S5PC100_GPIO_F0_START - 1:
101 return 6;
102 case S5PC100_GPIO_F0_START ... S5PC100_GPIO_F1_START - 1:
103 return 7;
104 case S5PC100_GPIO_F1_START ... S5PC100_GPIO_F2_START - 1:
105 return 8;
106 case S5PC100_GPIO_F2_START ... S5PC100_GPIO_F3_START - 1:
107 return 9;
108 case S5PC100_GPIO_F3_START ... S5PC100_GPIO_G0_START - 1:
109 return 10;
110 case S5PC100_GPIO_G0_START ... S5PC100_GPIO_G1_START - 1:
111 return 11;
112 case S5PC100_GPIO_G1_START ... S5PC100_GPIO_G2_START - 1:
113 return 12;
114 case S5PC100_GPIO_G2_START ... S5PC100_GPIO_G3_START - 1:
115 return 13;
116 case S5PC100_GPIO_G3_START ... S5PC100_GPIO_H0_START - 1:
117 return 14;
118 case S5PC100_GPIO_I_START ... S5PC100_GPIO_J0_START - 1:
119 return 15;
120 case S5PC100_GPIO_J0_START ... S5PC100_GPIO_J1_START - 1:
121 return 16;
122 case S5PC100_GPIO_J1_START ... S5PC100_GPIO_J2_START - 1:
123 return 17;
124 case S5PC100_GPIO_J2_START ... S5PC100_GPIO_J3_START - 1:
125 return 18;
126 case S5PC100_GPIO_J3_START ... S5PC100_GPIO_J4_START - 1:
127 return 19;
128 case S5PC100_GPIO_J4_START ... S5PC100_GPIO_K0_START - 1:
129 return 20;
130 default:
131 BUG();
132 }
133
134 return -EINVAL;
135}
136
137static int s5pc100_get_offset(unsigned int irq)
138{
139 struct gpio_chip *chip = get_irq_data(irq);
140 return irq - S3C_IRQ_GPIO(chip->base);
141}
142
143static void s5pc100_gpioint_ack(unsigned int irq)
144{
145 int group, offset, pend_offset;
146 unsigned int value;
147
148 group = s5pc100_get_group(irq);
149 offset = s5pc100_get_offset(irq);
150 pend_offset = group_to_pend_offset(group);
151
152 value = __raw_readl(S5P_GPIOREG(PEND_OFFSET) + pend_offset);
153 value |= 1 << offset;
154 __raw_writel(value, S5P_GPIOREG(PEND_OFFSET) + pend_offset);
155}
156
157static void s5pc100_gpioint_mask(unsigned int irq)
158{
159 int group, offset, mask_offset;
160 unsigned int value;
161
162 group = s5pc100_get_group(irq);
163 offset = s5pc100_get_offset(irq);
164 mask_offset = group_to_mask_offset(group);
165
166 value = __raw_readl(S5P_GPIOREG(MASK_OFFSET) + mask_offset);
167 value |= 1 << offset;
168 __raw_writel(value, S5P_GPIOREG(MASK_OFFSET) + mask_offset);
169}
170
171static void s5pc100_gpioint_unmask(unsigned int irq)
172{
173 int group, offset, mask_offset;
174 unsigned int value;
175
176 group = s5pc100_get_group(irq);
177 offset = s5pc100_get_offset(irq);
178 mask_offset = group_to_mask_offset(group);
179
180 value = __raw_readl(S5P_GPIOREG(MASK_OFFSET) + mask_offset);
181 value &= ~(1 << offset);
182 __raw_writel(value, S5P_GPIOREG(MASK_OFFSET) + mask_offset);
183}
184
185static void s5pc100_gpioint_mask_ack(unsigned int irq)
186{
187 s5pc100_gpioint_mask(irq);
188 s5pc100_gpioint_ack(irq);
189}
190
191static int s5pc100_gpioint_set_type(unsigned int irq, unsigned int type)
192{
193 int group, offset, con_offset;
194 unsigned int value;
195
196 group = s5pc100_get_group(irq);
197 offset = s5pc100_get_offset(irq);
198 con_offset = group_to_con_offset(group);
199
200 switch (type) {
201 case IRQ_TYPE_NONE:
202 printk(KERN_WARNING "No irq type\n");
203 return -EINVAL;
204 case IRQ_TYPE_EDGE_RISING:
205 type = GPIOINT_EDGE_RISING;
206 break;
207 case IRQ_TYPE_EDGE_FALLING:
208 type = GPIOINT_EDGE_FALLING;
209 break;
210 case IRQ_TYPE_EDGE_BOTH:
211 type = GPIOINT_EDGE_BOTH;
212 break;
213 case IRQ_TYPE_LEVEL_HIGH:
214 type = GPIOINT_LEVEL_HIGH;
215 break;
216 case IRQ_TYPE_LEVEL_LOW:
217 type = GPIOINT_LEVEL_LOW;
218 break;
219 default:
220 BUG();
221 }
222
223
224 value = __raw_readl(S5P_GPIOREG(CON_OFFSET) + con_offset);
225 value &= ~(0xf << (offset * 0x4));
226 value |= (type << (offset * 0x4));
227 __raw_writel(value, S5P_GPIOREG(CON_OFFSET) + con_offset);
228
229 return 0;
230}
231
232struct irq_chip s5pc100_gpioint = {
233 .name = "GPIO",
234 .ack = s5pc100_gpioint_ack,
235 .mask = s5pc100_gpioint_mask,
236 .mask_ack = s5pc100_gpioint_mask_ack,
237 .unmask = s5pc100_gpioint_unmask,
238 .set_type = s5pc100_gpioint_set_type,
239};
240
241void s5pc100_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc)
242{
243 int group, offset, pend_offset, mask_offset;
244 int real_irq, group_end;
245 unsigned int pend, mask;
246
247 group_end = 21;
248
249 for (group = 0; group < group_end; group++) {
250 pend_offset = group_to_pend_offset(group);
251 pend = __raw_readl(S5P_GPIOREG(PEND_OFFSET) + pend_offset);
252 if (!pend)
253 continue;
254
255 mask_offset = group_to_mask_offset(group);
256 mask = __raw_readl(S5P_GPIOREG(MASK_OFFSET) + mask_offset);
257 pend &= ~mask;
258
259 for (offset = 0; offset < 8; offset++) {
260 if (pend & (1 << offset)) {
261 real_irq = s5pc100_get_start(group) + offset;
262 generic_handle_irq(S3C_IRQ_GPIO(real_irq));
263 }
264 }
265 }
266}
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 880fb075092c..18b405d514d6 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -47,6 +47,7 @@
47#include <plat/adc.h> 47#include <plat/adc.h>
48#include <plat/keypad.h> 48#include <plat/keypad.h>
49#include <plat/ts.h> 49#include <plat/ts.h>
50#include <plat/audio.h>
50 51
51/* Following are default values for UCON, ULCON and UFCON UART registers */ 52/* Following are default values for UCON, ULCON and UFCON UART registers */
52#define SMDKC100_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 53#define SMDKC100_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -196,6 +197,7 @@ static struct platform_device *smdkc100_devices[] __initdata = {
196 &s5p_device_fimc0, 197 &s5p_device_fimc0,
197 &s5p_device_fimc1, 198 &s5p_device_fimc1,
198 &s5p_device_fimc2, 199 &s5p_device_fimc2,
200 &s5pc100_device_spdif,
199}; 201};
200 202
201static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = { 203static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
@@ -226,6 +228,8 @@ static void __init smdkc100_machine_init(void)
226 228
227 samsung_keypad_set_platdata(&smdkc100_keypad_data); 229 samsung_keypad_set_platdata(&smdkc100_keypad_data);
228 230
231 s5pc100_spdif_setup_gpio(S5PC100_SPDIF_GPD);
232
229 /* LCD init */ 233 /* LCD init */
230 gpio_request(S5PC100_GPD(0), "GPD"); 234 gpio_request(S5PC100_GPD(0), "GPD");
231 gpio_request(S5PC100_GPH0(6), "GPH0"); 235 gpio_request(S5PC100_GPH0(6), "GPH0");
diff --git a/arch/arm/mach-s5pc100/setup-fb-24bpp.c b/arch/arm/mach-s5pc100/setup-fb-24bpp.c
index 6eba6cb8e2f4..d31c0f3fe222 100644
--- a/arch/arm/mach-s5pc100/setup-fb-24bpp.c
+++ b/arch/arm/mach-s5pc100/setup-fb-24bpp.c
@@ -22,27 +22,15 @@
22 22
23#define DISR_OFFSET 0x7008 23#define DISR_OFFSET 0x7008
24 24
25void s5pc100_fb_gpio_setup_24bpp(void) 25static void s5pc100_fb_setgpios(unsigned int base, unsigned int nr)
26{ 26{
27 unsigned int gpio = 0; 27 s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2));
28 28}
29 for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) {
30 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
31 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
32 }
33
34 for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) {
35 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
36 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
37 }
38
39 for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) {
40 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
41 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
42 }
43 29
44 for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) { 30void s5pc100_fb_gpio_setup_24bpp(void)
45 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 31{
46 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 32 s5pc100_fb_setgpios(S5PC100_GPF0(0), 8);
47 } 33 s5pc100_fb_setgpios(S5PC100_GPF1(0), 8);
34 s5pc100_fb_setgpios(S5PC100_GPF2(0), 8);
35 s5pc100_fb_setgpios(S5PC100_GPF3(0), 4);
48} 36}
diff --git a/arch/arm/mach-s5pc100/setup-i2c0.c b/arch/arm/mach-s5pc100/setup-i2c0.c
index dd3174e6ecc5..eaef7a3bda49 100644
--- a/arch/arm/mach-s5pc100/setup-i2c0.c
+++ b/arch/arm/mach-s5pc100/setup-i2c0.c
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
23 23
24void s3c_i2c0_cfg_gpio(struct platform_device *dev) 24void s3c_i2c0_cfg_gpio(struct platform_device *dev)
25{ 25{
26 s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2)); 26 s3c_gpio_cfgall_range(S5PC100_GPD(3), 2,
27 s3c_gpio_setpull(S5PC100_GPD(3), S3C_GPIO_PULL_UP); 27 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
28 s3c_gpio_cfgpin(S5PC100_GPD(4), S3C_GPIO_SFN(2));
29 s3c_gpio_setpull(S5PC100_GPD(4), S3C_GPIO_PULL_UP);
30} 28}
diff --git a/arch/arm/mach-s5pc100/setup-i2c1.c b/arch/arm/mach-s5pc100/setup-i2c1.c
index d1fec26b69ee..aaff74a90dee 100644
--- a/arch/arm/mach-s5pc100/setup-i2c1.c
+++ b/arch/arm/mach-s5pc100/setup-i2c1.c
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
23 23
24void s3c_i2c1_cfg_gpio(struct platform_device *dev) 24void s3c_i2c1_cfg_gpio(struct platform_device *dev)
25{ 25{
26 s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2)); 26 s3c_gpio_cfgall_range(S5PC100_GPD(5), 2,
27 s3c_gpio_setpull(S5PC100_GPD(5), S3C_GPIO_PULL_UP); 27 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
28 s3c_gpio_cfgpin(S5PC100_GPD(6), S3C_GPIO_SFN(2));
29 s3c_gpio_setpull(S5PC100_GPD(6), S3C_GPIO_PULL_UP);
30} 28}
diff --git a/arch/arm/mach-s5pc100/setup-ide.c b/arch/arm/mach-s5pc100/setup-ide.c
index 83575671fb59..223aae044466 100644
--- a/arch/arm/mach-s5pc100/setup-ide.c
+++ b/arch/arm/mach-s5pc100/setup-ide.c
@@ -17,52 +17,39 @@
17#include <mach/regs-clock.h> 17#include <mach/regs-clock.h>
18#include <plat/gpio-cfg.h> 18#include <plat/gpio-cfg.h>
19 19
20static void s5pc100_ide_cfg_gpios(unsigned int base, unsigned int nr)
21{
22 s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(4));
23
24 for (; nr > 0; nr--, base++)
25 s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
26}
27
20void s5pc100_ide_setup_gpio(void) 28void s5pc100_ide_setup_gpio(void)
21{ 29{
22 u32 reg; 30 u32 reg;
23 u32 gpio = 0;
24 31
25 /* Independent CF interface, CF chip select configuration */ 32 /* Independent CF interface, CF chip select configuration */
26 reg = readl(S5PC100_MEM_SYS_CFG) & (~0x3f); 33 reg = readl(S5PC100_MEM_SYS_CFG) & (~0x3f);
27 writel(reg | MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S5PC100_MEM_SYS_CFG); 34 writel(reg | MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S5PC100_MEM_SYS_CFG);
28 35
29 /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */ 36 /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */
30 for (gpio = S5PC100_GPJ0(0); gpio <= S5PC100_GPJ0(7); gpio++) { 37 s5pc100_ide_cfg_gpios(S5PC100_GPJ0(0), 8);
31 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
32 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
33 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
34 }
35 38
36 /*CF_Data[0 - 7] */ 39 /*CF_Data[0 - 7] */
37 for (gpio = S5PC100_GPJ2(0); gpio <= S5PC100_GPJ2(7); gpio++) { 40 s5pc100_ide_cfg_gpios(S5PC100_GPJ2(0), 8);
38 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
39 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
40 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
41 }
42 41
43 /* CF_Data[8 - 15] */ 42 /* CF_Data[8 - 15] */
44 for (gpio = S5PC100_GPJ3(0); gpio <= S5PC100_GPJ3(7); gpio++) { 43 s5pc100_ide_cfg_gpios(S5PC100_GPJ3(0), 8);
45 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
46 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
47 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
48 }
49 44
50 /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */ 45 /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
51 for (gpio = S5PC100_GPJ4(0); gpio <= S5PC100_GPJ4(3); gpio++) { 46 s5pc100_ide_cfg_gpios(S5PC100_GPJ4(0), 4);
52 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
53 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
54 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
55 }
56 47
57 /* EBI_OE, EBI_WE */ 48 /* EBI_OE, EBI_WE */
58 for (gpio = S5PC100_GPK0(6); gpio <= S5PC100_GPK0(7); gpio++) 49 s3c_gpio_cfgpin_range(S5PC100_GPK0(6), 2, S3C_GPIO_SFN(0));
59 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0));
60 50
61 /* CF_OE, CF_WE */ 51 /* CF_OE, CF_WE */
62 for (gpio = S5PC100_GPK1(6); gpio <= S5PC100_GPK1(7); gpio++) { 52 s3c_gpio_cfgrange_nopull(S5PC100_GPK1(6), 8, S3C_GPIO_SFN(2));
63 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
64 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
65 }
66 53
67 /* CF_CD */ 54 /* CF_CD */
68 s3c_gpio_cfgpin(S5PC100_GPK3(5), S3C_GPIO_SFN(2)); 55 s3c_gpio_cfgpin(S5PC100_GPK3(5), S3C_GPIO_SFN(2));
diff --git a/arch/arm/mach-s5pc100/setup-keypad.c b/arch/arm/mach-s5pc100/setup-keypad.c
index d0837a72a58e..ada377f0c206 100644
--- a/arch/arm/mach-s5pc100/setup-keypad.c
+++ b/arch/arm/mach-s5pc100/setup-keypad.c
@@ -15,20 +15,9 @@
15 15
16void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) 16void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
17{ 17{
18 unsigned int gpio;
19 unsigned int end;
20
21 /* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */ 18 /* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */
22 end = S5PC100_GPH3(rows); 19 s3c_gpio_cfgrange_nopull(S5PC100_GPH3(0), rows, S3C_GPIO_SFN(3));
23 for (gpio = S5PC100_GPH3(0); gpio < end; gpio++) {
24 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
25 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
26 }
27 20
28 /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */ 21 /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
29 end = S5PC100_GPH2(cols); 22 s3c_gpio_cfgrange_nopull(S5PC100_GPH2(0), cols, S3C_GPIO_SFN(3));
30 for (gpio = S5PC100_GPH2(0); gpio < end; gpio++) {
31 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
32 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
33 }
34} 23}
diff --git a/arch/arm/mach-s5pc100/setup-sdhci-gpio.c b/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
index dc7208c639ea..03c02d04c68c 100644
--- a/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
@@ -25,8 +25,6 @@
25void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) 25void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
26{ 26{
27 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 27 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
28 unsigned int gpio;
29 unsigned int end;
30 unsigned int num; 28 unsigned int num;
31 29
32 num = width; 30 num = width;
@@ -34,20 +32,11 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
34 if (width == 8) 32 if (width == 8)
35 num = width - 2; 33 num = width - 2;
36 34
37 end = S5PC100_GPG0(2 + num);
38
39 /* Set all the necessary GPG0/GPG1 pins to special-function 0 */ 35 /* Set all the necessary GPG0/GPG1 pins to special-function 0 */
40 for (gpio = S5PC100_GPG0(0); gpio < end; gpio++) { 36 s3c_gpio_cfgrange_nopull(S5PC100_GPG0(0), 2 + num, S3C_GPIO_SFN(2));
41 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
42 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
43 }
44 37
45 if (width == 8) { 38 if (width == 8)
46 for (gpio = S5PC100_GPG1(0); gpio <= S5PC100_GPG1(1); gpio++) { 39 s3c_gpio_cfgrange_nopull(S5PC100_GPG1(0), 2, S3C_GPIO_SFN(2));
47 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
48 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
49 }
50 }
51 40
52 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 41 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
53 s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP); 42 s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP);
@@ -58,16 +47,9 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
58void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) 47void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
59{ 48{
60 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 49 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
61 unsigned int gpio;
62 unsigned int end;
63
64 end = S5PC100_GPG2(2 + width);
65 50
66 /* Set all the necessary GPG2 pins to special-function 2 */ 51 /* Set all the necessary GPG2 pins to special-function 2 */
67 for (gpio = S5PC100_GPG2(0); gpio < end; gpio++) { 52 s3c_gpio_cfgrange_nopull(S5PC100_GPG2(0), 2 + width, S3C_GPIO_SFN(2));
68 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
69 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
70 }
71 53
72 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 54 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
73 s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP); 55 s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP);
@@ -78,16 +60,9 @@ void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
78void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) 60void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
79{ 61{
80 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 62 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
81 unsigned int gpio;
82 unsigned int end;
83
84 end = S5PC100_GPG3(2 + width);
85 63
86 /* Set all the necessary GPG3 pins to special-function 2 */ 64 /* Set all the necessary GPG3 pins to special-function 2 */
87 for (gpio = S5PC100_GPG3(0); gpio < end; gpio++) { 65 s3c_gpio_cfgrange_nopull(S5PC100_GPG3(0), 2 + width, S3C_GPIO_SFN(2));
88 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
89 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
90 }
91 66
92 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 67 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
93 s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP); 68 s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 5315fec3db86..862f239a0fdb 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -11,9 +11,9 @@ if ARCH_S5PV210
11 11
12config CPU_S5PV210 12config CPU_S5PV210
13 bool 13 bool
14 select PLAT_S5P
15 select S3C_PL330_DMA 14 select S3C_PL330_DMA
16 select S5P_EXT_INT 15 select S5P_EXT_INT
16 select S5PV210_PM if PM
17 help 17 help
18 Enable S5PV210 CPU support 18 Enable S5PV210 CPU support
19 19
@@ -58,7 +58,6 @@ menu "S5PC110 Machines"
58config MACH_AQUILA 58config MACH_AQUILA
59 bool "Aquila" 59 bool "Aquila"
60 select CPU_S5PV210 60 select CPU_S5PV210
61 select ARCH_SPARSEMEM_ENABLE
62 select S3C_DEV_FB 61 select S3C_DEV_FB
63 select S5P_DEV_FIMC0 62 select S5P_DEV_FIMC0
64 select S5P_DEV_FIMC1 63 select S5P_DEV_FIMC1
@@ -75,7 +74,7 @@ config MACH_AQUILA
75config MACH_GONI 74config MACH_GONI
76 bool "GONI" 75 bool "GONI"
77 select CPU_S5PV210 76 select CPU_S5PV210
78 select ARCH_SPARSEMEM_ENABLE 77 select S5P_GPIO_INT
79 select S3C_DEV_FB 78 select S3C_DEV_FB
80 select S5P_DEV_FIMC0 79 select S5P_DEV_FIMC0
81 select S5P_DEV_FIMC1 80 select S5P_DEV_FIMC1
@@ -83,8 +82,15 @@ config MACH_GONI
83 select S3C_DEV_HSMMC 82 select S3C_DEV_HSMMC
84 select S3C_DEV_HSMMC1 83 select S3C_DEV_HSMMC1
85 select S3C_DEV_HSMMC2 84 select S3C_DEV_HSMMC2
85 select S3C_DEV_I2C1
86 select S3C_DEV_I2C2
87 select S3C_DEV_USB_HSOTG
86 select S5P_DEV_ONENAND 88 select S5P_DEV_ONENAND
89 select SAMSUNG_DEV_KEYPAD
87 select S5PV210_SETUP_FB_24BPP 90 select S5PV210_SETUP_FB_24BPP
91 select S5PV210_SETUP_I2C1
92 select S5PV210_SETUP_I2C2
93 select S5PV210_SETUP_KEYPAD
88 select S5PV210_SETUP_SDHCI 94 select S5PV210_SETUP_SDHCI
89 help 95 help
90 Machine support for Samsung GONI board 96 Machine support for Samsung GONI board
@@ -93,7 +99,6 @@ config MACH_GONI
93config MACH_SMDKC110 99config MACH_SMDKC110
94 bool "SMDKC110" 100 bool "SMDKC110"
95 select CPU_S5PV210 101 select CPU_S5PV210
96 select ARCH_SPARSEMEM_ENABLE
97 select S3C_DEV_I2C1 102 select S3C_DEV_I2C1
98 select S3C_DEV_I2C2 103 select S3C_DEV_I2C2
99 select S3C_DEV_RTC 104 select S3C_DEV_RTC
@@ -113,7 +118,6 @@ menu "S5PV210 Machines"
113config MACH_SMDKV210 118config MACH_SMDKV210
114 bool "SMDKV210" 119 bool "SMDKV210"
115 select CPU_S5PV210 120 select CPU_S5PV210
116 select ARCH_SPARSEMEM_ENABLE
117 select S3C_DEV_HSMMC 121 select S3C_DEV_HSMMC
118 select S3C_DEV_HSMMC1 122 select S3C_DEV_HSMMC1
119 select S3C_DEV_HSMMC2 123 select S3C_DEV_HSMMC2
@@ -134,6 +138,29 @@ config MACH_SMDKV210
134 help 138 help
135 Machine support for Samsung SMDKV210 139 Machine support for Samsung SMDKV210
136 140
141config MACH_TORBRECK
142 bool "Torbreck"
143 select CPU_S5PV210
144 select ARCH_SPARSEMEM_ENABLE
145 select S3C_DEV_HSMMC
146 select S3C_DEV_HSMMC1
147 select S3C_DEV_HSMMC2
148 select S3C_DEV_HSMMC3
149 select S3C_DEV_I2C1
150 select S3C_DEV_I2C2
151 select S3C_DEV_RTC
152 select S3C_DEV_WDT
153 select S5PV210_SETUP_I2C1
154 select S5PV210_SETUP_I2C2
155 select S5PV210_SETUP_SDHCI
156 help
157 Machine support for aESOP Torbreck
158
137endmenu 159endmenu
138 160
161config S5PV210_PM
162 bool
163 help
164 Power Management code common to S5PV210
165
139endif 166endif
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 704548912408..ff1a0db57a2f 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -14,6 +14,8 @@ obj- :=
14 14
15obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o 15obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o
16obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o 16obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o
17obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o
18obj-$(CONFIG_CPU_FREQ) += cpufreq.o
17 19
18# machine support 20# machine support
19 21
@@ -21,6 +23,7 @@ obj-$(CONFIG_MACH_AQUILA) += mach-aquila.o
21obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o 23obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o
22obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o 24obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o
23obj-$(CONFIG_MACH_GONI) += mach-goni.o 25obj-$(CONFIG_MACH_GONI) += mach-goni.o
26obj-$(CONFIG_MACH_TORBRECK) += mach-torbreck.o
24 27
25# device support 28# device support
26 29
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index d562670e1b0b..019c3a69b0e4 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -31,6 +31,8 @@
31#include <plat/clock-clksrc.h> 31#include <plat/clock-clksrc.h>
32#include <plat/s5pv210.h> 32#include <plat/s5pv210.h>
33 33
34static unsigned long xtal;
35
34static struct clksrc_clk clk_mout_apll = { 36static struct clksrc_clk clk_mout_apll = {
35 .clk = { 37 .clk = {
36 .name = "mout_apll", 38 .name = "mout_apll",
@@ -259,6 +261,36 @@ static struct clksrc_clk clk_sclk_vpll = {
259 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 }, 261 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
260}; 262};
261 263
264static struct clk *clkset_moutdmc0src_list[] = {
265 [0] = &clk_sclk_a2m.clk,
266 [1] = &clk_mout_mpll.clk,
267 [2] = NULL,
268 [3] = NULL,
269};
270
271static struct clksrc_sources clkset_moutdmc0src = {
272 .sources = clkset_moutdmc0src_list,
273 .nr_sources = ARRAY_SIZE(clkset_moutdmc0src_list),
274};
275
276static struct clksrc_clk clk_mout_dmc0 = {
277 .clk = {
278 .name = "mout_dmc0",
279 .id = -1,
280 },
281 .sources = &clkset_moutdmc0src,
282 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
283};
284
285static struct clksrc_clk clk_sclk_dmc0 = {
286 .clk = {
287 .name = "sclk_dmc0",
288 .id = -1,
289 .parent = &clk_mout_dmc0.clk,
290 },
291 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
292};
293
262static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk) 294static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
263{ 295{
264 return clk_get_rate(clk->parent) / 2; 296 return clk_get_rate(clk->parent) / 2;
@@ -268,8 +300,29 @@ static struct clk_ops clk_hclk_imem_ops = {
268 .get_rate = s5pv210_clk_imem_get_rate, 300 .get_rate = s5pv210_clk_imem_get_rate,
269}; 301};
270 302
303static unsigned long s5pv210_clk_fout_apll_get_rate(struct clk *clk)
304{
305 return s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
306}
307
308static struct clk_ops clk_fout_apll_ops = {
309 .get_rate = s5pv210_clk_fout_apll_get_rate,
310};
311
271static struct clk init_clocks_disable[] = { 312static struct clk init_clocks_disable[] = {
272 { 313 {
314 .name = "pdma",
315 .id = 0,
316 .parent = &clk_hclk_psys.clk,
317 .enable = s5pv210_clk_ip0_ctrl,
318 .ctrlbit = (1 << 3),
319 }, {
320 .name = "pdma",
321 .id = 1,
322 .parent = &clk_hclk_psys.clk,
323 .enable = s5pv210_clk_ip0_ctrl,
324 .ctrlbit = (1 << 4),
325 }, {
273 .name = "rot", 326 .name = "rot",
274 .id = -1, 327 .id = -1,
275 .parent = &clk_hclk_dsys.clk, 328 .parent = &clk_hclk_dsys.clk,
@@ -431,6 +484,12 @@ static struct clk init_clocks_disable[] = {
431 .parent = &clk_p, 484 .parent = &clk_p,
432 .enable = s5pv210_clk_ip3_ctrl, 485 .enable = s5pv210_clk_ip3_ctrl,
433 .ctrlbit = (1 << 6), 486 .ctrlbit = (1 << 6),
487 }, {
488 .name = "spdif",
489 .id = -1,
490 .parent = &clk_p,
491 .enable = s5pv210_clk_ip3_ctrl,
492 .ctrlbit = (1 << 0),
434 }, 493 },
435}; 494};
436 495
@@ -660,6 +719,53 @@ static struct clksrc_sources clkset_sclk_spdif = {
660 .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list), 719 .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list),
661}; 720};
662 721
722static int s5pv210_spdif_set_rate(struct clk *clk, unsigned long rate)
723{
724 struct clk *pclk;
725 int ret;
726
727 pclk = clk_get_parent(clk);
728 if (IS_ERR(pclk))
729 return -EINVAL;
730
731 ret = pclk->ops->set_rate(pclk, rate);
732 clk_put(pclk);
733
734 return ret;
735}
736
737static unsigned long s5pv210_spdif_get_rate(struct clk *clk)
738{
739 struct clk *pclk;
740 int rate;
741
742 pclk = clk_get_parent(clk);
743 if (IS_ERR(pclk))
744 return -EINVAL;
745
746 rate = pclk->ops->get_rate(clk);
747 clk_put(pclk);
748
749 return rate;
750}
751
752static struct clk_ops s5pv210_sclk_spdif_ops = {
753 .set_rate = s5pv210_spdif_set_rate,
754 .get_rate = s5pv210_spdif_get_rate,
755};
756
757static struct clksrc_clk clk_sclk_spdif = {
758 .clk = {
759 .name = "sclk_spdif",
760 .id = -1,
761 .enable = s5pv210_clk_mask0_ctrl,
762 .ctrlbit = (1 << 27),
763 .ops = &s5pv210_sclk_spdif_ops,
764 },
765 .sources = &clkset_sclk_spdif,
766 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
767};
768
663static struct clk *clkset_group2_list[] = { 769static struct clk *clkset_group2_list[] = {
664 [0] = &clk_ext_xtal_mux, 770 [0] = &clk_ext_xtal_mux,
665 [1] = &clk_xusbxti, 771 [1] = &clk_xusbxti,
@@ -744,15 +850,6 @@ static struct clksrc_clk clksrcs[] = {
744 .sources = &clkset_sclk_mixer, 850 .sources = &clkset_sclk_mixer,
745 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 }, 851 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
746 }, { 852 }, {
747 .clk = {
748 .name = "sclk_spdif",
749 .id = -1,
750 .enable = s5pv210_clk_mask0_ctrl,
751 .ctrlbit = (1 << 27),
752 },
753 .sources = &clkset_sclk_spdif,
754 .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
755 }, {
756 .clk = { 853 .clk = {
757 .name = "sclk_fimc", 854 .name = "sclk_fimc",
758 .id = 0, 855 .id = 0,
@@ -953,12 +1050,93 @@ static struct clksrc_clk *sysclks[] = {
953 &clk_sclk_dac, 1050 &clk_sclk_dac,
954 &clk_sclk_pixel, 1051 &clk_sclk_pixel,
955 &clk_sclk_hdmi, 1052 &clk_sclk_hdmi,
1053 &clk_mout_dmc0,
1054 &clk_sclk_dmc0,
1055 &clk_sclk_audio0,
1056 &clk_sclk_audio1,
1057 &clk_sclk_audio2,
1058 &clk_sclk_spdif,
1059};
1060
1061static u32 epll_div[][6] = {
1062 { 48000000, 0, 48, 3, 3, 0 },
1063 { 96000000, 0, 48, 3, 2, 0 },
1064 { 144000000, 1, 72, 3, 2, 0 },
1065 { 192000000, 0, 48, 3, 1, 0 },
1066 { 288000000, 1, 72, 3, 1, 0 },
1067 { 32750000, 1, 65, 3, 4, 35127 },
1068 { 32768000, 1, 65, 3, 4, 35127 },
1069 { 45158400, 0, 45, 3, 3, 10355 },
1070 { 45000000, 0, 45, 3, 3, 10355 },
1071 { 45158000, 0, 45, 3, 3, 10355 },
1072 { 49125000, 0, 49, 3, 3, 9961 },
1073 { 49152000, 0, 49, 3, 3, 9961 },
1074 { 67737600, 1, 67, 3, 3, 48366 },
1075 { 67738000, 1, 67, 3, 3, 48366 },
1076 { 73800000, 1, 73, 3, 3, 47710 },
1077 { 73728000, 1, 73, 3, 3, 47710 },
1078 { 36000000, 1, 32, 3, 4, 0 },
1079 { 60000000, 1, 60, 3, 3, 0 },
1080 { 72000000, 1, 72, 3, 3, 0 },
1081 { 80000000, 1, 80, 3, 3, 0 },
1082 { 84000000, 0, 42, 3, 2, 0 },
1083 { 50000000, 0, 50, 3, 3, 0 },
1084};
1085
1086static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
1087{
1088 unsigned int epll_con, epll_con_k;
1089 unsigned int i;
1090
1091 /* Return if nothing changed */
1092 if (clk->rate == rate)
1093 return 0;
1094
1095 epll_con = __raw_readl(S5P_EPLL_CON);
1096 epll_con_k = __raw_readl(S5P_EPLL_CON1);
1097
1098 epll_con_k &= ~PLL46XX_KDIV_MASK;
1099 epll_con &= ~(1 << 27 |
1100 PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
1101 PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
1102 PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1103
1104 for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
1105 if (epll_div[i][0] == rate) {
1106 epll_con_k |= epll_div[i][5] << 0;
1107 epll_con |= (epll_div[i][1] << 27 |
1108 epll_div[i][2] << PLL46XX_MDIV_SHIFT |
1109 epll_div[i][3] << PLL46XX_PDIV_SHIFT |
1110 epll_div[i][4] << PLL46XX_SDIV_SHIFT);
1111 break;
1112 }
1113 }
1114
1115 if (i == ARRAY_SIZE(epll_div)) {
1116 printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
1117 __func__);
1118 return -EINVAL;
1119 }
1120
1121 __raw_writel(epll_con, S5P_EPLL_CON);
1122 __raw_writel(epll_con_k, S5P_EPLL_CON1);
1123
1124 printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
1125 clk->rate, rate);
1126
1127 clk->rate = rate;
1128
1129 return 0;
1130}
1131
1132static struct clk_ops s5pv210_epll_ops = {
1133 .set_rate = s5pv210_epll_set_rate,
1134 .get_rate = s5p_epll_get_rate,
956}; 1135};
957 1136
958void __init_or_cpufreq s5pv210_setup_clocks(void) 1137void __init_or_cpufreq s5pv210_setup_clocks(void)
959{ 1138{
960 struct clk *xtal_clk; 1139 struct clk *xtal_clk;
961 unsigned long xtal;
962 unsigned long vpllsrc; 1140 unsigned long vpllsrc;
963 unsigned long armclk; 1141 unsigned long armclk;
964 unsigned long hclk_msys; 1142 unsigned long hclk_msys;
@@ -974,6 +1152,10 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
974 unsigned int ptr; 1152 unsigned int ptr;
975 u32 clkdiv0, clkdiv1; 1153 u32 clkdiv0, clkdiv1;
976 1154
1155 /* Set functions for clk_fout_epll */
1156 clk_fout_epll.enable = s5p_epll_enable;
1157 clk_fout_epll.ops = &s5pv210_epll_ops;
1158
977 printk(KERN_DEBUG "%s: registering clocks\n", __func__); 1159 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
978 1160
979 clkdiv0 = __raw_readl(S5P_CLK_DIV0); 1161 clkdiv0 = __raw_readl(S5P_CLK_DIV0);
@@ -992,11 +1174,12 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
992 1174
993 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508); 1175 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
994 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); 1176 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
995 epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500); 1177 epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON),
1178 __raw_readl(S5P_EPLL_CON1), pll_4600);
996 vpllsrc = clk_get_rate(&clk_vpllsrc.clk); 1179 vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
997 vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502); 1180 vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
998 1181
999 clk_fout_apll.rate = apll; 1182 clk_fout_apll.ops = &clk_fout_apll_ops;
1000 clk_fout_mpll.rate = mpll; 1183 clk_fout_mpll.rate = mpll;
1001 clk_fout_epll.rate = epll; 1184 clk_fout_epll.rate = epll;
1002 clk_fout_vpll.rate = vpll; 1185 clk_fout_vpll.rate = vpll;
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 2f16bfc0a116..8eb480e201b0 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -85,6 +85,21 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
85 .pfn = __phys_to_pfn(S5PV210_PA_SROMC), 85 .pfn = __phys_to_pfn(S5PV210_PA_SROMC),
86 .length = SZ_4K, 86 .length = SZ_4K,
87 .type = MT_DEVICE, 87 .type = MT_DEVICE,
88 }, {
89 .virtual = (unsigned long)S5P_VA_DMC0,
90 .pfn = __phys_to_pfn(S5PV210_PA_DMC0),
91 .length = SZ_4K,
92 .type = MT_DEVICE,
93 }, {
94 .virtual = (unsigned long)S5P_VA_DMC1,
95 .pfn = __phys_to_pfn(S5PV210_PA_DMC1),
96 .length = SZ_4K,
97 .type = MT_DEVICE,
98 }, {
99 .virtual = (unsigned long)S3C_VA_USB_HSPHY,
100 .pfn =__phys_to_pfn(S5PV210_PA_HSPHY),
101 .length = SZ_4K,
102 .type = MT_DEVICE,
88 } 103 }
89}; 104};
90 105
diff --git a/arch/arm/mach-s5pv210/cpufreq.c b/arch/arm/mach-s5pv210/cpufreq.c
new file mode 100644
index 000000000000..a6f22920a2c2
--- /dev/null
+++ b/arch/arm/mach-s5pv210/cpufreq.c
@@ -0,0 +1,484 @@
1/* linux/arch/arm/mach-s5pv210/cpufreq.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * CPU frequency scaling for S5PC110/S5PV210
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/types.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/err.h>
17#include <linux/clk.h>
18#include <linux/io.h>
19#include <linux/cpufreq.h>
20
21#include <mach/map.h>
22#include <mach/regs-clock.h>
23
24static struct clk *cpu_clk;
25static struct clk *dmc0_clk;
26static struct clk *dmc1_clk;
27static struct cpufreq_freqs freqs;
28
29/* APLL M,P,S values for 1G/800Mhz */
30#define APLL_VAL_1000 ((1 << 31) | (125 << 16) | (3 << 8) | 1)
31#define APLL_VAL_800 ((1 << 31) | (100 << 16) | (3 << 8) | 1)
32
33/*
34 * DRAM configurations to calculate refresh counter for changing
35 * frequency of memory.
36 */
37struct dram_conf {
38 unsigned long freq; /* HZ */
39 unsigned long refresh; /* DRAM refresh counter * 1000 */
40};
41
42/* DRAM configuration (DMC0 and DMC1) */
43static struct dram_conf s5pv210_dram_conf[2];
44
45enum perf_level {
46 L0, L1, L2, L3, L4,
47};
48
49enum s5pv210_mem_type {
50 LPDDR = 0x1,
51 LPDDR2 = 0x2,
52 DDR2 = 0x4,
53};
54
55enum s5pv210_dmc_port {
56 DMC0 = 0,
57 DMC1,
58};
59
60static struct cpufreq_frequency_table s5pv210_freq_table[] = {
61 {L0, 1000*1000},
62 {L1, 800*1000},
63 {L2, 400*1000},
64 {L3, 200*1000},
65 {L4, 100*1000},
66 {0, CPUFREQ_TABLE_END},
67};
68
69static u32 clkdiv_val[5][11] = {
70 /*
71 * Clock divider value for following
72 * { APLL, A2M, HCLK_MSYS, PCLK_MSYS,
73 * HCLK_DSYS, PCLK_DSYS, HCLK_PSYS, PCLK_PSYS,
74 * ONEDRAM, MFC, G3D }
75 */
76
77 /* L0 : [1000/200/100][166/83][133/66][200/200] */
78 {0, 4, 4, 1, 3, 1, 4, 1, 3, 0, 0},
79
80 /* L1 : [800/200/100][166/83][133/66][200/200] */
81 {0, 3, 3, 1, 3, 1, 4, 1, 3, 0, 0},
82
83 /* L2 : [400/200/100][166/83][133/66][200/200] */
84 {1, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0},
85
86 /* L3 : [200/200/100][166/83][133/66][200/200] */
87 {3, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0},
88
89 /* L4 : [100/100/100][83/83][66/66][100/100] */
90 {7, 7, 0, 0, 7, 0, 9, 0, 7, 0, 0},
91};
92
93/*
94 * This function set DRAM refresh counter
95 * accoriding to operating frequency of DRAM
96 * ch: DMC port number 0 or 1
97 * freq: Operating frequency of DRAM(KHz)
98 */
99static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq)
100{
101 unsigned long tmp, tmp1;
102 void __iomem *reg = NULL;
103
104 if (ch == DMC0)
105 reg = (S5P_VA_DMC0 + 0x30);
106 else if (ch == DMC1)
107 reg = (S5P_VA_DMC1 + 0x30);
108 else
109 printk(KERN_ERR "Cannot find DMC port\n");
110
111 /* Find current DRAM frequency */
112 tmp = s5pv210_dram_conf[ch].freq;
113
114 do_div(tmp, freq);
115
116 tmp1 = s5pv210_dram_conf[ch].refresh;
117
118 do_div(tmp1, tmp);
119
120 __raw_writel(tmp1, reg);
121}
122
123int s5pv210_verify_speed(struct cpufreq_policy *policy)
124{
125 if (policy->cpu)
126 return -EINVAL;
127
128 return cpufreq_frequency_table_verify(policy, s5pv210_freq_table);
129}
130
131unsigned int s5pv210_getspeed(unsigned int cpu)
132{
133 if (cpu)
134 return 0;
135
136 return clk_get_rate(cpu_clk) / 1000;
137}
138
139static int s5pv210_target(struct cpufreq_policy *policy,
140 unsigned int target_freq,
141 unsigned int relation)
142{
143 unsigned long reg;
144 unsigned int index, priv_index;
145 unsigned int pll_changing = 0;
146 unsigned int bus_speed_changing = 0;
147
148 freqs.old = s5pv210_getspeed(0);
149
150 if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
151 target_freq, relation, &index))
152 return -EINVAL;
153
154 freqs.new = s5pv210_freq_table[index].frequency;
155 freqs.cpu = 0;
156
157 if (freqs.new == freqs.old)
158 return 0;
159
160 /* Finding current running level index */
161 if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
162 freqs.old, relation, &priv_index))
163 return -EINVAL;
164
165 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
166
167 if (freqs.new > freqs.old) {
168 /* Voltage up: will be implemented */
169 }
170
171 /* Check if there need to change PLL */
172 if ((index == L0) || (priv_index == L0))
173 pll_changing = 1;
174
175 /* Check if there need to change System bus clock */
176 if ((index == L4) || (priv_index == L4))
177 bus_speed_changing = 1;
178
179 if (bus_speed_changing) {
180 /*
181 * Reconfigure DRAM refresh counter value for minimum
182 * temporary clock while changing divider.
183 * expected clock is 83Mhz : 7.8usec/(1/83Mhz) = 0x287
184 */
185 if (pll_changing)
186 s5pv210_set_refresh(DMC1, 83000);
187 else
188 s5pv210_set_refresh(DMC1, 100000);
189
190 s5pv210_set_refresh(DMC0, 83000);
191 }
192
193 /*
194 * APLL should be changed in this level
195 * APLL -> MPLL(for stable transition) -> APLL
196 * Some clock source's clock API are not prepared.
197 * Do not use clock API in below code.
198 */
199 if (pll_changing) {
200 /*
201 * 1. Temporary Change divider for MFC and G3D
202 * SCLKA2M(200/1=200)->(200/4=50)Mhz
203 */
204 reg = __raw_readl(S5P_CLK_DIV2);
205 reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK);
206 reg |= (3 << S5P_CLKDIV2_G3D_SHIFT) |
207 (3 << S5P_CLKDIV2_MFC_SHIFT);
208 __raw_writel(reg, S5P_CLK_DIV2);
209
210 /* For MFC, G3D dividing */
211 do {
212 reg = __raw_readl(S5P_CLKDIV_STAT0);
213 } while (reg & ((1 << 16) | (1 << 17)));
214
215 /*
216 * 2. Change SCLKA2M(200Mhz)to SCLKMPLL in MFC_MUX, G3D MUX
217 * (200/4=50)->(667/4=166)Mhz
218 */
219 reg = __raw_readl(S5P_CLK_SRC2);
220 reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK);
221 reg |= (1 << S5P_CLKSRC2_G3D_SHIFT) |
222 (1 << S5P_CLKSRC2_MFC_SHIFT);
223 __raw_writel(reg, S5P_CLK_SRC2);
224
225 do {
226 reg = __raw_readl(S5P_CLKMUX_STAT1);
227 } while (reg & ((1 << 7) | (1 << 3)));
228
229 /*
230 * 3. DMC1 refresh count for 133Mhz if (index == L4) is
231 * true refresh counter is already programed in upper
232 * code. 0x287@83Mhz
233 */
234 if (!bus_speed_changing)
235 s5pv210_set_refresh(DMC1, 133000);
236
237 /* 4. SCLKAPLL -> SCLKMPLL */
238 reg = __raw_readl(S5P_CLK_SRC0);
239 reg &= ~(S5P_CLKSRC0_MUX200_MASK);
240 reg |= (0x1 << S5P_CLKSRC0_MUX200_SHIFT);
241 __raw_writel(reg, S5P_CLK_SRC0);
242
243 do {
244 reg = __raw_readl(S5P_CLKMUX_STAT0);
245 } while (reg & (0x1 << 18));
246
247 }
248
249 /* Change divider */
250 reg = __raw_readl(S5P_CLK_DIV0);
251
252 reg &= ~(S5P_CLKDIV0_APLL_MASK | S5P_CLKDIV0_A2M_MASK |
253 S5P_CLKDIV0_HCLK200_MASK | S5P_CLKDIV0_PCLK100_MASK |
254 S5P_CLKDIV0_HCLK166_MASK | S5P_CLKDIV0_PCLK83_MASK |
255 S5P_CLKDIV0_HCLK133_MASK | S5P_CLKDIV0_PCLK66_MASK);
256
257 reg |= ((clkdiv_val[index][0] << S5P_CLKDIV0_APLL_SHIFT) |
258 (clkdiv_val[index][1] << S5P_CLKDIV0_A2M_SHIFT) |
259 (clkdiv_val[index][2] << S5P_CLKDIV0_HCLK200_SHIFT) |
260 (clkdiv_val[index][3] << S5P_CLKDIV0_PCLK100_SHIFT) |
261 (clkdiv_val[index][4] << S5P_CLKDIV0_HCLK166_SHIFT) |
262 (clkdiv_val[index][5] << S5P_CLKDIV0_PCLK83_SHIFT) |
263 (clkdiv_val[index][6] << S5P_CLKDIV0_HCLK133_SHIFT) |
264 (clkdiv_val[index][7] << S5P_CLKDIV0_PCLK66_SHIFT));
265
266 __raw_writel(reg, S5P_CLK_DIV0);
267
268 do {
269 reg = __raw_readl(S5P_CLKDIV_STAT0);
270 } while (reg & 0xff);
271
272 /* ARM MCS value changed */
273 reg = __raw_readl(S5P_ARM_MCS_CON);
274 reg &= ~0x3;
275 if (index >= L3)
276 reg |= 0x3;
277 else
278 reg |= 0x1;
279
280 __raw_writel(reg, S5P_ARM_MCS_CON);
281
282 if (pll_changing) {
283 /* 5. Set Lock time = 30us*24Mhz = 0x2cf */
284 __raw_writel(0x2cf, S5P_APLL_LOCK);
285
286 /*
287 * 6. Turn on APLL
288 * 6-1. Set PMS values
289 * 6-2. Wait untile the PLL is locked
290 */
291 if (index == L0)
292 __raw_writel(APLL_VAL_1000, S5P_APLL_CON);
293 else
294 __raw_writel(APLL_VAL_800, S5P_APLL_CON);
295
296 do {
297 reg = __raw_readl(S5P_APLL_CON);
298 } while (!(reg & (0x1 << 29)));
299
300 /*
301 * 7. Change souce clock from SCLKMPLL(667Mhz)
302 * to SCLKA2M(200Mhz) in MFC_MUX and G3D MUX
303 * (667/4=166)->(200/4=50)Mhz
304 */
305 reg = __raw_readl(S5P_CLK_SRC2);
306 reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK);
307 reg |= (0 << S5P_CLKSRC2_G3D_SHIFT) |
308 (0 << S5P_CLKSRC2_MFC_SHIFT);
309 __raw_writel(reg, S5P_CLK_SRC2);
310
311 do {
312 reg = __raw_readl(S5P_CLKMUX_STAT1);
313 } while (reg & ((1 << 7) | (1 << 3)));
314
315 /*
316 * 8. Change divider for MFC and G3D
317 * (200/4=50)->(200/1=200)Mhz
318 */
319 reg = __raw_readl(S5P_CLK_DIV2);
320 reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK);
321 reg |= (clkdiv_val[index][10] << S5P_CLKDIV2_G3D_SHIFT) |
322 (clkdiv_val[index][9] << S5P_CLKDIV2_MFC_SHIFT);
323 __raw_writel(reg, S5P_CLK_DIV2);
324
325 /* For MFC, G3D dividing */
326 do {
327 reg = __raw_readl(S5P_CLKDIV_STAT0);
328 } while (reg & ((1 << 16) | (1 << 17)));
329
330 /* 9. Change MPLL to APLL in MSYS_MUX */
331 reg = __raw_readl(S5P_CLK_SRC0);
332 reg &= ~(S5P_CLKSRC0_MUX200_MASK);
333 reg |= (0x0 << S5P_CLKSRC0_MUX200_SHIFT);
334 __raw_writel(reg, S5P_CLK_SRC0);
335
336 do {
337 reg = __raw_readl(S5P_CLKMUX_STAT0);
338 } while (reg & (0x1 << 18));
339
340 /*
341 * 10. DMC1 refresh counter
342 * L4 : DMC1 = 100Mhz 7.8us/(1/100) = 0x30c
343 * Others : DMC1 = 200Mhz 7.8us/(1/200) = 0x618
344 */
345 if (!bus_speed_changing)
346 s5pv210_set_refresh(DMC1, 200000);
347 }
348
349 /*
350 * L4 level need to change memory bus speed, hence onedram clock divier
351 * and memory refresh parameter should be changed
352 */
353 if (bus_speed_changing) {
354 reg = __raw_readl(S5P_CLK_DIV6);
355 reg &= ~S5P_CLKDIV6_ONEDRAM_MASK;
356 reg |= (clkdiv_val[index][8] << S5P_CLKDIV6_ONEDRAM_SHIFT);
357 __raw_writel(reg, S5P_CLK_DIV6);
358
359 do {
360 reg = __raw_readl(S5P_CLKDIV_STAT1);
361 } while (reg & (1 << 15));
362
363 /* Reconfigure DRAM refresh counter value */
364 if (index != L4) {
365 /*
366 * DMC0 : 166Mhz
367 * DMC1 : 200Mhz
368 */
369 s5pv210_set_refresh(DMC0, 166000);
370 s5pv210_set_refresh(DMC1, 200000);
371 } else {
372 /*
373 * DMC0 : 83Mhz
374 * DMC1 : 100Mhz
375 */
376 s5pv210_set_refresh(DMC0, 83000);
377 s5pv210_set_refresh(DMC1, 100000);
378 }
379 }
380
381 if (freqs.new < freqs.old) {
382 /* Voltage down: will be implemented */
383 }
384
385 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
386
387 printk(KERN_DEBUG "Perf changed[L%d]\n", index);
388
389 return 0;
390}
391
392#ifdef CONFIG_PM
393static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy,
394 pm_message_t pmsg)
395{
396 return 0;
397}
398
399static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy)
400{
401 return 0;
402}
403#endif
404
405static int check_mem_type(void __iomem *dmc_reg)
406{
407 unsigned long val;
408
409 val = __raw_readl(dmc_reg + 0x4);
410 val = (val & (0xf << 8));
411
412 return val >> 8;
413}
414
415static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
416{
417 unsigned long mem_type;
418
419 cpu_clk = clk_get(NULL, "armclk");
420 if (IS_ERR(cpu_clk))
421 return PTR_ERR(cpu_clk);
422
423 dmc0_clk = clk_get(NULL, "sclk_dmc0");
424 if (IS_ERR(dmc0_clk)) {
425 clk_put(cpu_clk);
426 return PTR_ERR(dmc0_clk);
427 }
428
429 dmc1_clk = clk_get(NULL, "hclk_msys");
430 if (IS_ERR(dmc1_clk)) {
431 clk_put(dmc0_clk);
432 clk_put(cpu_clk);
433 return PTR_ERR(dmc1_clk);
434 }
435
436 if (policy->cpu != 0)
437 return -EINVAL;
438
439 /*
440 * check_mem_type : This driver only support LPDDR & LPDDR2.
441 * other memory type is not supported.
442 */
443 mem_type = check_mem_type(S5P_VA_DMC0);
444
445 if ((mem_type != LPDDR) && (mem_type != LPDDR2)) {
446 printk(KERN_ERR "CPUFreq doesn't support this memory type\n");
447 return -EINVAL;
448 }
449
450 /* Find current refresh counter and frequency each DMC */
451 s5pv210_dram_conf[0].refresh = (__raw_readl(S5P_VA_DMC0 + 0x30) * 1000);
452 s5pv210_dram_conf[0].freq = clk_get_rate(dmc0_clk);
453
454 s5pv210_dram_conf[1].refresh = (__raw_readl(S5P_VA_DMC1 + 0x30) * 1000);
455 s5pv210_dram_conf[1].freq = clk_get_rate(dmc1_clk);
456
457 policy->cur = policy->min = policy->max = s5pv210_getspeed(0);
458
459 cpufreq_frequency_table_get_attr(s5pv210_freq_table, policy->cpu);
460
461 policy->cpuinfo.transition_latency = 40000;
462
463 return cpufreq_frequency_table_cpuinfo(policy, s5pv210_freq_table);
464}
465
466static struct cpufreq_driver s5pv210_driver = {
467 .flags = CPUFREQ_STICKY,
468 .verify = s5pv210_verify_speed,
469 .target = s5pv210_target,
470 .get = s5pv210_getspeed,
471 .init = s5pv210_cpu_init,
472 .name = "s5pv210",
473#ifdef CONFIG_PM
474 .suspend = s5pv210_cpufreq_suspend,
475 .resume = s5pv210_cpufreq_resume,
476#endif
477};
478
479static int __init s5pv210_cpufreq_init(void)
480{
481 return cpufreq_register_driver(&s5pv210_driver);
482}
483
484late_initcall(s5pv210_cpufreq_init);
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c
index 21dc6cf955c3..1303fcb12b51 100644
--- a/arch/arm/mach-s5pv210/dev-audio.c
+++ b/arch/arm/mach-s5pv210/dev-audio.c
@@ -24,29 +24,15 @@ static int s5pv210_cfg_i2s(struct platform_device *pdev)
24 /* configure GPIO for i2s port */ 24 /* configure GPIO for i2s port */
25 switch (pdev->id) { 25 switch (pdev->id) {
26 case 1: 26 case 1:
27 s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(2)); 27 s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2));
28 s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(2));
29 s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(2));
30 s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(2));
31 s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(2));
32 break; 28 break;
33 29
34 case 2: 30 case 2:
35 s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(4)); 31 s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4));
36 s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(4));
37 s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(4));
38 s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(4));
39 s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(4));
40 break; 32 break;
41 33
42 case -1: 34 case -1:
43 s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(2)); 35 s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
44 s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(2));
45 s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(2));
46 s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(2));
47 s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(2));
48 s3c_gpio_cfgpin(S5PV210_GPI(5), S3C_GPIO_SFN(2));
49 s3c_gpio_cfgpin(S5PV210_GPI(6), S3C_GPIO_SFN(2));
50 break; 36 break;
51 37
52 default: 38 default:
@@ -151,25 +137,13 @@ static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev)
151{ 137{
152 switch (pdev->id) { 138 switch (pdev->id) {
153 case 0: 139 case 0:
154 s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(3)); 140 s3c_gpio_cfgpin_range(S5PV210_GPI(0), 5, S3C_GPIO_SFN(3));
155 s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(3));
156 s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(3));
157 s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(3));
158 s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(3));
159 break; 141 break;
160 case 1: 142 case 1:
161 s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(3)); 143 s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(3));
162 s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(3));
163 s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(3));
164 s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(3));
165 s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(3));
166 break; 144 break;
167 case 2: 145 case 2:
168 s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(2)); 146 s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(2));
169 s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(2));
170 s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(2));
171 s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(2));
172 s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(2));
173 break; 147 break;
174 default: 148 default:
175 printk(KERN_DEBUG "Invalid PCM Controller number!"); 149 printk(KERN_DEBUG "Invalid PCM Controller number!");
@@ -271,13 +245,7 @@ struct platform_device s5pv210_device_pcm2 = {
271 245
272static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev) 246static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev)
273{ 247{
274 s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(4)); 248 return s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(4));
275 s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(4));
276 s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(4));
277 s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(4));
278 s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(4));
279
280 return 0;
281} 249}
282 250
283static struct resource s5pv210_ac97_resource[] = { 251static struct resource s5pv210_ac97_resource[] = {
@@ -325,3 +293,43 @@ struct platform_device s5pv210_device_ac97 = {
325 .coherent_dma_mask = DMA_BIT_MASK(32), 293 .coherent_dma_mask = DMA_BIT_MASK(32),
326 }, 294 },
327}; 295};
296
297/* S/PDIF Controller platform_device */
298
299static int s5pv210_spdif_cfg_gpio(struct platform_device *pdev)
300{
301 s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 2, S3C_GPIO_SFN(3));
302
303 return 0;
304}
305
306static struct resource s5pv210_spdif_resource[] = {
307 [0] = {
308 .start = S5PV210_PA_SPDIF,
309 .end = S5PV210_PA_SPDIF + 0x100 - 1,
310 .flags = IORESOURCE_MEM,
311 },
312 [1] = {
313 .start = DMACH_SPDIF,
314 .end = DMACH_SPDIF,
315 .flags = IORESOURCE_DMA,
316 },
317};
318
319static struct s3c_audio_pdata samsung_spdif_pdata = {
320 .cfg_gpio = s5pv210_spdif_cfg_gpio,
321};
322
323static u64 s5pv210_spdif_dmamask = DMA_BIT_MASK(32);
324
325struct platform_device s5pv210_device_spdif = {
326 .name = "samsung-spdif",
327 .id = -1,
328 .num_resources = ARRAY_SIZE(s5pv210_spdif_resource),
329 .resource = s5pv210_spdif_resource,
330 .dev = {
331 .platform_data = &samsung_spdif_pdata,
332 .dma_mask = &s5pv210_spdif_dmamask,
333 .coherent_dma_mask = DMA_BIT_MASK(32),
334 },
335};
diff --git a/arch/arm/mach-s5pv210/dev-spi.c b/arch/arm/mach-s5pv210/dev-spi.c
index 826cdbc43e20..e3249a47e3b1 100644
--- a/arch/arm/mach-s5pv210/dev-spi.c
+++ b/arch/arm/mach-s5pv210/dev-spi.c
@@ -35,23 +35,15 @@ static char *spi_src_clks[] = {
35 */ 35 */
36static int s5pv210_spi_cfg_gpio(struct platform_device *pdev) 36static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
37{ 37{
38 unsigned int base;
39
38 switch (pdev->id) { 40 switch (pdev->id) {
39 case 0: 41 case 0:
40 s3c_gpio_cfgpin(S5PV210_GPB(0), S3C_GPIO_SFN(2)); 42 base = S5PV210_GPB(0);
41 s3c_gpio_cfgpin(S5PV210_GPB(1), S3C_GPIO_SFN(2));
42 s3c_gpio_cfgpin(S5PV210_GPB(2), S3C_GPIO_SFN(2));
43 s3c_gpio_setpull(S5PV210_GPB(0), S3C_GPIO_PULL_UP);
44 s3c_gpio_setpull(S5PV210_GPB(1), S3C_GPIO_PULL_UP);
45 s3c_gpio_setpull(S5PV210_GPB(2), S3C_GPIO_PULL_UP);
46 break; 43 break;
47 44
48 case 1: 45 case 1:
49 s3c_gpio_cfgpin(S5PV210_GPB(4), S3C_GPIO_SFN(2)); 46 base = S5PV210_GPB(4);
50 s3c_gpio_cfgpin(S5PV210_GPB(5), S3C_GPIO_SFN(2));
51 s3c_gpio_cfgpin(S5PV210_GPB(6), S3C_GPIO_SFN(2));
52 s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP);
53 s3c_gpio_setpull(S5PV210_GPB(5), S3C_GPIO_PULL_UP);
54 s3c_gpio_setpull(S5PV210_GPB(6), S3C_GPIO_PULL_UP);
55 break; 47 break;
56 48
57 default: 49 default:
@@ -59,6 +51,9 @@ static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
59 return -EINVAL; 51 return -EINVAL;
60 } 52 }
61 53
54 s3c_gpio_cfgall_range(base, 3,
55 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
56
62 return 0; 57 return 0;
63} 58}
64 59
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
index 778ad5fe231a..497d3439a142 100644
--- a/arch/arm/mach-s5pv210/dma.c
+++ b/arch/arm/mach-s5pv210/dma.c
@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5pv210_pdma0_pdata = {
82 82
83static struct platform_device s5pv210_device_pdma0 = { 83static struct platform_device s5pv210_device_pdma0 = {
84 .name = "s3c-pl330", 84 .name = "s3c-pl330",
85 .id = 1, 85 .id = 0,
86 .num_resources = ARRAY_SIZE(s5pv210_pdma0_resource), 86 .num_resources = ARRAY_SIZE(s5pv210_pdma0_resource),
87 .resource = s5pv210_pdma0_resource, 87 .resource = s5pv210_pdma0_resource,
88 .dev = { 88 .dev = {
@@ -144,7 +144,7 @@ static struct s3c_pl330_platdata s5pv210_pdma1_pdata = {
144 144
145static struct platform_device s5pv210_device_pdma1 = { 145static struct platform_device s5pv210_device_pdma1 = {
146 .name = "s3c-pl330", 146 .name = "s3c-pl330",
147 .id = 2, 147 .id = 1,
148 .num_resources = ARRAY_SIZE(s5pv210_pdma1_resource), 148 .num_resources = ARRAY_SIZE(s5pv210_pdma1_resource),
149 .resource = s5pv210_pdma1_resource, 149 .resource = s5pv210_pdma1_resource,
150 .dev = { 150 .dev = {
diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/arch/arm/mach-s5pv210/gpiolib.c
index 0d459112d039..ab673effd767 100644
--- a/arch/arm/mach-s5pv210/gpiolib.c
+++ b/arch/arm/mach-s5pv210/gpiolib.c
@@ -150,6 +150,7 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
150 .label = "GPG3", 150 .label = "GPG3",
151 }, 151 },
152 }, { 152 }, {
153 .config = &gpio_cfg_noint,
153 .chip = { 154 .chip = {
154 .base = S5PV210_GPI(0), 155 .base = S5PV210_GPI(0),
155 .ngpio = S5PV210_GPIO_I_NR, 156 .ngpio = S5PV210_GPIO_I_NR,
@@ -223,34 +224,42 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
223 }, { 224 }, {
224 .base = (S5P_VA_GPIO + 0xC00), 225 .base = (S5P_VA_GPIO + 0xC00),
225 .config = &gpio_cfg_noint, 226 .config = &gpio_cfg_noint,
227 .irq_base = IRQ_EINT(0),
226 .chip = { 228 .chip = {
227 .base = S5PV210_GPH0(0), 229 .base = S5PV210_GPH0(0),
228 .ngpio = S5PV210_GPIO_H0_NR, 230 .ngpio = S5PV210_GPIO_H0_NR,
229 .label = "GPH0", 231 .label = "GPH0",
232 .to_irq = samsung_gpiolib_to_irq,
230 }, 233 },
231 }, { 234 }, {
232 .base = (S5P_VA_GPIO + 0xC20), 235 .base = (S5P_VA_GPIO + 0xC20),
233 .config = &gpio_cfg_noint, 236 .config = &gpio_cfg_noint,
237 .irq_base = IRQ_EINT(8),
234 .chip = { 238 .chip = {
235 .base = S5PV210_GPH1(0), 239 .base = S5PV210_GPH1(0),
236 .ngpio = S5PV210_GPIO_H1_NR, 240 .ngpio = S5PV210_GPIO_H1_NR,
237 .label = "GPH1", 241 .label = "GPH1",
242 .to_irq = samsung_gpiolib_to_irq,
238 }, 243 },
239 }, { 244 }, {
240 .base = (S5P_VA_GPIO + 0xC40), 245 .base = (S5P_VA_GPIO + 0xC40),
241 .config = &gpio_cfg_noint, 246 .config = &gpio_cfg_noint,
247 .irq_base = IRQ_EINT(16),
242 .chip = { 248 .chip = {
243 .base = S5PV210_GPH2(0), 249 .base = S5PV210_GPH2(0),
244 .ngpio = S5PV210_GPIO_H2_NR, 250 .ngpio = S5PV210_GPIO_H2_NR,
245 .label = "GPH2", 251 .label = "GPH2",
252 .to_irq = samsung_gpiolib_to_irq,
246 }, 253 },
247 }, { 254 }, {
248 .base = (S5P_VA_GPIO + 0xC60), 255 .base = (S5P_VA_GPIO + 0xC60),
249 .config = &gpio_cfg_noint, 256 .config = &gpio_cfg_noint,
257 .irq_base = IRQ_EINT(24),
250 .chip = { 258 .chip = {
251 .base = S5PV210_GPH3(0), 259 .base = S5PV210_GPH3(0),
252 .ngpio = S5PV210_GPIO_H3_NR, 260 .ngpio = S5PV210_GPIO_H3_NR,
253 .label = "GPH3", 261 .label = "GPH3",
262 .to_irq = samsung_gpiolib_to_irq,
254 }, 263 },
255 }, 264 },
256}; 265};
@@ -259,11 +268,14 @@ static __init int s5pv210_gpiolib_init(void)
259{ 268{
260 struct s3c_gpio_chip *chip = s5pv210_gpio_4bit; 269 struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
261 int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit); 270 int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
271 int gpioint_group = 0;
262 int i = 0; 272 int i = 0;
263 273
264 for (i = 0; i < nr_chips; i++, chip++) { 274 for (i = 0; i < nr_chips; i++, chip++) {
265 if (chip->config == NULL) 275 if (chip->config == NULL) {
266 chip->config = &gpio_cfg; 276 chip->config = &gpio_cfg;
277 chip->group = gpioint_group++;
278 }
267 if (chip->base == NULL) 279 if (chip->base == NULL)
268 chip->base = S5PV210_BANK_BASE(i); 280 chip->base = S5PV210_BANK_BASE(i);
269 } 281 }
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index e1c020e5a49b..119b95fdc3ce 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -55,8 +55,8 @@
55#define IRQ_SPI1 S5P_IRQ_VIC1(16) 55#define IRQ_SPI1 S5P_IRQ_VIC1(16)
56#define IRQ_SPI2 S5P_IRQ_VIC1(17) 56#define IRQ_SPI2 S5P_IRQ_VIC1(17)
57#define IRQ_IRDA S5P_IRQ_VIC1(18) 57#define IRQ_IRDA S5P_IRQ_VIC1(18)
58#define IRQ_CAN0 S5P_IRQ_VIC1(19) 58#define IRQ_IIC2 S5P_IRQ_VIC1(19)
59#define IRQ_CAN1 S5P_IRQ_VIC1(20) 59#define IRQ_IIC3 S5P_IRQ_VIC1(20)
60#define IRQ_HSIRX S5P_IRQ_VIC1(21) 60#define IRQ_HSIRX S5P_IRQ_VIC1(21)
61#define IRQ_HSITX S5P_IRQ_VIC1(22) 61#define IRQ_HSITX S5P_IRQ_VIC1(22)
62#define IRQ_UHOST S5P_IRQ_VIC1(23) 62#define IRQ_UHOST S5P_IRQ_VIC1(23)
@@ -109,7 +109,7 @@
109 109
110#define IRQ_IPC S5P_IRQ_VIC3(0) 110#define IRQ_IPC S5P_IRQ_VIC3(0)
111#define IRQ_HOSTIF S5P_IRQ_VIC3(1) 111#define IRQ_HOSTIF S5P_IRQ_VIC3(1)
112#define IRQ_MMC3 S5P_IRQ_VIC3(2) 112#define IRQ_HSMMC3 S5P_IRQ_VIC3(2)
113#define IRQ_CEC S5P_IRQ_VIC3(3) 113#define IRQ_CEC S5P_IRQ_VIC3(3)
114#define IRQ_TSI S5P_IRQ_VIC3(4) 114#define IRQ_TSI S5P_IRQ_VIC3(4)
115#define IRQ_MDNIE0 S5P_IRQ_VIC3(5) 115#define IRQ_MDNIE0 S5P_IRQ_VIC3(5)
@@ -121,8 +121,12 @@
121#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) 121#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
122#define S5P_EINT_BASE2 (IRQ_VIC_END + 1) 122#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
123 123
124/* GPIO interrupt */
125#define S5P_GPIOINT_BASE (IRQ_EINT(31) + 1)
126#define S5P_GPIOINT_GROUP_MAXNR 22
127
124/* Set the default NR_IRQS */ 128/* Set the default NR_IRQS */
125#define NR_IRQS (IRQ_EINT(31) + 1) 129#define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
126 130
127/* Compatibility */ 131/* Compatibility */
128#define IRQ_LCD_FIFO IRQ_LCD0 132#define IRQ_LCD_FIFO IRQ_LCD0
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index bd9afd52466a..861d7fe11fc9 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -57,6 +57,8 @@
57 57
58#define S5P_SZ_UART SZ_256 58#define S5P_SZ_UART SZ_256
59 59
60#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
61
60#define S5PV210_PA_SROMC (0xE8000000) 62#define S5PV210_PA_SROMC (0xE8000000)
61 63
62#define S5PV210_PA_CFCON (0xE8200000) 64#define S5PV210_PA_CFCON (0xE8200000)
@@ -73,6 +75,9 @@
73 75
74#define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000)) 76#define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000))
75 77
78#define S5PV210_PA_HSOTG (0xEC000000)
79#define S5PV210_PA_HSPHY (0xEC100000)
80
76#define S5PV210_PA_VIC0 (0xF2000000) 81#define S5PV210_PA_VIC0 (0xF2000000)
77#define S5PV210_PA_VIC1 (0xF2100000) 82#define S5PV210_PA_VIC1 (0xF2100000)
78#define S5PV210_PA_VIC2 (0xF2200000) 83#define S5PV210_PA_VIC2 (0xF2200000)
@@ -81,6 +86,9 @@
81#define S5PV210_PA_SDRAM (0x20000000) 86#define S5PV210_PA_SDRAM (0x20000000)
82#define S5P_PA_SDRAM S5PV210_PA_SDRAM 87#define S5P_PA_SDRAM S5PV210_PA_SDRAM
83 88
89/* S/PDIF */
90#define S5PV210_PA_SPDIF 0xE1100000
91
84/* I2S */ 92/* I2S */
85#define S5PV210_PA_IIS0 0xEEE30000 93#define S5PV210_PA_IIS0 0xEEE30000
86#define S5PV210_PA_IIS1 0xE2100000 94#define S5PV210_PA_IIS1 0xE2100000
@@ -96,6 +104,9 @@
96 104
97#define S5PV210_PA_ADC (0xE1700000) 105#define S5PV210_PA_ADC (0xE1700000)
98 106
107#define S5PV210_PA_DMC0 (0xF0000000)
108#define S5PV210_PA_DMC1 (0xF1400000)
109
99/* compatibiltiy defines. */ 110/* compatibiltiy defines. */
100#define S3C_PA_UART S5PV210_PA_UART 111#define S3C_PA_UART S5PV210_PA_UART
101#define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0) 112#define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0)
@@ -108,6 +119,7 @@
108#define S3C_PA_FB S5PV210_PA_FB 119#define S3C_PA_FB S5PV210_PA_FB
109#define S3C_PA_RTC S5PV210_PA_RTC 120#define S3C_PA_RTC S5PV210_PA_RTC
110#define S3C_PA_WDT S5PV210_PA_WATCHDOG 121#define S3C_PA_WDT S5PV210_PA_WATCHDOG
122#define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG
111#define S5P_PA_FIMC0 S5PV210_PA_FIMC0 123#define S5P_PA_FIMC0 S5PV210_PA_FIMC0
112#define S5P_PA_FIMC1 S5PV210_PA_FIMC1 124#define S5P_PA_FIMC1 S5PV210_PA_FIMC1
113#define S5P_PA_FIMC2 S5PV210_PA_FIMC2 125#define S5P_PA_FIMC2 S5PV210_PA_FIMC2
diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h
new file mode 100644
index 000000000000..e8d394f8b057
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h
@@ -0,0 +1,43 @@
1/* linux/arch/arm/mach-s5pv210/include/mach/pm-core.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
7 * Copyright 2008 Simtec Electronics
8 * Ben Dooks <ben@simtec.co.uk>
9 * http://armlinux.simtec.co.uk/
10 *
11 * S5PV210 - PM core support for arch/arm/plat-s5p/pm.c
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16*/
17
18static inline void s3c_pm_debug_init_uart(void)
19{
20 /* nothing here yet */
21}
22
23static inline void s3c_pm_arch_prepare_irqs(void)
24{
25 __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK);
26 __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK);
27}
28
29static inline void s3c_pm_arch_stop_clocks(void)
30{
31 /* nothing here yet */
32}
33
34static inline void s3c_pm_arch_show_resume_irqs(void)
35{
36 /* nothing here yet */
37}
38
39static inline void s3c_pm_arch_update_uart(void __iomem *regs,
40 struct pm_uart_save *save)
41{
42 /* nothing here yet */
43}
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
index 499aef737476..ebaabe021af9 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -25,6 +25,7 @@
25#define S5P_APLL_CON S5P_CLKREG(0x100) 25#define S5P_APLL_CON S5P_CLKREG(0x100)
26#define S5P_MPLL_CON S5P_CLKREG(0x108) 26#define S5P_MPLL_CON S5P_CLKREG(0x108)
27#define S5P_EPLL_CON S5P_CLKREG(0x110) 27#define S5P_EPLL_CON S5P_CLKREG(0x110)
28#define S5P_EPLL_CON1 S5P_CLKREG(0x114)
28#define S5P_VPLL_CON S5P_CLKREG(0x120) 29#define S5P_VPLL_CON S5P_CLKREG(0x120)
29 30
30#define S5P_CLK_SRC0 S5P_CLKREG(0x200) 31#define S5P_CLK_SRC0 S5P_CLKREG(0x200)
@@ -67,11 +68,28 @@
67#define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488) 68#define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488)
68#define S5P_CLK_OUT S5P_CLKREG(0x500) 69#define S5P_CLK_OUT S5P_CLKREG(0x500)
69 70
71/* DIV/MUX STATUS */
72#define S5P_CLKDIV_STAT0 S5P_CLKREG(0x1000)
73#define S5P_CLKDIV_STAT1 S5P_CLKREG(0x1004)
74#define S5P_CLKMUX_STAT0 S5P_CLKREG(0x1100)
75#define S5P_CLKMUX_STAT1 S5P_CLKREG(0x1104)
76
70/* CLKSRC0 */ 77/* CLKSRC0 */
71#define S5P_CLKSRC0_MUX200_MASK (0x1<<16) 78#define S5P_CLKSRC0_MUX200_SHIFT (16)
79#define S5P_CLKSRC0_MUX200_MASK (0x1 << S5P_CLKSRC0_MUX200_SHIFT)
72#define S5P_CLKSRC0_MUX166_MASK (0x1<<20) 80#define S5P_CLKSRC0_MUX166_MASK (0x1<<20)
73#define S5P_CLKSRC0_MUX133_MASK (0x1<<24) 81#define S5P_CLKSRC0_MUX133_MASK (0x1<<24)
74 82
83/* CLKSRC2 */
84#define S5P_CLKSRC2_G3D_SHIFT (0)
85#define S5P_CLKSRC2_G3D_MASK (0x3 << S5P_CLKSRC2_G3D_SHIFT)
86#define S5P_CLKSRC2_MFC_SHIFT (4)
87#define S5P_CLKSRC2_MFC_MASK (0x3 << S5P_CLKSRC2_MFC_SHIFT)
88
89/* CLKSRC6*/
90#define S5P_CLKSRC6_ONEDRAM_SHIFT (24)
91#define S5P_CLKSRC6_ONEDRAM_MASK (0x3 << S5P_CLKSRC6_ONEDRAM_SHIFT)
92
75/* CLKDIV0 */ 93/* CLKDIV0 */
76#define S5P_CLKDIV0_APLL_SHIFT (0) 94#define S5P_CLKDIV0_APLL_SHIFT (0)
77#define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT) 95#define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT)
@@ -90,12 +108,24 @@
90#define S5P_CLKDIV0_PCLK66_SHIFT (28) 108#define S5P_CLKDIV0_PCLK66_SHIFT (28)
91#define S5P_CLKDIV0_PCLK66_MASK (0x7 << S5P_CLKDIV0_PCLK66_SHIFT) 109#define S5P_CLKDIV0_PCLK66_MASK (0x7 << S5P_CLKDIV0_PCLK66_SHIFT)
92 110
111/* CLKDIV2 */
112#define S5P_CLKDIV2_G3D_SHIFT (0)
113#define S5P_CLKDIV2_G3D_MASK (0xF << S5P_CLKDIV2_G3D_SHIFT)
114#define S5P_CLKDIV2_MFC_SHIFT (4)
115#define S5P_CLKDIV2_MFC_MASK (0xF << S5P_CLKDIV2_MFC_SHIFT)
116
117/* CLKDIV6 */
118#define S5P_CLKDIV6_ONEDRAM_SHIFT (28)
119#define S5P_CLKDIV6_ONEDRAM_MASK (0xF << S5P_CLKDIV6_ONEDRAM_SHIFT)
120
93#define S5P_SWRESET S5P_CLKREG(0x2000) 121#define S5P_SWRESET S5P_CLKREG(0x2000)
94 122
123#define S5P_ARM_MCS_CON S5P_CLKREG(0x6100)
124
95/* Registers related to power management */ 125/* Registers related to power management */
96#define S5P_PWR_CFG S5P_CLKREG(0xC000) 126#define S5P_PWR_CFG S5P_CLKREG(0xC000)
97#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004) 127#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004)
98#define S5P_WAKEUP_MASK S5P_CLKREG(0xC008) 128#define S5P_WAKEUP_MASK S5P_CLKREG(0xC008)
99#define S5P_PWR_MODE S5P_CLKREG(0xC00C) 129#define S5P_PWR_MODE S5P_CLKREG(0xC00C)
100#define S5P_NORMAL_CFG S5P_CLKREG(0xC010) 130#define S5P_NORMAL_CFG S5P_CLKREG(0xC010)
101#define S5P_IDLE_CFG S5P_CLKREG(0xC020) 131#define S5P_IDLE_CFG S5P_CLKREG(0xC020)
@@ -159,8 +189,11 @@
159#define S5P_SLEEP_CFG_USBOSC_EN (1 << 1) 189#define S5P_SLEEP_CFG_USBOSC_EN (1 << 1)
160 190
161/* OTHERS Resgister */ 191/* OTHERS Resgister */
192#define S5P_OTHERS_RET_IO (1 << 31)
193#define S5P_OTHERS_RET_CF (1 << 30)
194#define S5P_OTHERS_RET_MMC (1 << 29)
195#define S5P_OTHERS_RET_UART (1 << 28)
162#define S5P_OTHERS_USB_SIG_MASK (1 << 16) 196#define S5P_OTHERS_USB_SIG_MASK (1 << 16)
163#define S5P_OTHERS_MIPI_DPHY_EN (1 << 28)
164 197
165/* MIPI */ 198/* MIPI */
166#define S5P_MIPI_DPHY_EN (3) 199#define S5P_MIPI_DPHY_EN (3)
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
index 49e029b4978a..de0c89976078 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
@@ -31,13 +31,6 @@
31 31
32#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) 32#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
33 33
34/* values for S5P_EXTINT0 */
35#define S5P_EXTINT_LOWLEV (0x00)
36#define S5P_EXTINT_HILEV (0x01)
37#define S5P_EXTINT_FALLEDGE (0x02)
38#define S5P_EXTINT_RISEEDGE (0x03)
39#define S5P_EXTINT_BOTHEDGE (0x04)
40
41#define EINT_MODE S3C_GPIO_SFN(0xf) 34#define EINT_MODE S3C_GPIO_SFN(0xf)
42 35
43#define EINT_GPIO_0(x) S5PV210_GPH0(x) 36#define EINT_GPIO_0(x) S5PV210_GPH0(x)
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-sys.h b/arch/arm/mach-s5pv210/include/mach/regs-sys.h
new file mode 100644
index 000000000000..26691d39d0f4
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-sys.h
@@ -0,0 +1,19 @@
1/* arch/arm/mach-s5pv210/include/mach/regs-sys.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - System registers definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#define S5PV210_USB_PHY_CON (S3C_VA_SYS + 0xE80C)
14#define S5PV210_USB_PHY0_EN (1 << 0)
15#define S5PV210_USB_PHY1_EN (1 << 1)
16
17/* compatibility defines for s3c-hsotg driver */
18#define S3C64XX_OTHERS S5PV210_USB_PHY_CON
19#define S3C64XX_OTHERS_USBMASK S5PV210_USB_PHY0_EN
diff --git a/arch/arm/mach-s5pv210/include/mach/vmalloc.h b/arch/arm/mach-s5pv210/include/mach/vmalloc.h
index df9a28808323..a6c659d68a5d 100644
--- a/arch/arm/mach-s5pv210/include/mach/vmalloc.h
+++ b/arch/arm/mach-s5pv210/include/mach/vmalloc.h
@@ -17,6 +17,6 @@
17#ifndef __ASM_ARCH_VMALLOC_H 17#ifndef __ASM_ARCH_VMALLOC_H
18#define __ASM_ARCH_VMALLOC_H __FILE__ 18#define __ASM_ARCH_VMALLOC_H __FILE__
19 19
20#define VMALLOC_END (0xE0000000UL) 20#define VMALLOC_END 0xF6000000UL
21 21
22#endif /* __ASM_ARCH_VMALLOC_H */ 22#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 00883087363c..28677caf3613 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -16,6 +16,8 @@
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/i2c-gpio.h> 17#include <linux/i2c-gpio.h>
18#include <linux/mfd/max8998.h> 18#include <linux/mfd/max8998.h>
19#include <linux/mfd/wm8994/pdata.h>
20#include <linux/regulator/fixed.h>
19#include <linux/gpio_keys.h> 21#include <linux/gpio_keys.h>
20#include <linux/input.h> 22#include <linux/input.h>
21#include <linux/gpio.h> 23#include <linux/gpio.h>
@@ -379,6 +381,119 @@ static struct max8998_platform_data aquila_max8998_pdata = {
379}; 381};
380#endif 382#endif
381 383
384static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
385 {
386 .dev_name = "5-001a",
387 .supply = "DBVDD",
388 }, {
389 .dev_name = "5-001a",
390 .supply = "AVDD2",
391 }, {
392 .dev_name = "5-001a",
393 .supply = "CPVDD",
394 },
395};
396
397static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
398 {
399 .dev_name = "5-001a",
400 .supply = "SPKVDD1",
401 }, {
402 .dev_name = "5-001a",
403 .supply = "SPKVDD2",
404 },
405};
406
407static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
408 .constraints = {
409 .always_on = 1,
410 },
411 .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
412 .consumer_supplies = wm8994_fixed_voltage0_supplies,
413};
414
415static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
416 .constraints = {
417 .always_on = 1,
418 },
419 .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
420 .consumer_supplies = wm8994_fixed_voltage1_supplies,
421};
422
423static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
424 .supply_name = "VCC_1.8V_PDA",
425 .microvolts = 1800000,
426 .gpio = -EINVAL,
427 .init_data = &wm8994_fixed_voltage0_init_data,
428};
429
430static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
431 .supply_name = "V_BAT",
432 .microvolts = 3700000,
433 .gpio = -EINVAL,
434 .init_data = &wm8994_fixed_voltage1_init_data,
435};
436
437static struct platform_device wm8994_fixed_voltage0 = {
438 .name = "reg-fixed-voltage",
439 .id = 0,
440 .dev = {
441 .platform_data = &wm8994_fixed_voltage0_config,
442 },
443};
444
445static struct platform_device wm8994_fixed_voltage1 = {
446 .name = "reg-fixed-voltage",
447 .id = 1,
448 .dev = {
449 .platform_data = &wm8994_fixed_voltage1_config,
450 },
451};
452
453static struct regulator_consumer_supply wm8994_avdd1_supply = {
454 .dev_name = "5-001a",
455 .supply = "AVDD1",
456};
457
458static struct regulator_consumer_supply wm8994_dcvdd_supply = {
459 .dev_name = "5-001a",
460 .supply = "DCVDD",
461};
462
463static struct regulator_init_data wm8994_ldo1_data = {
464 .constraints = {
465 .name = "AVDD1_3.0V",
466 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
467 },
468 .num_consumer_supplies = 1,
469 .consumer_supplies = &wm8994_avdd1_supply,
470};
471
472static struct regulator_init_data wm8994_ldo2_data = {
473 .constraints = {
474 .name = "DCVDD_1.0V",
475 },
476 .num_consumer_supplies = 1,
477 .consumer_supplies = &wm8994_dcvdd_supply,
478};
479
480static struct wm8994_pdata wm8994_platform_data = {
481 /* configure gpio1 function: 0x0001(Logic level input/output) */
482 .gpio_defaults[0] = 0x0001,
483 /* configure gpio3/4/5/7 function for AIF2 voice */
484 .gpio_defaults[2] = 0x8100,
485 .gpio_defaults[3] = 0x8100,
486 .gpio_defaults[4] = 0x8100,
487 .gpio_defaults[6] = 0x0100,
488 /* configure gpio8/9/10/11 function for AIF3 BT */
489 .gpio_defaults[7] = 0x8100,
490 .gpio_defaults[8] = 0x0100,
491 .gpio_defaults[9] = 0x0100,
492 .gpio_defaults[10] = 0x0100,
493 .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */
494 .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
495};
496
382/* GPIO I2C PMIC */ 497/* GPIO I2C PMIC */
383#define AP_I2C_GPIO_PMIC_BUS_4 4 498#define AP_I2C_GPIO_PMIC_BUS_4 4
384static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = { 499static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = {
@@ -404,6 +519,29 @@ static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
404#endif 519#endif
405}; 520};
406 521
522/* GPIO I2C AP 1.8V */
523#define AP_I2C_GPIO_BUS_5 5
524static struct i2c_gpio_platform_data aquila_i2c_gpio5_data = {
525 .sda_pin = S5PV210_MP05(3), /* XM0ADDR_11 */
526 .scl_pin = S5PV210_MP05(2), /* XM0ADDR_10 */
527};
528
529static struct platform_device aquila_i2c_gpio5 = {
530 .name = "i2c-gpio",
531 .id = AP_I2C_GPIO_BUS_5,
532 .dev = {
533 .platform_data = &aquila_i2c_gpio5_data,
534 },
535};
536
537static struct i2c_board_info i2c_gpio5_devs[] __initdata = {
538 {
539 /* CS/ADDR = low 0x34 (FYI: high = 0x36) */
540 I2C_BOARD_INFO("wm8994", 0x1a),
541 .platform_data = &wm8994_platform_data,
542 },
543};
544
407/* PMIC Power button */ 545/* PMIC Power button */
408static struct gpio_keys_button aquila_gpio_keys_table[] = { 546static struct gpio_keys_button aquila_gpio_keys_table[] = {
409 { 547 {
@@ -475,6 +613,7 @@ static void aquila_setup_sdhci(void)
475 613
476static struct platform_device *aquila_devices[] __initdata = { 614static struct platform_device *aquila_devices[] __initdata = {
477 &aquila_i2c_gpio_pmic, 615 &aquila_i2c_gpio_pmic,
616 &aquila_i2c_gpio5,
478 &aquila_device_gpiokeys, 617 &aquila_device_gpiokeys,
479 &s3c_device_fb, 618 &s3c_device_fb,
480 &s5p_device_onenand, 619 &s5p_device_onenand,
@@ -484,8 +623,33 @@ static struct platform_device *aquila_devices[] __initdata = {
484 &s5p_device_fimc0, 623 &s5p_device_fimc0,
485 &s5p_device_fimc1, 624 &s5p_device_fimc1,
486 &s5p_device_fimc2, 625 &s5p_device_fimc2,
626 &s5pv210_device_iis0,
627 &wm8994_fixed_voltage0,
628 &wm8994_fixed_voltage1,
487}; 629};
488 630
631static void __init aquila_sound_init(void)
632{
633 unsigned int gpio;
634
635 /* CODEC_XTAL_EN
636 *
637 * The Aquila board have a oscillator which provide main clock
638 * to WM8994 codec. The oscillator provide 24MHz clock to WM8994
639 * clock. Set gpio setting of "CODEC_XTAL_EN" to enable a oscillator.
640 * */
641 gpio = S5PV210_GPH3(2); /* XEINT_26 */
642 gpio_request(gpio, "CODEC_XTAL_EN");
643 s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
644 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
645
646 /* Ths main clock of WM8994 codec uses the output of CLKOUT pin.
647 * The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS)
648 * because it needs 24MHz clock to operate WM8994 codec.
649 */
650 __raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS);
651}
652
489static void __init aquila_map_io(void) 653static void __init aquila_map_io(void)
490{ 654{
491 s5p_init_io(NULL, 0, S5P_VA_CHIPID); 655 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -506,6 +670,11 @@ static void __init aquila_machine_init(void)
506 s3c_fimc_setname(1, "s5p-fimc"); 670 s3c_fimc_setname(1, "s5p-fimc");
507 s3c_fimc_setname(2, "s5p-fimc"); 671 s3c_fimc_setname(2, "s5p-fimc");
508 672
673 /* SOUND */
674 aquila_sound_init();
675 i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs,
676 ARRAY_SIZE(i2c_gpio5_devs));
677
509 /* FB */ 678 /* FB */
510 s3c_fb_set_platdata(&aquila_lcd_pdata); 679 s3c_fb_set_platdata(&aquila_lcd_pdata);
511 680
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index d9ecf57fc2a5..b1dcf964a768 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -15,7 +15,13 @@
15#include <linux/fb.h> 15#include <linux/fb.h>
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/i2c-gpio.h> 17#include <linux/i2c-gpio.h>
18#include <linux/i2c/qt602240_ts.h>
18#include <linux/mfd/max8998.h> 19#include <linux/mfd/max8998.h>
20#include <linux/mfd/wm8994/pdata.h>
21#include <linux/regulator/fixed.h>
22#include <linux/spi/spi.h>
23#include <linux/spi/spi_gpio.h>
24#include <linux/lcd.h>
19#include <linux/gpio_keys.h> 25#include <linux/gpio_keys.h>
20#include <linux/input.h> 26#include <linux/input.h>
21#include <linux/gpio.h> 27#include <linux/gpio.h>
@@ -35,7 +41,10 @@
35#include <plat/devs.h> 41#include <plat/devs.h>
36#include <plat/cpu.h> 42#include <plat/cpu.h>
37#include <plat/fb.h> 43#include <plat/fb.h>
44#include <plat/iic.h>
45#include <plat/keypad.h>
38#include <plat/sdhci.h> 46#include <plat/sdhci.h>
47#include <plat/clock.h>
39 48
40/* Following are default values for UCON, ULCON and UFCON UART registers */ 49/* Following are default values for UCON, ULCON and UFCON UART registers */
41#define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 50#define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -87,13 +96,12 @@ static struct s3c2410_uartcfg goni_uartcfgs[] __initdata = {
87/* Frame Buffer */ 96/* Frame Buffer */
88static struct s3c_fb_pd_win goni_fb_win0 = { 97static struct s3c_fb_pd_win goni_fb_win0 = {
89 .win_mode = { 98 .win_mode = {
90 .pixclock = 1000000000000ULL / ((16+16+2+480)*(28+3+2+800)*55),
91 .left_margin = 16, 99 .left_margin = 16,
92 .right_margin = 16, 100 .right_margin = 16,
93 .upper_margin = 3, 101 .upper_margin = 2,
94 .lower_margin = 28, 102 .lower_margin = 28,
95 .hsync_len = 2, 103 .hsync_len = 2,
96 .vsync_len = 2, 104 .vsync_len = 1,
97 .xres = 480, 105 .xres = 480,
98 .yres = 800, 106 .yres = 800,
99 .refresh = 55, 107 .refresh = 55,
@@ -111,9 +119,160 @@ static struct s3c_fb_platdata goni_lcd_pdata __initdata = {
111 .setup_gpio = s5pv210_fb_gpio_setup_24bpp, 119 .setup_gpio = s5pv210_fb_gpio_setup_24bpp,
112}; 120};
113 121
122static int lcd_power_on(struct lcd_device *ld, int enable)
123{
124 return 1;
125}
126
127static int reset_lcd(struct lcd_device *ld)
128{
129 static unsigned int first = 1;
130 int reset_gpio = -1;
131
132 reset_gpio = S5PV210_MP05(5);
133
134 if (first) {
135 gpio_request(reset_gpio, "MLCD_RST");
136 first = 0;
137 }
138
139 gpio_direction_output(reset_gpio, 1);
140 return 1;
141}
142
143static struct lcd_platform_data goni_lcd_platform_data = {
144 .reset = reset_lcd,
145 .power_on = lcd_power_on,
146 .lcd_enabled = 0,
147 .reset_delay = 120, /* 120ms */
148 .power_on_delay = 25, /* 25ms */
149 .power_off_delay = 200, /* 200ms */
150};
151
152#define LCD_BUS_NUM 3
153static struct spi_board_info spi_board_info[] __initdata = {
154 {
155 .modalias = "s6e63m0",
156 .platform_data = &goni_lcd_platform_data,
157 .max_speed_hz = 1200000,
158 .bus_num = LCD_BUS_NUM,
159 .chip_select = 0,
160 .mode = SPI_MODE_3,
161 .controller_data = (void *)S5PV210_MP01(1), /* DISPLAY_CS */
162 },
163};
164
165static struct spi_gpio_platform_data lcd_spi_gpio_data = {
166 .sck = S5PV210_MP04(1), /* DISPLAY_CLK */
167 .mosi = S5PV210_MP04(3), /* DISPLAY_SI */
168 .miso = SPI_GPIO_NO_MISO,
169 .num_chipselect = 1,
170};
171
172static struct platform_device goni_spi_gpio = {
173 .name = "spi_gpio",
174 .id = LCD_BUS_NUM,
175 .dev = {
176 .parent = &s3c_device_fb.dev,
177 .platform_data = &lcd_spi_gpio_data,
178 },
179};
180
181/* KEYPAD */
182static uint32_t keymap[] __initdata = {
183 /* KEY(row, col, keycode) */
184 KEY(0, 1, KEY_MENU), /* Send */
185 KEY(0, 2, KEY_BACK), /* End */
186 KEY(1, 1, KEY_CONFIG), /* Half shot */
187 KEY(1, 2, KEY_VOLUMEUP),
188 KEY(2, 1, KEY_CAMERA), /* Full shot */
189 KEY(2, 2, KEY_VOLUMEDOWN),
190};
191
192static struct matrix_keymap_data keymap_data __initdata = {
193 .keymap = keymap,
194 .keymap_size = ARRAY_SIZE(keymap),
195};
196
197static struct samsung_keypad_platdata keypad_data __initdata = {
198 .keymap_data = &keymap_data,
199 .rows = 3,
200 .cols = 3,
201};
202
203/* Radio */
204static struct i2c_board_info i2c1_devs[] __initdata = {
205 {
206 I2C_BOARD_INFO("si470x", 0x10),
207 },
208};
209
210static void __init goni_radio_init(void)
211{
212 int gpio;
213
214 gpio = S5PV210_GPJ2(4); /* XMSMDATA_4 */
215 gpio_request(gpio, "FM_INT");
216 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
217 i2c1_devs[0].irq = gpio_to_irq(gpio);
218
219 gpio = S5PV210_GPJ2(5); /* XMSMDATA_5 */
220 gpio_request(gpio, "FM_RST");
221 gpio_direction_output(gpio, 1);
222}
223
224/* TSP */
225static struct qt602240_platform_data qt602240_platform_data = {
226 .x_line = 17,
227 .y_line = 11,
228 .x_size = 800,
229 .y_size = 480,
230 .blen = 0x21,
231 .threshold = 0x28,
232 .voltage = 2800000, /* 2.8V */
233 .orient = QT602240_DIAGONAL,
234};
235
236static struct s3c2410_platform_i2c i2c2_data __initdata = {
237 .flags = 0,
238 .bus_num = 2,
239 .slave_addr = 0x10,
240 .frequency = 400 * 1000,
241 .sda_delay = 100,
242};
243
244static struct i2c_board_info i2c2_devs[] __initdata = {
245 {
246 I2C_BOARD_INFO("qt602240_ts", 0x4a),
247 .platform_data = &qt602240_platform_data,
248 },
249};
250
251static void __init goni_tsp_init(void)
252{
253 int gpio;
254
255 gpio = S5PV210_GPJ1(3); /* XMSMADDR_11 */
256 gpio_request(gpio, "TSP_LDO_ON");
257 gpio_direction_output(gpio, 1);
258 gpio_export(gpio, 0);
259
260 gpio = S5PV210_GPJ0(5); /* XMSMADDR_5 */
261 gpio_request(gpio, "TSP_INT");
262
263 s5p_register_gpio_interrupt(gpio);
264 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
265 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
266 i2c2_devs[0].irq = gpio_to_irq(gpio);
267}
268
114/* MAX8998 regulators */ 269/* MAX8998 regulators */
115#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE) 270#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
116 271
272static struct regulator_consumer_supply goni_ldo5_consumers[] = {
273 REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
274};
275
117static struct regulator_init_data goni_ldo2_data = { 276static struct regulator_init_data goni_ldo2_data = {
118 .constraints = { 277 .constraints = {
119 .name = "VALIVE_1.1V", 278 .name = "VALIVE_1.1V",
@@ -153,6 +312,8 @@ static struct regulator_init_data goni_ldo5_data = {
153 .max_uV = 2800000, 312 .max_uV = 2800000,
154 .apply_uV = 1, 313 .apply_uV = 1,
155 }, 314 },
315 .num_consumer_supplies = ARRAY_SIZE(goni_ldo5_consumers),
316 .consumer_supplies = goni_ldo5_consumers,
156}; 317};
157 318
158static struct regulator_init_data goni_ldo6_data = { 319static struct regulator_init_data goni_ldo6_data = {
@@ -360,6 +521,119 @@ static struct max8998_platform_data goni_max8998_pdata = {
360}; 521};
361#endif 522#endif
362 523
524static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
525 {
526 .dev_name = "5-001a",
527 .supply = "DBVDD",
528 }, {
529 .dev_name = "5-001a",
530 .supply = "AVDD2",
531 }, {
532 .dev_name = "5-001a",
533 .supply = "CPVDD",
534 },
535};
536
537static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
538 {
539 .dev_name = "5-001a",
540 .supply = "SPKVDD1",
541 }, {
542 .dev_name = "5-001a",
543 .supply = "SPKVDD2",
544 },
545};
546
547static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
548 .constraints = {
549 .always_on = 1,
550 },
551 .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
552 .consumer_supplies = wm8994_fixed_voltage0_supplies,
553};
554
555static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
556 .constraints = {
557 .always_on = 1,
558 },
559 .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
560 .consumer_supplies = wm8994_fixed_voltage1_supplies,
561};
562
563static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
564 .supply_name = "VCC_1.8V_PDA",
565 .microvolts = 1800000,
566 .gpio = -EINVAL,
567 .init_data = &wm8994_fixed_voltage0_init_data,
568};
569
570static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
571 .supply_name = "V_BAT",
572 .microvolts = 3700000,
573 .gpio = -EINVAL,
574 .init_data = &wm8994_fixed_voltage1_init_data,
575};
576
577static struct platform_device wm8994_fixed_voltage0 = {
578 .name = "reg-fixed-voltage",
579 .id = 0,
580 .dev = {
581 .platform_data = &wm8994_fixed_voltage0_config,
582 },
583};
584
585static struct platform_device wm8994_fixed_voltage1 = {
586 .name = "reg-fixed-voltage",
587 .id = 1,
588 .dev = {
589 .platform_data = &wm8994_fixed_voltage1_config,
590 },
591};
592
593static struct regulator_consumer_supply wm8994_avdd1_supply = {
594 .dev_name = "5-001a",
595 .supply = "AVDD1",
596};
597
598static struct regulator_consumer_supply wm8994_dcvdd_supply = {
599 .dev_name = "5-001a",
600 .supply = "DCVDD",
601};
602
603static struct regulator_init_data wm8994_ldo1_data = {
604 .constraints = {
605 .name = "AVDD1_3.0V",
606 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
607 },
608 .num_consumer_supplies = 1,
609 .consumer_supplies = &wm8994_avdd1_supply,
610};
611
612static struct regulator_init_data wm8994_ldo2_data = {
613 .constraints = {
614 .name = "DCVDD_1.0V",
615 },
616 .num_consumer_supplies = 1,
617 .consumer_supplies = &wm8994_dcvdd_supply,
618};
619
620static struct wm8994_pdata wm8994_platform_data = {
621 /* configure gpio1 function: 0x0001(Logic level input/output) */
622 .gpio_defaults[0] = 0x0001,
623 /* configure gpio3/4/5/7 function for AIF2 voice */
624 .gpio_defaults[2] = 0x8100,
625 .gpio_defaults[3] = 0x8100,
626 .gpio_defaults[4] = 0x8100,
627 .gpio_defaults[6] = 0x0100,
628 /* configure gpio8/9/10/11 function for AIF3 BT */
629 .gpio_defaults[7] = 0x8100,
630 .gpio_defaults[8] = 0x0100,
631 .gpio_defaults[9] = 0x0100,
632 .gpio_defaults[10] = 0x0100,
633 .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */
634 .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
635};
636
363/* GPIO I2C PMIC */ 637/* GPIO I2C PMIC */
364#define AP_I2C_GPIO_PMIC_BUS_4 4 638#define AP_I2C_GPIO_PMIC_BUS_4 4
365static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = { 639static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = {
@@ -385,6 +659,29 @@ static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
385#endif 659#endif
386}; 660};
387 661
662/* GPIO I2C AP 1.8V */
663#define AP_I2C_GPIO_BUS_5 5
664static struct i2c_gpio_platform_data goni_i2c_gpio5_data = {
665 .sda_pin = S5PV210_MP05(3), /* XM0ADDR_11 */
666 .scl_pin = S5PV210_MP05(2), /* XM0ADDR_10 */
667};
668
669static struct platform_device goni_i2c_gpio5 = {
670 .name = "i2c-gpio",
671 .id = AP_I2C_GPIO_BUS_5,
672 .dev = {
673 .platform_data = &goni_i2c_gpio5_data,
674 },
675};
676
677static struct i2c_board_info i2c_gpio5_devs[] __initdata = {
678 {
679 /* CS/ADDR = low 0x34 (FYI: high = 0x36) */
680 I2C_BOARD_INFO("wm8994", 0x1a),
681 .platform_data = &wm8994_platform_data,
682 },
683};
684
388/* PMIC Power button */ 685/* PMIC Power button */
389static struct gpio_keys_button goni_gpio_keys_table[] = { 686static struct gpio_keys_button goni_gpio_keys_table[] = {
390 { 687 {
@@ -444,11 +741,37 @@ static struct s3c_sdhci_platdata goni_hsmmc2_data __initdata = {
444 .ext_cd_gpio_invert = 1, 741 .ext_cd_gpio_invert = 1,
445}; 742};
446 743
744static struct regulator_consumer_supply mmc2_supplies[] = {
745 REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"),
746};
747
748static struct regulator_init_data mmc2_fixed_voltage_init_data = {
749 .constraints = {
750 .name = "V_TF_2.8V",
751 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
752 },
753 .num_consumer_supplies = ARRAY_SIZE(mmc2_supplies),
754 .consumer_supplies = mmc2_supplies,
755};
756
757static struct fixed_voltage_config mmc2_fixed_voltage_config = {
758 .supply_name = "EXT_FLASH_EN",
759 .microvolts = 2800000,
760 .gpio = GONI_EXT_FLASH_EN,
761 .enable_high = true,
762 .init_data = &mmc2_fixed_voltage_init_data,
763};
764
765static struct platform_device mmc2_fixed_voltage = {
766 .name = "reg-fixed-voltage",
767 .id = 2,
768 .dev = {
769 .platform_data = &mmc2_fixed_voltage_config,
770 },
771};
772
447static void goni_setup_sdhci(void) 773static void goni_setup_sdhci(void)
448{ 774{
449 gpio_request(GONI_EXT_FLASH_EN, "FLASH_EN");
450 gpio_direction_output(GONI_EXT_FLASH_EN, 1);
451
452 s3c_sdhci0_set_platdata(&goni_hsmmc0_data); 775 s3c_sdhci0_set_platdata(&goni_hsmmc0_data);
453 s3c_sdhci1_set_platdata(&goni_hsmmc1_data); 776 s3c_sdhci1_set_platdata(&goni_hsmmc1_data);
454 s3c_sdhci2_set_platdata(&goni_hsmmc2_data); 777 s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
@@ -457,7 +780,10 @@ static void goni_setup_sdhci(void)
457static struct platform_device *goni_devices[] __initdata = { 780static struct platform_device *goni_devices[] __initdata = {
458 &s3c_device_fb, 781 &s3c_device_fb,
459 &s5p_device_onenand, 782 &s5p_device_onenand,
783 &goni_spi_gpio,
460 &goni_i2c_gpio_pmic, 784 &goni_i2c_gpio_pmic,
785 &goni_i2c_gpio5,
786 &mmc2_fixed_voltage,
461 &goni_device_gpiokeys, 787 &goni_device_gpiokeys,
462 &s5p_device_fimc0, 788 &s5p_device_fimc0,
463 &s5p_device_fimc1, 789 &s5p_device_fimc1,
@@ -465,8 +791,24 @@ static struct platform_device *goni_devices[] __initdata = {
465 &s3c_device_hsmmc0, 791 &s3c_device_hsmmc0,
466 &s3c_device_hsmmc1, 792 &s3c_device_hsmmc1,
467 &s3c_device_hsmmc2, 793 &s3c_device_hsmmc2,
794 &s5pv210_device_iis0,
795 &s3c_device_usb_hsotg,
796 &samsung_device_keypad,
797 &s3c_device_i2c1,
798 &s3c_device_i2c2,
799 &wm8994_fixed_voltage0,
800 &wm8994_fixed_voltage1,
468}; 801};
469 802
803static void __init goni_sound_init(void)
804{
805 /* Ths main clock of WM8994 codec uses the output of CLKOUT pin.
806 * The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS)
807 * because it needs 24MHz clock to operate WM8994 codec.
808 */
809 __raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS);
810}
811
470static void __init goni_map_io(void) 812static void __init goni_map_io(void)
471{ 813{
472 s5p_init_io(NULL, 0, S5P_VA_CHIPID); 814 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -476,6 +818,20 @@ static void __init goni_map_io(void)
476 818
477static void __init goni_machine_init(void) 819static void __init goni_machine_init(void)
478{ 820{
821 /* Radio: call before I2C 1 registeration */
822 goni_radio_init();
823
824 /* I2C1 */
825 s3c_i2c1_set_platdata(NULL);
826 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
827
828 /* TSP: call before I2C 2 registeration */
829 goni_tsp_init();
830
831 /* I2C2 */
832 s3c_i2c2_set_platdata(&i2c2_data);
833 i2c_register_board_info(2, i2c2_devs, ARRAY_SIZE(i2c2_devs));
834
479 /* PMIC */ 835 /* PMIC */
480 goni_pmic_init(); 836 goni_pmic_init();
481 i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs, 837 i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs,
@@ -483,9 +839,22 @@ static void __init goni_machine_init(void)
483 /* SDHCI */ 839 /* SDHCI */
484 goni_setup_sdhci(); 840 goni_setup_sdhci();
485 841
842 /* SOUND */
843 goni_sound_init();
844 i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs,
845 ARRAY_SIZE(i2c_gpio5_devs));
846
486 /* FB */ 847 /* FB */
487 s3c_fb_set_platdata(&goni_lcd_pdata); 848 s3c_fb_set_platdata(&goni_lcd_pdata);
488 849
850 /* SPI */
851 spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
852
853 /* KEYPAD */
854 samsung_keypad_set_platdata(&keypad_data);
855
856 clk_xusbxti.rate = 24000000;
857
489 platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices)); 858 platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices));
490} 859}
491 860
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
index cea9bca79d88..0ad7924fe62e 100644
--- a/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -28,6 +28,7 @@
28#include <plat/cpu.h> 28#include <plat/cpu.h>
29#include <plat/ata.h> 29#include <plat/ata.h>
30#include <plat/iic.h> 30#include <plat/iic.h>
31#include <plat/pm.h>
31 32
32/* Following are default values for UCON, ULCON and UFCON UART registers */ 33/* Following are default values for UCON, ULCON and UFCON UART registers */
33#define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 34#define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -81,6 +82,7 @@ static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = {
81static struct platform_device *smdkc110_devices[] __initdata = { 82static struct platform_device *smdkc110_devices[] __initdata = {
82 &s5pv210_device_iis0, 83 &s5pv210_device_iis0,
83 &s5pv210_device_ac97, 84 &s5pv210_device_ac97,
85 &s5pv210_device_spdif,
84 &s3c_device_cfcon, 86 &s3c_device_cfcon,
85 &s3c_device_i2c0, 87 &s3c_device_i2c0,
86 &s3c_device_i2c1, 88 &s3c_device_i2c1,
@@ -110,6 +112,8 @@ static void __init smdkc110_map_io(void)
110 112
111static void __init smdkc110_machine_init(void) 113static void __init smdkc110_machine_init(void)
112{ 114{
115 s3c_pm_init();
116
113 s3c_i2c0_set_platdata(NULL); 117 s3c_i2c0_set_platdata(NULL);
114 s3c_i2c1_set_platdata(NULL); 118 s3c_i2c1_set_platdata(NULL);
115 s3c_i2c2_set_platdata(NULL); 119 s3c_i2c2_set_platdata(NULL);
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index 83189ae9da9a..bcd7a5d53401 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -31,6 +31,7 @@
31#include <plat/ata.h> 31#include <plat/ata.h>
32#include <plat/iic.h> 32#include <plat/iic.h>
33#include <plat/keypad.h> 33#include <plat/keypad.h>
34#include <plat/pm.h>
34 35
35/* Following are default values for UCON, ULCON and UFCON UART registers */ 36/* Following are default values for UCON, ULCON and UFCON UART registers */
36#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 37#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -103,6 +104,7 @@ static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = {
103static struct platform_device *smdkv210_devices[] __initdata = { 104static struct platform_device *smdkv210_devices[] __initdata = {
104 &s5pv210_device_iis0, 105 &s5pv210_device_iis0,
105 &s5pv210_device_ac97, 106 &s5pv210_device_ac97,
107 &s5pv210_device_spdif,
106 &s3c_device_adc, 108 &s3c_device_adc,
107 &s3c_device_cfcon, 109 &s3c_device_cfcon,
108 &s3c_device_hsmmc0, 110 &s3c_device_hsmmc0,
@@ -145,6 +147,8 @@ static void __init smdkv210_map_io(void)
145 147
146static void __init smdkv210_machine_init(void) 148static void __init smdkv210_machine_init(void)
147{ 149{
150 s3c_pm_init();
151
148 samsung_keypad_set_platdata(&smdkv210_keypad_data); 152 samsung_keypad_set_platdata(&smdkv210_keypad_data);
149 s3c24xx_ts_set_platdata(&s3c_ts_platform); 153 s3c24xx_ts_set_platdata(&s3c_ts_platform);
150 154
diff --git a/arch/arm/mach-s5pv210/mach-torbreck.c b/arch/arm/mach-s5pv210/mach-torbreck.c
new file mode 100644
index 000000000000..043c938806b0
--- /dev/null
+++ b/arch/arm/mach-s5pv210/mach-torbreck.c
@@ -0,0 +1,131 @@
1/* linux/arch/arm/mach-s5pv210/mach-torbreck.c
2 *
3 * Copyright (c) 2010 aESOP Community
4 * http://www.aesop.or.kr/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/i2c.h>
14#include <linux/init.h>
15#include <linux/serial_core.h>
16
17#include <asm/mach/arch.h>
18#include <asm/mach/map.h>
19#include <asm/setup.h>
20#include <asm/mach-types.h>
21
22#include <mach/map.h>
23#include <mach/regs-clock.h>
24
25#include <plat/regs-serial.h>
26#include <plat/s5pv210.h>
27#include <plat/devs.h>
28#include <plat/cpu.h>
29#include <plat/iic.h>
30
31/* Following are default values for UCON, ULCON and UFCON UART registers */
32#define TORBRECK_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
33 S3C2410_UCON_RXILEVEL | \
34 S3C2410_UCON_TXIRQMODE | \
35 S3C2410_UCON_RXIRQMODE | \
36 S3C2410_UCON_RXFIFO_TOI | \
37 S3C2443_UCON_RXERR_IRQEN)
38
39#define TORBRECK_ULCON_DEFAULT S3C2410_LCON_CS8
40
41#define TORBRECK_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
42 S5PV210_UFCON_TXTRIG4 | \
43 S5PV210_UFCON_RXTRIG4)
44
45static struct s3c2410_uartcfg torbreck_uartcfgs[] __initdata = {
46 [0] = {
47 .hwport = 0,
48 .flags = 0,
49 .ucon = TORBRECK_UCON_DEFAULT,
50 .ulcon = TORBRECK_ULCON_DEFAULT,
51 .ufcon = TORBRECK_UFCON_DEFAULT,
52 },
53 [1] = {
54 .hwport = 1,
55 .flags = 0,
56 .ucon = TORBRECK_UCON_DEFAULT,
57 .ulcon = TORBRECK_ULCON_DEFAULT,
58 .ufcon = TORBRECK_UFCON_DEFAULT,
59 },
60 [2] = {
61 .hwport = 2,
62 .flags = 0,
63 .ucon = TORBRECK_UCON_DEFAULT,
64 .ulcon = TORBRECK_ULCON_DEFAULT,
65 .ufcon = TORBRECK_UFCON_DEFAULT,
66 },
67 [3] = {
68 .hwport = 3,
69 .flags = 0,
70 .ucon = TORBRECK_UCON_DEFAULT,
71 .ulcon = TORBRECK_ULCON_DEFAULT,
72 .ufcon = TORBRECK_UFCON_DEFAULT,
73 },
74};
75
76static struct platform_device *torbreck_devices[] __initdata = {
77 &s5pv210_device_iis0,
78 &s3c_device_cfcon,
79 &s3c_device_hsmmc0,
80 &s3c_device_hsmmc1,
81 &s3c_device_hsmmc2,
82 &s3c_device_hsmmc3,
83 &s3c_device_i2c0,
84 &s3c_device_i2c1,
85 &s3c_device_i2c2,
86 &s3c_device_rtc,
87 &s3c_device_wdt,
88};
89
90static struct i2c_board_info torbreck_i2c_devs0[] __initdata = {
91 /* To Be Updated */
92};
93
94static struct i2c_board_info torbreck_i2c_devs1[] __initdata = {
95 /* To Be Updated */
96};
97
98static struct i2c_board_info torbreck_i2c_devs2[] __initdata = {
99 /* To Be Updated */
100};
101
102static void __init torbreck_map_io(void)
103{
104 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
105 s3c24xx_init_clocks(24000000);
106 s3c24xx_init_uarts(torbreck_uartcfgs, ARRAY_SIZE(torbreck_uartcfgs));
107}
108
109static void __init torbreck_machine_init(void)
110{
111 s3c_i2c0_set_platdata(NULL);
112 s3c_i2c1_set_platdata(NULL);
113 s3c_i2c2_set_platdata(NULL);
114 i2c_register_board_info(0, torbreck_i2c_devs0,
115 ARRAY_SIZE(torbreck_i2c_devs0));
116 i2c_register_board_info(1, torbreck_i2c_devs1,
117 ARRAY_SIZE(torbreck_i2c_devs1));
118 i2c_register_board_info(2, torbreck_i2c_devs2,
119 ARRAY_SIZE(torbreck_i2c_devs2));
120
121 platform_add_devices(torbreck_devices, ARRAY_SIZE(torbreck_devices));
122}
123
124MACHINE_START(TORBRECK, "TORBRECK")
125 /* Maintainer: Hyunchul Ko <ghcstop@gmail.com> */
126 .boot_params = S5P_PA_SDRAM + 0x100,
127 .init_irq = s5pv210_init_irq,
128 .map_io = torbreck_map_io,
129 .init_machine = torbreck_machine_init,
130 .timer = &s3c24xx_timer,
131MACHINE_END
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c
new file mode 100644
index 000000000000..549d7924fd4c
--- /dev/null
+++ b/arch/arm/mach-s5pv210/pm.c
@@ -0,0 +1,166 @@
1/* linux/arch/arm/mach-s5pv210/pm.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV210 - Power Management support
7 *
8 * Based on arch/arm/mach-s3c2410/pm.c
9 * Copyright (c) 2006 Simtec Electronics
10 * Ben Dooks <ben@simtec.co.uk>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15*/
16
17#include <linux/init.h>
18#include <linux/suspend.h>
19#include <linux/io.h>
20
21#include <plat/cpu.h>
22#include <plat/pm.h>
23#include <plat/regs-timer.h>
24
25#include <mach/regs-irq.h>
26#include <mach/regs-clock.h>
27
28static struct sleep_save s5pv210_core_save[] = {
29 /* Clock source */
30 SAVE_ITEM(S5P_CLK_SRC0),
31 SAVE_ITEM(S5P_CLK_SRC1),
32 SAVE_ITEM(S5P_CLK_SRC2),
33 SAVE_ITEM(S5P_CLK_SRC3),
34 SAVE_ITEM(S5P_CLK_SRC4),
35 SAVE_ITEM(S5P_CLK_SRC5),
36 SAVE_ITEM(S5P_CLK_SRC6),
37
38 /* Clock source Mask */
39 SAVE_ITEM(S5P_CLK_SRC_MASK0),
40 SAVE_ITEM(S5P_CLK_SRC_MASK1),
41
42 /* Clock Divider */
43 SAVE_ITEM(S5P_CLK_DIV0),
44 SAVE_ITEM(S5P_CLK_DIV1),
45 SAVE_ITEM(S5P_CLK_DIV2),
46 SAVE_ITEM(S5P_CLK_DIV3),
47 SAVE_ITEM(S5P_CLK_DIV4),
48 SAVE_ITEM(S5P_CLK_DIV5),
49 SAVE_ITEM(S5P_CLK_DIV6),
50 SAVE_ITEM(S5P_CLK_DIV7),
51
52 /* Clock Main Gate */
53 SAVE_ITEM(S5P_CLKGATE_MAIN0),
54 SAVE_ITEM(S5P_CLKGATE_MAIN1),
55 SAVE_ITEM(S5P_CLKGATE_MAIN2),
56
57 /* Clock source Peri Gate */
58 SAVE_ITEM(S5P_CLKGATE_PERI0),
59 SAVE_ITEM(S5P_CLKGATE_PERI1),
60
61 /* Clock source SCLK Gate */
62 SAVE_ITEM(S5P_CLKGATE_SCLK0),
63 SAVE_ITEM(S5P_CLKGATE_SCLK1),
64
65 /* Clock IP Clock gate */
66 SAVE_ITEM(S5P_CLKGATE_IP0),
67 SAVE_ITEM(S5P_CLKGATE_IP1),
68 SAVE_ITEM(S5P_CLKGATE_IP2),
69 SAVE_ITEM(S5P_CLKGATE_IP3),
70 SAVE_ITEM(S5P_CLKGATE_IP4),
71
72 /* Clock Blcok and Bus gate */
73 SAVE_ITEM(S5P_CLKGATE_BLOCK),
74 SAVE_ITEM(S5P_CLKGATE_BUS0),
75
76 /* Clock ETC */
77 SAVE_ITEM(S5P_CLK_OUT),
78 SAVE_ITEM(S5P_MDNIE_SEL),
79
80 /* PWM Register */
81 SAVE_ITEM(S3C2410_TCFG0),
82 SAVE_ITEM(S3C2410_TCFG1),
83 SAVE_ITEM(S3C64XX_TINT_CSTAT),
84 SAVE_ITEM(S3C2410_TCON),
85 SAVE_ITEM(S3C2410_TCNTB(0)),
86 SAVE_ITEM(S3C2410_TCMPB(0)),
87 SAVE_ITEM(S3C2410_TCNTO(0)),
88};
89
90void s5pv210_cpu_suspend(void)
91{
92 unsigned long tmp;
93
94 /* issue the standby signal into the pm unit. Note, we
95 * issue a write-buffer drain just in case */
96
97 tmp = 0;
98
99 asm("b 1f\n\t"
100 ".align 5\n\t"
101 "1:\n\t"
102 "mcr p15, 0, %0, c7, c10, 5\n\t"
103 "mcr p15, 0, %0, c7, c10, 4\n\t"
104 "wfi" : : "r" (tmp));
105
106 /* we should never get past here */
107 panic("sleep resumed to originator?");
108}
109
110static void s5pv210_pm_prepare(void)
111{
112 unsigned int tmp;
113
114 /* ensure at least INFORM0 has the resume address */
115 __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
116
117 tmp = __raw_readl(S5P_SLEEP_CFG);
118 tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN);
119 __raw_writel(tmp, S5P_SLEEP_CFG);
120
121 /* WFI for SLEEP mode configuration by SYSCON */
122 tmp = __raw_readl(S5P_PWR_CFG);
123 tmp &= S5P_CFG_WFI_CLEAN;
124 tmp |= S5P_CFG_WFI_SLEEP;
125 __raw_writel(tmp, S5P_PWR_CFG);
126
127 /* SYSCON interrupt handling disable */
128 tmp = __raw_readl(S5P_OTHERS);
129 tmp |= S5P_OTHER_SYSC_INTOFF;
130 __raw_writel(tmp, S5P_OTHERS);
131
132 s3c_pm_do_save(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
133}
134
135static int s5pv210_pm_add(struct sys_device *sysdev)
136{
137 pm_cpu_prep = s5pv210_pm_prepare;
138 pm_cpu_sleep = s5pv210_cpu_suspend;
139
140 return 0;
141}
142
143static int s5pv210_pm_resume(struct sys_device *dev)
144{
145 u32 tmp;
146
147 tmp = __raw_readl(S5P_OTHERS);
148 tmp |= (S5P_OTHERS_RET_IO | S5P_OTHERS_RET_CF |\
149 S5P_OTHERS_RET_MMC | S5P_OTHERS_RET_UART);
150 __raw_writel(tmp , S5P_OTHERS);
151
152 s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
153
154 return 0;
155}
156
157static struct sysdev_driver s5pv210_pm_driver = {
158 .add = s5pv210_pm_add,
159 .resume = s5pv210_pm_resume,
160};
161
162static __init int s5pv210_pm_drvinit(void)
163{
164 return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver);
165}
166arch_initcall(s5pv210_pm_drvinit);
diff --git a/arch/arm/mach-s5pv210/setup-fb-24bpp.c b/arch/arm/mach-s5pv210/setup-fb-24bpp.c
index 928cf1f125fa..e932ebfac56d 100644
--- a/arch/arm/mach-s5pv210/setup-fb-24bpp.c
+++ b/arch/arm/mach-s5pv210/setup-fb-24bpp.c
@@ -21,33 +21,21 @@
21#include <mach/regs-clock.h> 21#include <mach/regs-clock.h>
22#include <plat/gpio-cfg.h> 22#include <plat/gpio-cfg.h>
23 23
24void s5pv210_fb_gpio_setup_24bpp(void) 24static void s5pv210_fb_cfg_gpios(unsigned int base, unsigned int nr)
25{ 25{
26 unsigned int gpio = 0; 26 s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2));
27
28 for (gpio = S5PV210_GPF0(0); gpio <= S5PV210_GPF0(7); gpio++) {
29 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
30 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
31 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
32 }
33 27
34 for (gpio = S5PV210_GPF1(0); gpio <= S5PV210_GPF1(7); gpio++) { 28 for (; nr > 0; nr--, base++)
35 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 29 s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
36 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 30}
37 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
38 }
39 31
40 for (gpio = S5PV210_GPF2(0); gpio <= S5PV210_GPF2(7); gpio++) {
41 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
42 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
43 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
44 }
45 32
46 for (gpio = S5PV210_GPF3(0); gpio <= S5PV210_GPF3(3); gpio++) { 33void s5pv210_fb_gpio_setup_24bpp(void)
47 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 34{
48 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 35 s5pv210_fb_cfg_gpios(S5PV210_GPF0(0), 8);
49 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); 36 s5pv210_fb_cfg_gpios(S5PV210_GPF1(0), 8);
50 } 37 s5pv210_fb_cfg_gpios(S5PV210_GPF2(0), 8);
38 s5pv210_fb_cfg_gpios(S5PV210_GPF3(0), 4);
51 39
52 /* Set DISPLAY_CONTROL register for Display path selection. 40 /* Set DISPLAY_CONTROL register for Display path selection.
53 * 41 *
diff --git a/arch/arm/mach-s5pv210/setup-i2c0.c b/arch/arm/mach-s5pv210/setup-i2c0.c
index d38f7cb7e662..0f1cc3a1c1e8 100644
--- a/arch/arm/mach-s5pv210/setup-i2c0.c
+++ b/arch/arm/mach-s5pv210/setup-i2c0.c
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
23 23
24void s3c_i2c0_cfg_gpio(struct platform_device *dev) 24void s3c_i2c0_cfg_gpio(struct platform_device *dev)
25{ 25{
26 s3c_gpio_cfgpin(S5PV210_GPD1(0), S3C_GPIO_SFN(2)); 26 s3c_gpio_cfgall_range(S5PV210_GPD1(0), 2,
27 s3c_gpio_setpull(S5PV210_GPD1(0), S3C_GPIO_PULL_UP); 27 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
28 s3c_gpio_cfgpin(S5PV210_GPD1(1), S3C_GPIO_SFN(2));
29 s3c_gpio_setpull(S5PV210_GPD1(1), S3C_GPIO_PULL_UP);
30} 28}
diff --git a/arch/arm/mach-s5pv210/setup-i2c1.c b/arch/arm/mach-s5pv210/setup-i2c1.c
index 148bb7857d89..f61365a34c56 100644
--- a/arch/arm/mach-s5pv210/setup-i2c1.c
+++ b/arch/arm/mach-s5pv210/setup-i2c1.c
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
23 23
24void s3c_i2c1_cfg_gpio(struct platform_device *dev) 24void s3c_i2c1_cfg_gpio(struct platform_device *dev)
25{ 25{
26 s3c_gpio_cfgpin(S5PV210_GPD1(2), S3C_GPIO_SFN(2)); 26 s3c_gpio_cfgall_range(S5PV210_GPD1(2), 2,
27 s3c_gpio_setpull(S5PV210_GPD1(2), S3C_GPIO_PULL_UP); 27 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
28 s3c_gpio_cfgpin(S5PV210_GPD1(3), S3C_GPIO_SFN(2));
29 s3c_gpio_setpull(S5PV210_GPD1(3), S3C_GPIO_PULL_UP);
30} 28}
diff --git a/arch/arm/mach-s5pv210/setup-i2c2.c b/arch/arm/mach-s5pv210/setup-i2c2.c
index 2396cb8c373e..2f91b5cefbc6 100644
--- a/arch/arm/mach-s5pv210/setup-i2c2.c
+++ b/arch/arm/mach-s5pv210/setup-i2c2.c
@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
23 23
24void s3c_i2c2_cfg_gpio(struct platform_device *dev) 24void s3c_i2c2_cfg_gpio(struct platform_device *dev)
25{ 25{
26 s3c_gpio_cfgpin(S5PV210_GPD1(4), S3C_GPIO_SFN(2)); 26 s3c_gpio_cfgall_range(S5PV210_GPD1(4), 2,
27 s3c_gpio_setpull(S5PV210_GPD1(4), S3C_GPIO_PULL_UP); 27 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
28 s3c_gpio_cfgpin(S5PV210_GPD1(5), S3C_GPIO_SFN(2));
29 s3c_gpio_setpull(S5PV210_GPD1(5), S3C_GPIO_PULL_UP);
30} 28}
diff --git a/arch/arm/mach-s5pv210/setup-ide.c b/arch/arm/mach-s5pv210/setup-ide.c
index b558b1cc8d60..ea123d546bd2 100644
--- a/arch/arm/mach-s5pv210/setup-ide.c
+++ b/arch/arm/mach-s5pv210/setup-ide.c
@@ -15,36 +15,25 @@
15 15
16#include <plat/gpio-cfg.h> 16#include <plat/gpio-cfg.h>
17 17
18static void s5pv210_ide_cfg_gpios(unsigned int base, unsigned int nr)
19{
20 s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(4));
21
22 for (; nr > 0; nr--, base++)
23 s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
24}
25
18void s5pv210_ide_setup_gpio(void) 26void s5pv210_ide_setup_gpio(void)
19{ 27{
20 unsigned int gpio = 0; 28 /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */
21 29 s5pv210_ide_cfg_gpios(S5PV210_GPJ0(0), 8);
22 for (gpio = S5PV210_GPJ0(0); gpio <= S5PV210_GPJ0(7); gpio++) { 30
23 /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, 31 /* CF_Data[0 - 7] */
24 CF_DMACK */ 32 s5pv210_ide_cfg_gpios(S5PV210_GPJ2(0), 8);
25 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4)); 33
26 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 34 /* CF_Data[8 - 15] */
27 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); 35 s5pv210_ide_cfg_gpios(S5PV210_GPJ3(0), 8);
28 } 36
29 37 /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
30 for (gpio = S5PV210_GPJ2(0); gpio <= S5PV210_GPJ2(7); gpio++) { 38 s5pv210_ide_cfg_gpios(S5PV210_GPJ4(0), 4);
31 /*CF_Data[0 - 7] */
32 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
33 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
34 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
35 }
36
37 for (gpio = S5PV210_GPJ3(0); gpio <= S5PV210_GPJ3(7); gpio++) {
38 /* CF_Data[8 - 15] */
39 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
40 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
41 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
42 }
43
44 for (gpio = S5PV210_GPJ4(0); gpio <= S5PV210_GPJ4(3); gpio++) {
45 /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
46 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
47 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
48 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
49 }
50} 39}
diff --git a/arch/arm/mach-s5pv210/setup-keypad.c b/arch/arm/mach-s5pv210/setup-keypad.c
index 37b2790aafc3..c56420a52f48 100644
--- a/arch/arm/mach-s5pv210/setup-keypad.c
+++ b/arch/arm/mach-s5pv210/setup-keypad.c
@@ -16,19 +16,9 @@
16 16
17void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) 17void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
18{ 18{
19 unsigned int gpio, end;
20
21 /* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */ 19 /* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */
22 end = S5PV210_GPH3(rows); 20 s3c_gpio_cfgrange_nopull(S5PV210_GPH3(0), rows, S3C_GPIO_SFN(3));
23 for (gpio = S5PV210_GPH3(0); gpio < end; gpio++) {
24 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
25 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
26 }
27 21
28 /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */ 22 /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
29 end = S5PV210_GPH2(cols); 23 s3c_gpio_cfgrange_nopull(S5PV210_GPH2(0), cols, S3C_GPIO_SFN(3));
30 for (gpio = S5PV210_GPH2(0); gpio < end; gpio++) {
31 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
32 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
33 }
34} 24}
diff --git a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
index b18587b1ec58..746777d56df9 100644
--- a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
@@ -26,26 +26,17 @@
26void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) 26void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
27{ 27{
28 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 28 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
29 unsigned int gpio;
30 29
31 /* Set all the necessary GPG0/GPG1 pins to special-function 2 */ 30 /* Set all the necessary GPG0/GPG1 pins to special-function 2 */
32 for (gpio = S5PV210_GPG0(0); gpio < S5PV210_GPG0(2); gpio++) { 31 s3c_gpio_cfgrange_nopull(S5PV210_GPG0(0), 2, S3C_GPIO_SFN(2));
33 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 32
34 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
35 }
36 switch (width) { 33 switch (width) {
37 case 8: 34 case 8:
38 /* GPG1[3:6] special-funtion 3 */ 35 /* GPG1[3:6] special-funtion 3 */
39 for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) { 36 s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(3));
40 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
41 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
42 }
43 case 4: 37 case 4:
44 /* GPG0[3:6] special-funtion 2 */ 38 /* GPG0[3:6] special-funtion 2 */
45 for (gpio = S5PV210_GPG0(3); gpio <= S5PV210_GPG0(6); gpio++) { 39 s3c_gpio_cfgrange_nopull(S5PV210_GPG0(3), 4, S3C_GPIO_SFN(2));
46 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
47 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
48 }
49 default: 40 default:
50 break; 41 break;
51 } 42 }
@@ -59,19 +50,12 @@ void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
59void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) 50void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
60{ 51{
61 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 52 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
62 unsigned int gpio;
63 53
64 /* Set all the necessary GPG1[0:1] pins to special-function 2 */ 54 /* Set all the necessary GPG1[0:1] pins to special-function 2 */
65 for (gpio = S5PV210_GPG1(0); gpio < S5PV210_GPG1(2); gpio++) { 55 s3c_gpio_cfgrange_nopull(S5PV210_GPG1(0), 2, S3C_GPIO_SFN(2));
66 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
67 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
68 }
69 56
70 /* Data pin GPG1[3:6] to special-function 2 */ 57 /* Data pin GPG1[3:6] to special-function 2 */
71 for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) { 58 s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(2));
72 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
73 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
74 }
75 59
76 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 60 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
77 s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP); 61 s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
@@ -82,27 +66,17 @@ void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
82void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) 66void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
83{ 67{
84 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 68 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
85 unsigned int gpio;
86 69
87 /* Set all the necessary GPG2[0:1] pins to special-function 2 */ 70 /* Set all the necessary GPG2[0:1] pins to special-function 2 */
88 for (gpio = S5PV210_GPG2(0); gpio < S5PV210_GPG2(2); gpio++) { 71 s3c_gpio_cfgrange_nopull(S5PV210_GPG2(0), 2, S3C_GPIO_SFN(2));
89 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
90 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
91 }
92 72
93 switch (width) { 73 switch (width) {
94 case 8: 74 case 8:
95 /* Data pin GPG3[3:6] to special-function 3 */ 75 /* Data pin GPG3[3:6] to special-function 3 */
96 for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) { 76 s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(3));
97 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
98 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
99 }
100 case 4: 77 case 4:
101 /* Data pin GPG2[3:6] to special-function 2 */ 78 /* Data pin GPG2[3:6] to special-function 2 */
102 for (gpio = S5PV210_GPG2(3); gpio <= S5PV210_GPG2(6); gpio++) { 79 s3c_gpio_cfgrange_nopull(S5PV210_GPG2(3), 4, S3C_GPIO_SFN(2));
103 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
104 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
105 }
106 default: 80 default:
107 break; 81 break;
108 } 82 }
@@ -116,19 +90,12 @@ void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
116void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width) 90void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
117{ 91{
118 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 92 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
119 unsigned int gpio;
120 93
121 /* Set all the necessary GPG3[0:2] pins to special-function 2 */ 94 /* Set all the necessary GPG3[0:1] pins to special-function 2 */
122 for (gpio = S5PV210_GPG3(0); gpio < S5PV210_GPG3(2); gpio++) { 95 s3c_gpio_cfgrange_nopull(S5PV210_GPG3(0), 2, S3C_GPIO_SFN(2));
123 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
124 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
125 }
126 96
127 /* Data pin GPG3[3:6] to special-function 2 */ 97 /* Data pin GPG3[3:6] to special-function 2 */
128 for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) { 98 s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(2));
129 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
130 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
131 }
132 99
133 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 100 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
134 s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP); 101 s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP);
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
new file mode 100644
index 000000000000..d4d222b716b4
--- /dev/null
+++ b/arch/arm/mach-s5pv210/sleep.S
@@ -0,0 +1,170 @@
1/* linux/arch/arm/plat-s5p/sleep.S
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV210 power Manager (Suspend-To-RAM) support
7 * Based on S3C2410 sleep code by:
8 * Ben Dooks, (c) 2004 Simtec Electronics
9 *
10 * Based on PXA/SA1100 sleep code by:
11 * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
12 * Cliff Brake, (c) 2001
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27*/
28
29#include <linux/linkage.h>
30#include <asm/assembler.h>
31#include <asm/memory.h>
32
33 .text
34
35 /* s3c_cpu_save
36 *
37 * entry:
38 * r0 = save address (virtual addr of s3c_sleep_save_phys)
39 */
40
41ENTRY(s3c_cpu_save)
42
43 stmfd sp!, { r3 - r12, lr }
44
45 mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
46 mrc p15, 0, r5, c3, c0, 0 @ Domain ID
47 mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
48 mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
49 mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control
50 mrc p15, 0, r9, c1, c0, 0 @ Control register
51 mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
52 mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls
53 mrc p15, 0, r12, c10, c2, 0 @ Read PRRR
54 mrc p15, 0, r3, c10, c2, 1 @ READ NMRR
55
56 stmia r0, { r3 - r13 }
57
58 bl s3c_pm_cb_flushcache
59
60 ldr r0, =pm_cpu_sleep
61 ldr r0, [ r0 ]
62 mov pc, r0
63
64resume_with_mmu:
65 /*
66 * After MMU is turned on, restore the previous MMU table.
67 */
68 ldr r9 , =(PAGE_OFFSET - PHYS_OFFSET)
69 add r4, r4, r9
70 str r12, [r4]
71
72 ldmfd sp!, { r3 - r12, pc }
73
74 .ltorg
75
76 .data
77
78 .global s3c_sleep_save_phys
79s3c_sleep_save_phys:
80 .word 0
81
82 /* sleep magic, to allow the bootloader to check for an valid
83 * image to resume to. Must be the first word before the
84 * s3c_cpu_resume entry.
85 */
86
87 .word 0x2bedf00d
88
89 /* s3c_cpu_resume
90 *
91 * resume code entry for bootloader to call
92 *
93 * we must put this code here in the data segment as we have no
94 * other way of restoring the stack pointer after sleep, and we
95 * must not write to the code segment (code is read-only)
96 */
97
98ENTRY(s3c_cpu_resume)
99 mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
100 msr cpsr_c, r0
101
102 mov r1, #0
103 mcr p15, 0, r1, c8, c7, 0 @ invalidate TLBs
104 mcr p15, 0, r1, c7, c5, 0 @ invalidate I Cache
105
106 ldr r0, s3c_sleep_save_phys @ address of restore block
107 ldmia r0, { r3 - r13 }
108
109 mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
110 mcr p15, 0, r5, c3, c0, 0 @ Domain ID
111
112 mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control
113 mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
114 mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
115
116 mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
117
118 mov r0, #0
119 mcr p15, 0, r0, c8, c7, 0 @ Invalidate I & D TLB
120
121 mov r0, #0 @ restore copro access
122 mcr p15, 0, r11, c1, c0, 2 @ Co-processor access
123 mcr p15, 0, r0, c7, c5, 4
124
125 mcr p15, 0, r12, c10, c2, 0 @ write PRRR
126 mcr p15, 0, r3, c10, c2, 1 @ write NMRR
127
128 /*
129 * In Cortex-A8, when MMU is turned on, the pipeline is flushed.
130 * And there are no valid entries in the MMU table at this point.
131 * So before turning on the MMU, the MMU entry for the DRAM address
132 * range is added. After the MMU is turned on, the other entries
133 * in the MMU table will be restored.
134 */
135
136 /* r6 = Translation Table BASE0 */
137 mov r4, r6
138 mov r4, r4, LSR #14
139 mov r4, r4, LSL #14
140
141 /* Load address for adding to MMU table list */
142 ldr r11, =0xE010F000 @ INFORM0 reg.
143 ldr r10, [r11, #0]
144 mov r10, r10, LSR #18
145 bic r10, r10, #0x3
146 orr r4, r4, r10
147
148 /* Calculate MMU table entry */
149 mov r10, r10, LSL #18
150 ldr r5, =0x40E
151 orr r10, r10, r5
152
153 /* Back up originally data */
154 ldr r12, [r4]
155
156 /* Add calculated MMU table entry into MMU table list */
157 str r10, [r4]
158
159 ldr r2, =resume_with_mmu
160 mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc
161
162 nop
163 nop
164 nop
165 nop
166 nop @ second-to-last before mmu
167
168 mov pc, r2 @ go back to virtual address
169
170 .ltorg
diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig
index 331b5bd97aba..1150b360f38c 100644
--- a/arch/arm/mach-s5pv310/Kconfig
+++ b/arch/arm/mach-s5pv310/Kconfig
@@ -11,7 +11,6 @@ if ARCH_S5PV310
11 11
12config CPU_S5PV310 12config CPU_S5PV310
13 bool 13 bool
14 select PLAT_S5P
15 help 14 help
16 Enable S5PV310 CPU support 15 Enable S5PV310 CPU support
17 16
@@ -25,21 +24,105 @@ config S5PV310_SETUP_I2C2
25 help 24 help
26 Common setup code for i2c bus 2. 25 Common setup code for i2c bus 2.
27 26
27config S5PV310_SETUP_I2C3
28 bool
29 help
30 Common setup code for i2c bus 3.
31
32config S5PV310_SETUP_I2C4
33 bool
34 help
35 Common setup code for i2c bus 4.
36
37config S5PV310_SETUP_I2C5
38 bool
39 help
40 Common setup code for i2c bus 5.
41
42config S5PV310_SETUP_I2C6
43 bool
44 help
45 Common setup code for i2c bus 6.
46
47config S5PV310_SETUP_I2C7
48 bool
49 help
50 Common setup code for i2c bus 7.
51
52config S5PV310_SETUP_SDHCI
53 bool
54 select S5PV310_SETUP_SDHCI_GPIO
55 help
56 Internal helper functions for S5PV310 based SDHCI systems.
57
58config S5PV310_SETUP_SDHCI_GPIO
59 bool
60 help
61 Common setup code for SDHCI gpio.
62
28# machine support 63# machine support
29 64
30config MACH_SMDKV310 65menu "S5PC210 Machines"
31 bool "SMDKV310" 66
67config MACH_SMDKC210
68 bool "SMDKC210"
32 select CPU_S5PV310 69 select CPU_S5PV310
33 select ARCH_SPARSEMEM_ENABLE 70 select S3C_DEV_RTC
71 select S3C_DEV_WDT
72 select S3C_DEV_HSMMC
73 select S3C_DEV_HSMMC1
74 select S3C_DEV_HSMMC2
75 select S3C_DEV_HSMMC3
76 select S5PV310_SETUP_SDHCI
34 help 77 help
35 Machine support for Samsung SMDKV310 78 Machine support for Samsung SMDKC210
79 S5PC210(MCP) is one of package option of S5PV310
36 80
37config MACH_UNIVERSAL_C210 81config MACH_UNIVERSAL_C210
38 bool "Mobile UNIVERSAL_C210 Board" 82 bool "Mobile UNIVERSAL_C210 Board"
39 select CPU_S5PV310 83 select CPU_S5PV310
40 select ARCH_SPARSEMEM_ENABLE 84 select S5P_DEV_ONENAND
85 select S3C_DEV_I2C1
86 select S5PV310_SETUP_I2C1
41 help 87 help
42 Machine support for Samsung Mobile Universal S5PC210 Reference 88 Machine support for Samsung Mobile Universal S5PC210 Reference
43 Board. S5PC210(MCP) is one of package option of S5PV310 89 Board. S5PC210(MCP) is one of package option of S5PV310
44 90
91endmenu
92
93menu "S5PV310 Machines"
94
95config MACH_SMDKV310
96 bool "SMDKV310"
97 select CPU_S5PV310
98 select S3C_DEV_RTC
99 select S3C_DEV_WDT
100 select S3C_DEV_HSMMC
101 select S3C_DEV_HSMMC1
102 select S3C_DEV_HSMMC2
103 select S3C_DEV_HSMMC3
104 select S5PV310_SETUP_SDHCI
105 help
106 Machine support for Samsung SMDKV310
107
108endmenu
109
110comment "Configuration for HSMMC bus width"
111
112menu "Use 8-bit bus width"
113
114config S5PV310_SDHCI_CH0_8BIT
115 bool "Channel 0 with 8-bit bus"
116 help
117 Support HSMMC Channel 0 8-bit bus.
118 If selected, Channel 1 is disabled.
119
120config S5PV310_SDHCI_CH2_8BIT
121 bool "Channel 2 with 8-bit bus"
122 help
123 Support HSMMC Channel 2 8-bit bus.
124 If selected, Channel 3 is disabled.
125
126endmenu
127
45endif 128endif
diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile
index d5b51c72340f..84afc64e7c01 100644
--- a/arch/arm/mach-s5pv310/Makefile
+++ b/arch/arm/mach-s5pv310/Makefile
@@ -13,7 +13,7 @@ obj- :=
13# Core support for S5PV310 system 13# Core support for S5PV310 system
14 14
15obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o 15obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o
16obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o 16obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o
17 17
18obj-$(CONFIG_SMP) += platsmp.o headsmp.o 18obj-$(CONFIG_SMP) += platsmp.o headsmp.o
19obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o 19obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
@@ -21,6 +21,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
21 21
22# machine support 22# machine support
23 23
24obj-$(CONFIG_MACH_SMDKC210) += mach-smdkc210.o
24obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o 25obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o
25obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o 26obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
26 27
@@ -28,3 +29,10 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
28 29
29obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o 30obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o
30obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o 31obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o
32obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o
33obj-$(CONFIG_S5PV310_SETUP_I2C4) += setup-i2c4.o
34obj-$(CONFIG_S5PV310_SETUP_I2C5) += setup-i2c5.o
35obj-$(CONFIG_S5PV310_SETUP_I2C6) += setup-i2c6.o
36obj-$(CONFIG_S5PV310_SETUP_I2C7) += setup-i2c7.o
37obj-$(CONFIG_S5PV310_SETUP_SDHCI) += setup-sdhci.o
38obj-$(CONFIG_S5PV310_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c
index 26a0f03df8ea..58c9d33f36fe 100644
--- a/arch/arm/mach-s5pv310/clock.c
+++ b/arch/arm/mach-s5pv310/clock.c
@@ -30,16 +30,92 @@ static struct clk clk_sclk_hdmi27m = {
30 .rate = 27000000, 30 .rate = 27000000,
31}; 31};
32 32
33static struct clk clk_sclk_hdmiphy = {
34 .name = "sclk_hdmiphy",
35 .id = -1,
36};
37
38static struct clk clk_sclk_usbphy0 = {
39 .name = "sclk_usbphy0",
40 .id = -1,
41 .rate = 27000000,
42};
43
44static struct clk clk_sclk_usbphy1 = {
45 .name = "sclk_usbphy1",
46 .id = -1,
47};
48
49static int s5pv310_clksrc_mask_top_ctrl(struct clk *clk, int enable)
50{
51 return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
52}
53
54static int s5pv310_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
55{
56 return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
57}
58
59static int s5pv310_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
60{
61 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
62}
63
64static int s5pv310_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
65{
66 return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
67}
68
69static int s5pv310_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
70{
71 return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
72}
73
33static int s5pv310_clksrc_mask_peril0_ctrl(struct clk *clk, int enable) 74static int s5pv310_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
34{ 75{
35 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable); 76 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
36} 77}
37 78
79static int s5pv310_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
80{
81 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
82}
83
84static int s5pv310_clk_ip_cam_ctrl(struct clk *clk, int enable)
85{
86 return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
87}
88
89static int s5pv310_clk_ip_image_ctrl(struct clk *clk, int enable)
90{
91 return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
92}
93
94static int s5pv310_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
95{
96 return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
97}
98
99static int s5pv310_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
100{
101 return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
102}
103
104static int s5pv310_clk_ip_fsys_ctrl(struct clk *clk, int enable)
105{
106 return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
107}
108
38static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable) 109static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable)
39{ 110{
40 return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable); 111 return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
41} 112}
42 113
114static int s5pv310_clk_ip_perir_ctrl(struct clk *clk, int enable)
115{
116 return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
117}
118
43/* Core list of CMU_CPU side */ 119/* Core list of CMU_CPU side */
44 120
45static struct clksrc_clk clk_mout_apll = { 121static struct clksrc_clk clk_mout_apll = {
@@ -79,7 +155,7 @@ static struct clksrc_clk clk_mout_mpll = {
79}; 155};
80 156
81static struct clk *clkset_moutcore_list[] = { 157static struct clk *clkset_moutcore_list[] = {
82 [0] = &clk_sclk_apll.clk, 158 [0] = &clk_mout_apll.clk,
83 [1] = &clk_mout_mpll.clk, 159 [1] = &clk_mout_mpll.clk,
84}; 160};
85 161
@@ -150,24 +226,6 @@ static struct clksrc_clk clk_periphclk = {
150 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 }, 226 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
151}; 227};
152 228
153static struct clksrc_clk clk_atclk = {
154 .clk = {
155 .name = "atclk",
156 .id = -1,
157 .parent = &clk_moutcore.clk,
158 },
159 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 16, .size = 3 },
160};
161
162static struct clksrc_clk clk_pclk_dbg = {
163 .clk = {
164 .name = "pclk_dbg",
165 .id = -1,
166 .parent = &clk_atclk.clk,
167 },
168 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 20, .size = 3 },
169};
170
171/* Core list of CMU_CORE side */ 229/* Core list of CMU_CORE side */
172 230
173static struct clk *clkset_corebus_list[] = { 231static struct clk *clkset_corebus_list[] = {
@@ -241,7 +299,7 @@ static struct clk *clkset_aclk_top_list[] = {
241 [1] = &clk_sclk_apll.clk, 299 [1] = &clk_sclk_apll.clk,
242}; 300};
243 301
244static struct clksrc_sources clkset_aclk_200 = { 302static struct clksrc_sources clkset_aclk = {
245 .sources = clkset_aclk_top_list, 303 .sources = clkset_aclk_top_list,
246 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list), 304 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
247}; 305};
@@ -251,52 +309,37 @@ static struct clksrc_clk clk_aclk_200 = {
251 .name = "aclk_200", 309 .name = "aclk_200",
252 .id = -1, 310 .id = -1,
253 }, 311 },
254 .sources = &clkset_aclk_200, 312 .sources = &clkset_aclk,
255 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 }, 313 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
256 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 }, 314 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
257}; 315};
258 316
259static struct clksrc_sources clkset_aclk_100 = {
260 .sources = clkset_aclk_top_list,
261 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
262};
263
264static struct clksrc_clk clk_aclk_100 = { 317static struct clksrc_clk clk_aclk_100 = {
265 .clk = { 318 .clk = {
266 .name = "aclk_100", 319 .name = "aclk_100",
267 .id = -1, 320 .id = -1,
268 }, 321 },
269 .sources = &clkset_aclk_100, 322 .sources = &clkset_aclk,
270 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 }, 323 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
271 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 }, 324 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
272}; 325};
273 326
274static struct clksrc_sources clkset_aclk_160 = {
275 .sources = clkset_aclk_top_list,
276 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
277};
278
279static struct clksrc_clk clk_aclk_160 = { 327static struct clksrc_clk clk_aclk_160 = {
280 .clk = { 328 .clk = {
281 .name = "aclk_160", 329 .name = "aclk_160",
282 .id = -1, 330 .id = -1,
283 }, 331 },
284 .sources = &clkset_aclk_160, 332 .sources = &clkset_aclk,
285 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 }, 333 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
286 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 }, 334 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
287}; 335};
288 336
289static struct clksrc_sources clkset_aclk_133 = {
290 .sources = clkset_aclk_top_list,
291 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
292};
293
294static struct clksrc_clk clk_aclk_133 = { 337static struct clksrc_clk clk_aclk_133 = {
295 .clk = { 338 .clk = {
296 .name = "aclk_133", 339 .name = "aclk_133",
297 .id = -1, 340 .id = -1,
298 }, 341 },
299 .sources = &clkset_aclk_133, 342 .sources = &clkset_aclk,
300 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 }, 343 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
301 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 }, 344 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
302}; 345};
@@ -315,6 +358,8 @@ static struct clksrc_clk clk_vpllsrc = {
315 .clk = { 358 .clk = {
316 .name = "vpll_src", 359 .name = "vpll_src",
317 .id = -1, 360 .id = -1,
361 .enable = s5pv310_clksrc_mask_top_ctrl,
362 .ctrlbit = (1 << 0),
318 }, 363 },
319 .sources = &clkset_vpllsrc, 364 .sources = &clkset_vpllsrc,
320 .reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 }, 365 .reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
@@ -346,7 +391,175 @@ static struct clk init_clocks_disable[] = {
346 .parent = &clk_aclk_100.clk, 391 .parent = &clk_aclk_100.clk,
347 .enable = s5pv310_clk_ip_peril_ctrl, 392 .enable = s5pv310_clk_ip_peril_ctrl,
348 .ctrlbit = (1<<24), 393 .ctrlbit = (1<<24),
349 } 394 }, {
395 .name = "csis",
396 .id = 0,
397 .enable = s5pv310_clk_ip_cam_ctrl,
398 .ctrlbit = (1 << 4),
399 }, {
400 .name = "csis",
401 .id = 1,
402 .enable = s5pv310_clk_ip_cam_ctrl,
403 .ctrlbit = (1 << 5),
404 }, {
405 .name = "fimc",
406 .id = 0,
407 .enable = s5pv310_clk_ip_cam_ctrl,
408 .ctrlbit = (1 << 0),
409 }, {
410 .name = "fimc",
411 .id = 1,
412 .enable = s5pv310_clk_ip_cam_ctrl,
413 .ctrlbit = (1 << 1),
414 }, {
415 .name = "fimc",
416 .id = 2,
417 .enable = s5pv310_clk_ip_cam_ctrl,
418 .ctrlbit = (1 << 2),
419 }, {
420 .name = "fimc",
421 .id = 3,
422 .enable = s5pv310_clk_ip_cam_ctrl,
423 .ctrlbit = (1 << 3),
424 }, {
425 .name = "fimd",
426 .id = 0,
427 .enable = s5pv310_clk_ip_lcd0_ctrl,
428 .ctrlbit = (1 << 0),
429 }, {
430 .name = "fimd",
431 .id = 1,
432 .enable = s5pv310_clk_ip_lcd1_ctrl,
433 .ctrlbit = (1 << 0),
434 }, {
435 .name = "hsmmc",
436 .id = 0,
437 .parent = &clk_aclk_133.clk,
438 .enable = s5pv310_clk_ip_fsys_ctrl,
439 .ctrlbit = (1 << 5),
440 }, {
441 .name = "hsmmc",
442 .id = 1,
443 .parent = &clk_aclk_133.clk,
444 .enable = s5pv310_clk_ip_fsys_ctrl,
445 .ctrlbit = (1 << 6),
446 }, {
447 .name = "hsmmc",
448 .id = 2,
449 .parent = &clk_aclk_133.clk,
450 .enable = s5pv310_clk_ip_fsys_ctrl,
451 .ctrlbit = (1 << 7),
452 }, {
453 .name = "hsmmc",
454 .id = 3,
455 .parent = &clk_aclk_133.clk,
456 .enable = s5pv310_clk_ip_fsys_ctrl,
457 .ctrlbit = (1 << 8),
458 }, {
459 .name = "hsmmc",
460 .id = 4,
461 .parent = &clk_aclk_133.clk,
462 .enable = s5pv310_clk_ip_fsys_ctrl,
463 .ctrlbit = (1 << 9),
464 }, {
465 .name = "sata",
466 .id = -1,
467 .enable = s5pv310_clk_ip_fsys_ctrl,
468 .ctrlbit = (1 << 10),
469 }, {
470 .name = "adc",
471 .id = -1,
472 .enable = s5pv310_clk_ip_peril_ctrl,
473 .ctrlbit = (1 << 15),
474 }, {
475 .name = "rtc",
476 .id = -1,
477 .enable = s5pv310_clk_ip_perir_ctrl,
478 .ctrlbit = (1 << 15),
479 }, {
480 .name = "watchdog",
481 .id = -1,
482 .enable = s5pv310_clk_ip_perir_ctrl,
483 .ctrlbit = (1 << 14),
484 }, {
485 .name = "usbhost",
486 .id = -1,
487 .enable = s5pv310_clk_ip_fsys_ctrl ,
488 .ctrlbit = (1 << 12),
489 }, {
490 .name = "otg",
491 .id = -1,
492 .enable = s5pv310_clk_ip_fsys_ctrl,
493 .ctrlbit = (1 << 13),
494 }, {
495 .name = "spi",
496 .id = 0,
497 .enable = s5pv310_clk_ip_peril_ctrl,
498 .ctrlbit = (1 << 16),
499 }, {
500 .name = "spi",
501 .id = 1,
502 .enable = s5pv310_clk_ip_peril_ctrl,
503 .ctrlbit = (1 << 17),
504 }, {
505 .name = "spi",
506 .id = 2,
507 .enable = s5pv310_clk_ip_peril_ctrl,
508 .ctrlbit = (1 << 18),
509 }, {
510 .name = "fimg2d",
511 .id = -1,
512 .enable = s5pv310_clk_ip_image_ctrl,
513 .ctrlbit = (1 << 0),
514 }, {
515 .name = "i2c",
516 .id = 0,
517 .parent = &clk_aclk_100.clk,
518 .enable = s5pv310_clk_ip_peril_ctrl,
519 .ctrlbit = (1 << 6),
520 }, {
521 .name = "i2c",
522 .id = 1,
523 .parent = &clk_aclk_100.clk,
524 .enable = s5pv310_clk_ip_peril_ctrl,
525 .ctrlbit = (1 << 7),
526 }, {
527 .name = "i2c",
528 .id = 2,
529 .parent = &clk_aclk_100.clk,
530 .enable = s5pv310_clk_ip_peril_ctrl,
531 .ctrlbit = (1 << 8),
532 }, {
533 .name = "i2c",
534 .id = 3,
535 .parent = &clk_aclk_100.clk,
536 .enable = s5pv310_clk_ip_peril_ctrl,
537 .ctrlbit = (1 << 9),
538 }, {
539 .name = "i2c",
540 .id = 4,
541 .parent = &clk_aclk_100.clk,
542 .enable = s5pv310_clk_ip_peril_ctrl,
543 .ctrlbit = (1 << 10),
544 }, {
545 .name = "i2c",
546 .id = 5,
547 .parent = &clk_aclk_100.clk,
548 .enable = s5pv310_clk_ip_peril_ctrl,
549 .ctrlbit = (1 << 11),
550 }, {
551 .name = "i2c",
552 .id = 6,
553 .parent = &clk_aclk_100.clk,
554 .enable = s5pv310_clk_ip_peril_ctrl,
555 .ctrlbit = (1 << 12),
556 }, {
557 .name = "i2c",
558 .id = 7,
559 .parent = &clk_aclk_100.clk,
560 .enable = s5pv310_clk_ip_peril_ctrl,
561 .ctrlbit = (1 << 13),
562 },
350}; 563};
351 564
352static struct clk init_clocks[] = { 565static struct clk init_clocks[] = {
@@ -387,6 +600,9 @@ static struct clk *clkset_group_list[] = {
387 [0] = &clk_ext_xtal_mux, 600 [0] = &clk_ext_xtal_mux,
388 [1] = &clk_xusbxti, 601 [1] = &clk_xusbxti,
389 [2] = &clk_sclk_hdmi27m, 602 [2] = &clk_sclk_hdmi27m,
603 [3] = &clk_sclk_usbphy0,
604 [4] = &clk_sclk_usbphy1,
605 [5] = &clk_sclk_hdmiphy,
390 [6] = &clk_mout_mpll.clk, 606 [6] = &clk_mout_mpll.clk,
391 [7] = &clk_mout_epll.clk, 607 [7] = &clk_mout_epll.clk,
392 [8] = &clk_sclk_vpll.clk, 608 [8] = &clk_sclk_vpll.clk,
@@ -397,6 +613,104 @@ static struct clksrc_sources clkset_group = {
397 .nr_sources = ARRAY_SIZE(clkset_group_list), 613 .nr_sources = ARRAY_SIZE(clkset_group_list),
398}; 614};
399 615
616static struct clk *clkset_mout_g2d0_list[] = {
617 [0] = &clk_mout_mpll.clk,
618 [1] = &clk_sclk_apll.clk,
619};
620
621static struct clksrc_sources clkset_mout_g2d0 = {
622 .sources = clkset_mout_g2d0_list,
623 .nr_sources = ARRAY_SIZE(clkset_mout_g2d0_list),
624};
625
626static struct clksrc_clk clk_mout_g2d0 = {
627 .clk = {
628 .name = "mout_g2d0",
629 .id = -1,
630 },
631 .sources = &clkset_mout_g2d0,
632 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
633};
634
635static struct clk *clkset_mout_g2d1_list[] = {
636 [0] = &clk_mout_epll.clk,
637 [1] = &clk_sclk_vpll.clk,
638};
639
640static struct clksrc_sources clkset_mout_g2d1 = {
641 .sources = clkset_mout_g2d1_list,
642 .nr_sources = ARRAY_SIZE(clkset_mout_g2d1_list),
643};
644
645static struct clksrc_clk clk_mout_g2d1 = {
646 .clk = {
647 .name = "mout_g2d1",
648 .id = -1,
649 },
650 .sources = &clkset_mout_g2d1,
651 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
652};
653
654static struct clk *clkset_mout_g2d_list[] = {
655 [0] = &clk_mout_g2d0.clk,
656 [1] = &clk_mout_g2d1.clk,
657};
658
659static struct clksrc_sources clkset_mout_g2d = {
660 .sources = clkset_mout_g2d_list,
661 .nr_sources = ARRAY_SIZE(clkset_mout_g2d_list),
662};
663
664static struct clksrc_clk clk_dout_mmc0 = {
665 .clk = {
666 .name = "dout_mmc0",
667 .id = -1,
668 },
669 .sources = &clkset_group,
670 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
671 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
672};
673
674static struct clksrc_clk clk_dout_mmc1 = {
675 .clk = {
676 .name = "dout_mmc1",
677 .id = -1,
678 },
679 .sources = &clkset_group,
680 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
681 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
682};
683
684static struct clksrc_clk clk_dout_mmc2 = {
685 .clk = {
686 .name = "dout_mmc2",
687 .id = -1,
688 },
689 .sources = &clkset_group,
690 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
691 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
692};
693
694static struct clksrc_clk clk_dout_mmc3 = {
695 .clk = {
696 .name = "dout_mmc3",
697 .id = -1,
698 },
699 .sources = &clkset_group,
700 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
701 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
702};
703
704static struct clksrc_clk clk_dout_mmc4 = {
705 .clk = {
706 .name = "dout_mmc4",
707 .id = -1,
708 },
709 .sources = &clkset_group,
710 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
711 .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
712};
713
400static struct clksrc_clk clksrcs[] = { 714static struct clksrc_clk clksrcs[] = {
401 { 715 {
402 .clk = { 716 .clk = {
@@ -448,7 +762,200 @@ static struct clksrc_clk clksrcs[] = {
448 .sources = &clkset_group, 762 .sources = &clkset_group,
449 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 }, 763 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
450 .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 }, 764 .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
451 }, 765 }, {
766 .clk = {
767 .name = "sclk_csis",
768 .id = 0,
769 .enable = s5pv310_clksrc_mask_cam_ctrl,
770 .ctrlbit = (1 << 24),
771 },
772 .sources = &clkset_group,
773 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
774 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
775 }, {
776 .clk = {
777 .name = "sclk_csis",
778 .id = 1,
779 .enable = s5pv310_clksrc_mask_cam_ctrl,
780 .ctrlbit = (1 << 28),
781 },
782 .sources = &clkset_group,
783 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
784 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
785 }, {
786 .clk = {
787 .name = "sclk_cam",
788 .id = 0,
789 .enable = s5pv310_clksrc_mask_cam_ctrl,
790 .ctrlbit = (1 << 16),
791 },
792 .sources = &clkset_group,
793 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
794 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
795 }, {
796 .clk = {
797 .name = "sclk_cam",
798 .id = 1,
799 .enable = s5pv310_clksrc_mask_cam_ctrl,
800 .ctrlbit = (1 << 20),
801 },
802 .sources = &clkset_group,
803 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
804 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
805 }, {
806 .clk = {
807 .name = "sclk_fimc",
808 .id = 0,
809 .enable = s5pv310_clksrc_mask_cam_ctrl,
810 .ctrlbit = (1 << 0),
811 },
812 .sources = &clkset_group,
813 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
814 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
815 }, {
816 .clk = {
817 .name = "sclk_fimc",
818 .id = 1,
819 .enable = s5pv310_clksrc_mask_cam_ctrl,
820 .ctrlbit = (1 << 4),
821 },
822 .sources = &clkset_group,
823 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
824 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
825 }, {
826 .clk = {
827 .name = "sclk_fimc",
828 .id = 2,
829 .enable = s5pv310_clksrc_mask_cam_ctrl,
830 .ctrlbit = (1 << 8),
831 },
832 .sources = &clkset_group,
833 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
834 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
835 }, {
836 .clk = {
837 .name = "sclk_fimc",
838 .id = 3,
839 .enable = s5pv310_clksrc_mask_cam_ctrl,
840 .ctrlbit = (1 << 12),
841 },
842 .sources = &clkset_group,
843 .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
844 .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
845 }, {
846 .clk = {
847 .name = "sclk_fimd",
848 .id = 0,
849 .enable = s5pv310_clksrc_mask_lcd0_ctrl,
850 .ctrlbit = (1 << 0),
851 },
852 .sources = &clkset_group,
853 .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
854 .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
855 }, {
856 .clk = {
857 .name = "sclk_fimd",
858 .id = 1,
859 .enable = s5pv310_clksrc_mask_lcd1_ctrl,
860 .ctrlbit = (1 << 0),
861 },
862 .sources = &clkset_group,
863 .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
864 .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
865 }, {
866 .clk = {
867 .name = "sclk_sata",
868 .id = -1,
869 .enable = s5pv310_clksrc_mask_fsys_ctrl,
870 .ctrlbit = (1 << 24),
871 },
872 .sources = &clkset_mout_corebus,
873 .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
874 .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
875 }, {
876 .clk = {
877 .name = "sclk_spi",
878 .id = 0,
879 .enable = s5pv310_clksrc_mask_peril1_ctrl,
880 .ctrlbit = (1 << 16),
881 },
882 .sources = &clkset_group,
883 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
884 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
885 }, {
886 .clk = {
887 .name = "sclk_spi",
888 .id = 1,
889 .enable = s5pv310_clksrc_mask_peril1_ctrl,
890 .ctrlbit = (1 << 20),
891 },
892 .sources = &clkset_group,
893 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
894 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
895 }, {
896 .clk = {
897 .name = "sclk_spi",
898 .id = 2,
899 .enable = s5pv310_clksrc_mask_peril1_ctrl,
900 .ctrlbit = (1 << 24),
901 },
902 .sources = &clkset_group,
903 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
904 .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
905 }, {
906 .clk = {
907 .name = "sclk_fimg2d",
908 .id = -1,
909 },
910 .sources = &clkset_mout_g2d,
911 .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
912 .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
913 }, {
914 .clk = {
915 .name = "sclk_mmc",
916 .id = 0,
917 .parent = &clk_dout_mmc0.clk,
918 .enable = s5pv310_clksrc_mask_fsys_ctrl,
919 .ctrlbit = (1 << 0),
920 },
921 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
922 }, {
923 .clk = {
924 .name = "sclk_mmc",
925 .id = 1,
926 .parent = &clk_dout_mmc1.clk,
927 .enable = s5pv310_clksrc_mask_fsys_ctrl,
928 .ctrlbit = (1 << 4),
929 },
930 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
931 }, {
932 .clk = {
933 .name = "sclk_mmc",
934 .id = 2,
935 .parent = &clk_dout_mmc2.clk,
936 .enable = s5pv310_clksrc_mask_fsys_ctrl,
937 .ctrlbit = (1 << 8),
938 },
939 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
940 }, {
941 .clk = {
942 .name = "sclk_mmc",
943 .id = 3,
944 .parent = &clk_dout_mmc3.clk,
945 .enable = s5pv310_clksrc_mask_fsys_ctrl,
946 .ctrlbit = (1 << 12),
947 },
948 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
949 }, {
950 .clk = {
951 .name = "sclk_mmc",
952 .id = 4,
953 .parent = &clk_dout_mmc4.clk,
954 .enable = s5pv310_clksrc_mask_fsys_ctrl,
955 .ctrlbit = (1 << 16),
956 },
957 .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
958 }
452}; 959};
453 960
454/* Clock initialization code */ 961/* Clock initialization code */
@@ -464,8 +971,6 @@ static struct clksrc_clk *sysclks[] = {
464 &clk_aclk_cores, 971 &clk_aclk_cores,
465 &clk_aclk_corem1, 972 &clk_aclk_corem1,
466 &clk_periphclk, 973 &clk_periphclk,
467 &clk_atclk,
468 &clk_pclk_dbg,
469 &clk_mout_corebus, 974 &clk_mout_corebus,
470 &clk_sclk_dmc, 975 &clk_sclk_dmc,
471 &clk_aclk_cored, 976 &clk_aclk_cored,
@@ -478,6 +983,11 @@ static struct clksrc_clk *sysclks[] = {
478 &clk_aclk_100, 983 &clk_aclk_100,
479 &clk_aclk_160, 984 &clk_aclk_160,
480 &clk_aclk_133, 985 &clk_aclk_133,
986 &clk_dout_mmc0,
987 &clk_dout_mmc1,
988 &clk_dout_mmc2,
989 &clk_dout_mmc3,
990 &clk_dout_mmc4,
481}; 991};
482 992
483void __init_or_cpufreq s5pv310_setup_clocks(void) 993void __init_or_cpufreq s5pv310_setup_clocks(void)
@@ -490,15 +1000,11 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
490 unsigned long vpllsrc; 1000 unsigned long vpllsrc;
491 unsigned long xtal; 1001 unsigned long xtal;
492 unsigned long armclk; 1002 unsigned long armclk;
493 unsigned long aclk_corem0;
494 unsigned long aclk_cores;
495 unsigned long aclk_corem1;
496 unsigned long periphclk;
497 unsigned long sclk_dmc; 1003 unsigned long sclk_dmc;
498 unsigned long aclk_cored; 1004 unsigned long aclk_200;
499 unsigned long aclk_corep; 1005 unsigned long aclk_100;
500 unsigned long aclk_acp; 1006 unsigned long aclk_160;
501 unsigned long pclk_acp; 1007 unsigned long aclk_133;
502 unsigned int ptr; 1008 unsigned int ptr;
503 1009
504 printk(KERN_DEBUG "%s: registering clocks\n", __func__); 1010 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
@@ -529,26 +1035,21 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
529 apll, mpll, epll, vpll); 1035 apll, mpll, epll, vpll);
530 1036
531 armclk = clk_get_rate(&clk_armclk.clk); 1037 armclk = clk_get_rate(&clk_armclk.clk);
532 aclk_corem0 = clk_get_rate(&clk_aclk_corem0.clk);
533 aclk_cores = clk_get_rate(&clk_aclk_cores.clk);
534 aclk_corem1 = clk_get_rate(&clk_aclk_corem1.clk);
535 periphclk = clk_get_rate(&clk_periphclk.clk);
536 sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk); 1038 sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
537 aclk_cored = clk_get_rate(&clk_aclk_cored.clk); 1039
538 aclk_corep = clk_get_rate(&clk_aclk_corep.clk); 1040 aclk_200 = clk_get_rate(&clk_aclk_200.clk);
539 aclk_acp = clk_get_rate(&clk_aclk_acp.clk); 1041 aclk_100 = clk_get_rate(&clk_aclk_100.clk);
540 pclk_acp = clk_get_rate(&clk_pclk_acp.clk); 1042 aclk_160 = clk_get_rate(&clk_aclk_160.clk);
541 1043 aclk_133 = clk_get_rate(&clk_aclk_133.clk);
542 printk(KERN_INFO "S5PV310: ARMCLK=%ld, COREM0=%ld, CORES=%ld\n" 1044
543 "COREM1=%ld, PERI=%ld, DMC=%ld, CORED=%ld\n" 1045 printk(KERN_INFO "S5PV310: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
544 "COREP=%ld, ACLK_ACP=%ld, PCLK_ACP=%ld", 1046 "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
545 armclk, aclk_corem0, aclk_cores, aclk_corem1, 1047 armclk, sclk_dmc, aclk_200,
546 periphclk, sclk_dmc, aclk_cored, aclk_corep, 1048 aclk_100, aclk_160, aclk_133);
547 aclk_acp, pclk_acp);
548 1049
549 clk_f.rate = armclk; 1050 clk_f.rate = armclk;
550 clk_h.rate = sclk_dmc; 1051 clk_h.rate = sclk_dmc;
551 clk_p.rate = periphclk; 1052 clk_p.rate = aclk_100;
552 1053
553 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) 1054 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
554 s3c_set_clksrc(&clksrcs[ptr], true); 1055 s3c_set_clksrc(&clksrcs[ptr], true);
diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c
index 4add39853ff9..82ce4aa6d61a 100644
--- a/arch/arm/mach-s5pv310/cpu.c
+++ b/arch/arm/mach-s5pv310/cpu.c
@@ -15,10 +15,12 @@
15#include <asm/mach/irq.h> 15#include <asm/mach/irq.h>
16 16
17#include <asm/proc-fns.h> 17#include <asm/proc-fns.h>
18#include <asm/hardware/cache-l2x0.h>
18 19
19#include <plat/cpu.h> 20#include <plat/cpu.h>
20#include <plat/clock.h> 21#include <plat/clock.h>
21#include <plat/s5pv310.h> 22#include <plat/s5pv310.h>
23#include <plat/sdhci.h>
22 24
23#include <mach/regs-irq.h> 25#include <mach/regs-irq.h>
24 26
@@ -56,15 +58,30 @@ static struct map_desc s5pv310_iodesc[] __initdata = {
56 .length = SZ_4K, 58 .length = SZ_4K,
57 .type = MT_DEVICE, 59 .type = MT_DEVICE,
58 }, { 60 }, {
59 .virtual = (unsigned long)S5P_VA_GPIO, 61 .virtual = (unsigned long)S5P_VA_GPIO1,
60 .pfn = __phys_to_pfn(S5PV310_PA_GPIO1), 62 .pfn = __phys_to_pfn(S5PV310_PA_GPIO1),
61 .length = SZ_4K, 63 .length = SZ_4K,
62 .type = MT_DEVICE, 64 .type = MT_DEVICE,
63 }, { 65 }, {
66 .virtual = (unsigned long)S5P_VA_GPIO2,
67 .pfn = __phys_to_pfn(S5PV310_PA_GPIO2),
68 .length = SZ_4K,
69 .type = MT_DEVICE,
70 }, {
71 .virtual = (unsigned long)S5P_VA_GPIO3,
72 .pfn = __phys_to_pfn(S5PV310_PA_GPIO3),
73 .length = SZ_256,
74 .type = MT_DEVICE,
75 }, {
64 .virtual = (unsigned long)S3C_VA_UART, 76 .virtual = (unsigned long)S3C_VA_UART,
65 .pfn = __phys_to_pfn(S3C_PA_UART), 77 .pfn = __phys_to_pfn(S3C_PA_UART),
66 .length = SZ_512K, 78 .length = SZ_512K,
67 .type = MT_DEVICE, 79 .type = MT_DEVICE,
80 }, {
81 .virtual = (unsigned long)S5P_VA_SROMC,
82 .pfn = __phys_to_pfn(S5PV310_PA_SROMC),
83 .length = SZ_4K,
84 .type = MT_DEVICE,
68 }, 85 },
69}; 86};
70 87
@@ -83,6 +100,12 @@ static void s5pv310_idle(void)
83void __init s5pv310_map_io(void) 100void __init s5pv310_map_io(void)
84{ 101{
85 iotable_init(s5pv310_iodesc, ARRAY_SIZE(s5pv310_iodesc)); 102 iotable_init(s5pv310_iodesc, ARRAY_SIZE(s5pv310_iodesc));
103
104 /* initialize device information early */
105 s5pv310_default_sdhci0();
106 s5pv310_default_sdhci1();
107 s5pv310_default_sdhci2();
108 s5pv310_default_sdhci3();
86} 109}
87 110
88void __init s5pv310_init_clocks(int xtal) 111void __init s5pv310_init_clocks(int xtal)
@@ -131,6 +154,28 @@ static int __init s5pv310_core_init(void)
131 154
132core_initcall(s5pv310_core_init); 155core_initcall(s5pv310_core_init);
133 156
157#ifdef CONFIG_CACHE_L2X0
158static int __init s5pv310_l2x0_cache_init(void)
159{
160 /* TAG, Data Latency Control: 2cycle */
161 __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
162 __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
163
164 /* L2X0 Prefetch Control */
165 __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
166
167 /* L2X0 Power Control */
168 __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
169 S5P_VA_L2CC + L2X0_POWER_CTRL);
170
171 l2x0_init(S5P_VA_L2CC, 0x7C070001, 0xC200ffff);
172
173 return 0;
174}
175
176early_initcall(s5pv310_l2x0_cache_init);
177#endif
178
134int __init s5pv310_init(void) 179int __init s5pv310_init(void)
135{ 180{
136 printk(KERN_INFO "S5PV310: Initializing architecture\n"); 181 printk(KERN_INFO "S5PV310: Initializing architecture\n");
diff --git a/arch/arm/mach-s5pv310/gpiolib.c b/arch/arm/mach-s5pv310/gpiolib.c
new file mode 100644
index 000000000000..55217b8923ec
--- /dev/null
+++ b/arch/arm/mach-s5pv310/gpiolib.c
@@ -0,0 +1,304 @@
1/* linux/arch/arm/mach-s5pv310/gpiolib.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV310 - GPIOlib support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/irq.h>
15#include <linux/io.h>
16#include <linux/gpio.h>
17
18#include <mach/map.h>
19
20#include <plat/gpio-core.h>
21#include <plat/gpio-cfg.h>
22#include <plat/gpio-cfg-helpers.h>
23
24static struct s3c_gpio_cfg gpio_cfg = {
25 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
26 .set_pull = s3c_gpio_setpull_updown,
27 .get_pull = s3c_gpio_getpull_updown,
28};
29
30static struct s3c_gpio_cfg gpio_cfg_noint = {
31 .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
32 .set_pull = s3c_gpio_setpull_updown,
33 .get_pull = s3c_gpio_getpull_updown,
34};
35
36/*
37 * Following are the gpio banks in v310.
38 *
39 * The 'config' member when left to NULL, is initialized to the default
40 * structure gpio_cfg in the init function below.
41 *
42 * The 'base' member is also initialized in the init function below.
43 * Note: The initialization of 'base' member of s3c_gpio_chip structure
44 * uses the above macro and depends on the banks being listed in order here.
45 */
46static struct s3c_gpio_chip s5pv310_gpio_part1_4bit[] = {
47 {
48 .chip = {
49 .base = S5PV310_GPA0(0),
50 .ngpio = S5PV310_GPIO_A0_NR,
51 .label = "GPA0",
52 },
53 }, {
54 .chip = {
55 .base = S5PV310_GPA1(0),
56 .ngpio = S5PV310_GPIO_A1_NR,
57 .label = "GPA1",
58 },
59 }, {
60 .chip = {
61 .base = S5PV310_GPB(0),
62 .ngpio = S5PV310_GPIO_B_NR,
63 .label = "GPB",
64 },
65 }, {
66 .chip = {
67 .base = S5PV310_GPC0(0),
68 .ngpio = S5PV310_GPIO_C0_NR,
69 .label = "GPC0",
70 },
71 }, {
72 .chip = {
73 .base = S5PV310_GPC1(0),
74 .ngpio = S5PV310_GPIO_C1_NR,
75 .label = "GPC1",
76 },
77 }, {
78 .chip = {
79 .base = S5PV310_GPD0(0),
80 .ngpio = S5PV310_GPIO_D0_NR,
81 .label = "GPD0",
82 },
83 }, {
84 .chip = {
85 .base = S5PV310_GPD1(0),
86 .ngpio = S5PV310_GPIO_D1_NR,
87 .label = "GPD1",
88 },
89 }, {
90 .chip = {
91 .base = S5PV310_GPE0(0),
92 .ngpio = S5PV310_GPIO_E0_NR,
93 .label = "GPE0",
94 },
95 }, {
96 .chip = {
97 .base = S5PV310_GPE1(0),
98 .ngpio = S5PV310_GPIO_E1_NR,
99 .label = "GPE1",
100 },
101 }, {
102 .chip = {
103 .base = S5PV310_GPE2(0),
104 .ngpio = S5PV310_GPIO_E2_NR,
105 .label = "GPE2",
106 },
107 }, {
108 .chip = {
109 .base = S5PV310_GPE3(0),
110 .ngpio = S5PV310_GPIO_E3_NR,
111 .label = "GPE3",
112 },
113 }, {
114 .chip = {
115 .base = S5PV310_GPE4(0),
116 .ngpio = S5PV310_GPIO_E4_NR,
117 .label = "GPE4",
118 },
119 }, {
120 .chip = {
121 .base = S5PV310_GPF0(0),
122 .ngpio = S5PV310_GPIO_F0_NR,
123 .label = "GPF0",
124 },
125 }, {
126 .chip = {
127 .base = S5PV310_GPF1(0),
128 .ngpio = S5PV310_GPIO_F1_NR,
129 .label = "GPF1",
130 },
131 }, {
132 .chip = {
133 .base = S5PV310_GPF2(0),
134 .ngpio = S5PV310_GPIO_F2_NR,
135 .label = "GPF2",
136 },
137 }, {
138 .chip = {
139 .base = S5PV310_GPF3(0),
140 .ngpio = S5PV310_GPIO_F3_NR,
141 .label = "GPF3",
142 },
143 },
144};
145
146static struct s3c_gpio_chip s5pv310_gpio_part2_4bit[] = {
147 {
148 .chip = {
149 .base = S5PV310_GPJ0(0),
150 .ngpio = S5PV310_GPIO_J0_NR,
151 .label = "GPJ0",
152 },
153 }, {
154 .chip = {
155 .base = S5PV310_GPJ1(0),
156 .ngpio = S5PV310_GPIO_J1_NR,
157 .label = "GPJ1",
158 },
159 }, {
160 .chip = {
161 .base = S5PV310_GPK0(0),
162 .ngpio = S5PV310_GPIO_K0_NR,
163 .label = "GPK0",
164 },
165 }, {
166 .chip = {
167 .base = S5PV310_GPK1(0),
168 .ngpio = S5PV310_GPIO_K1_NR,
169 .label = "GPK1",
170 },
171 }, {
172 .chip = {
173 .base = S5PV310_GPK2(0),
174 .ngpio = S5PV310_GPIO_K2_NR,
175 .label = "GPK2",
176 },
177 }, {
178 .chip = {
179 .base = S5PV310_GPK3(0),
180 .ngpio = S5PV310_GPIO_K3_NR,
181 .label = "GPK3",
182 },
183 }, {
184 .chip = {
185 .base = S5PV310_GPL0(0),
186 .ngpio = S5PV310_GPIO_L0_NR,
187 .label = "GPL0",
188 },
189 }, {
190 .chip = {
191 .base = S5PV310_GPL1(0),
192 .ngpio = S5PV310_GPIO_L1_NR,
193 .label = "GPL1",
194 },
195 }, {
196 .chip = {
197 .base = S5PV310_GPL2(0),
198 .ngpio = S5PV310_GPIO_L2_NR,
199 .label = "GPL2",
200 },
201 }, {
202 .base = (S5P_VA_GPIO2 + 0xC00),
203 .config = &gpio_cfg_noint,
204 .irq_base = IRQ_EINT(0),
205 .chip = {
206 .base = S5PV310_GPX0(0),
207 .ngpio = S5PV310_GPIO_X0_NR,
208 .label = "GPX0",
209 .to_irq = samsung_gpiolib_to_irq,
210 },
211 }, {
212 .base = (S5P_VA_GPIO2 + 0xC20),
213 .config = &gpio_cfg_noint,
214 .irq_base = IRQ_EINT(8),
215 .chip = {
216 .base = S5PV310_GPX1(0),
217 .ngpio = S5PV310_GPIO_X1_NR,
218 .label = "GPX1",
219 .to_irq = samsung_gpiolib_to_irq,
220 },
221 }, {
222 .base = (S5P_VA_GPIO2 + 0xC40),
223 .config = &gpio_cfg_noint,
224 .irq_base = IRQ_EINT(16),
225 .chip = {
226 .base = S5PV310_GPX2(0),
227 .ngpio = S5PV310_GPIO_X2_NR,
228 .label = "GPX2",
229 .to_irq = samsung_gpiolib_to_irq,
230 },
231 }, {
232 .base = (S5P_VA_GPIO2 + 0xC60),
233 .config = &gpio_cfg_noint,
234 .irq_base = IRQ_EINT(24),
235 .chip = {
236 .base = S5PV310_GPX3(0),
237 .ngpio = S5PV310_GPIO_X3_NR,
238 .label = "GPX3",
239 .to_irq = samsung_gpiolib_to_irq,
240 },
241 },
242};
243
244static struct s3c_gpio_chip s5pv310_gpio_part3_4bit[] = {
245 {
246 .chip = {
247 .base = S5PV310_GPZ(0),
248 .ngpio = S5PV310_GPIO_Z_NR,
249 .label = "GPZ",
250 },
251 },
252};
253
254static __init int s5pv310_gpiolib_init(void)
255{
256 struct s3c_gpio_chip *chip;
257 int i;
258 int nr_chips;
259
260 /* GPIO part 1 */
261
262 chip = s5pv310_gpio_part1_4bit;
263 nr_chips = ARRAY_SIZE(s5pv310_gpio_part1_4bit);
264
265 for (i = 0; i < nr_chips; i++, chip++) {
266 if (chip->config == NULL)
267 chip->config = &gpio_cfg;
268 if (chip->base == NULL)
269 chip->base = S5P_VA_GPIO1 + (i) * 0x20;
270 }
271
272 samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part1_4bit, nr_chips);
273
274 /* GPIO part 2 */
275
276 chip = s5pv310_gpio_part2_4bit;
277 nr_chips = ARRAY_SIZE(s5pv310_gpio_part2_4bit);
278
279 for (i = 0; i < nr_chips; i++, chip++) {
280 if (chip->config == NULL)
281 chip->config = &gpio_cfg;
282 if (chip->base == NULL)
283 chip->base = S5P_VA_GPIO2 + (i) * 0x20;
284 }
285
286 samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part2_4bit, nr_chips);
287
288 /* GPIO part 3 */
289
290 chip = s5pv310_gpio_part3_4bit;
291 nr_chips = ARRAY_SIZE(s5pv310_gpio_part3_4bit);
292
293 for (i = 0; i < nr_chips; i++, chip++) {
294 if (chip->config == NULL)
295 chip->config = &gpio_cfg;
296 if (chip->base == NULL)
297 chip->base = S5P_VA_GPIO3 + (i) * 0x20;
298 }
299
300 samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part3_4bit, nr_chips);
301
302 return 0;
303}
304core_initcall(s5pv310_gpiolib_init);
diff --git a/arch/arm/mach-s5pv310/hotplug.c b/arch/arm/mach-s5pv310/hotplug.c
new file mode 100644
index 000000000000..03652c3605f6
--- /dev/null
+++ b/arch/arm/mach-s5pv310/hotplug.c
@@ -0,0 +1,144 @@
1/* linux arch/arm/mach-s5pv310/hotplug.c
2 *
3 * Cloned from linux/arch/arm/mach-realview/hotplug.c
4 *
5 * Copyright (C) 2002 ARM Ltd.
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/smp.h>
16#include <linux/completion.h>
17
18#include <asm/cacheflush.h>
19
20extern volatile int pen_release;
21
22static DECLARE_COMPLETION(cpu_killed);
23
24static inline void cpu_enter_lowpower(void)
25{
26 unsigned int v;
27
28 flush_cache_all();
29 asm volatile(
30 " mcr p15, 0, %1, c7, c5, 0\n"
31 " mcr p15, 0, %1, c7, c10, 4\n"
32 /*
33 * Turn off coherency
34 */
35 " mrc p15, 0, %0, c1, c0, 1\n"
36 " bic %0, %0, #0x20\n"
37 " mcr p15, 0, %0, c1, c0, 1\n"
38 " mrc p15, 0, %0, c1, c0, 0\n"
39 " bic %0, %0, #0x04\n"
40 " mcr p15, 0, %0, c1, c0, 0\n"
41 : "=&r" (v)
42 : "r" (0)
43 : "cc");
44}
45
46static inline void cpu_leave_lowpower(void)
47{
48 unsigned int v;
49
50 asm volatile(
51 "mrc p15, 0, %0, c1, c0, 0\n"
52 " orr %0, %0, #0x04\n"
53 " mcr p15, 0, %0, c1, c0, 0\n"
54 " mrc p15, 0, %0, c1, c0, 1\n"
55 " orr %0, %0, #0x20\n"
56 " mcr p15, 0, %0, c1, c0, 1\n"
57 : "=&r" (v)
58 :
59 : "cc");
60}
61
62static inline void platform_do_lowpower(unsigned int cpu)
63{
64 /*
65 * there is no power-control hardware on this platform, so all
66 * we can do is put the core into WFI; this is safe as the calling
67 * code will have already disabled interrupts
68 */
69 for (;;) {
70 /*
71 * here's the WFI
72 */
73 asm(".word 0xe320f003\n"
74 :
75 :
76 : "memory", "cc");
77
78 if (pen_release == cpu) {
79 /*
80 * OK, proper wakeup, we're done
81 */
82 break;
83 }
84
85 /*
86 * getting here, means that we have come out of WFI without
87 * having been woken up - this shouldn't happen
88 *
89 * The trouble is, letting people know about this is not really
90 * possible, since we are currently running incoherently, and
91 * therefore cannot safely call printk() or anything else
92 */
93#ifdef DEBUG
94 printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
95#endif
96 }
97}
98
99int platform_cpu_kill(unsigned int cpu)
100{
101 return wait_for_completion_timeout(&cpu_killed, 5000);
102}
103
104/*
105 * platform-specific code to shutdown a CPU
106 *
107 * Called with IRQs disabled
108 */
109void platform_cpu_die(unsigned int cpu)
110{
111#ifdef DEBUG
112 unsigned int this_cpu = hard_smp_processor_id();
113
114 if (cpu != this_cpu) {
115 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
116 this_cpu, cpu);
117 BUG();
118 }
119#endif
120
121 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
122 complete(&cpu_killed);
123
124 /*
125 * we're ready for shutdown now, so do it
126 */
127 cpu_enter_lowpower();
128 platform_do_lowpower(cpu);
129
130 /*
131 * bring this CPU back into the world of cache
132 * coherency, and then restore interrupts
133 */
134 cpu_leave_lowpower();
135}
136
137int platform_cpu_disable(unsigned int cpu)
138{
139 /*
140 * we don't allow CPU 0 to be shutdown (it is still too special
141 * e.g. clock tick interrupts)
142 */
143 return cpu == 0 ? -EPERM : 0;
144}
diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h
index 471fc3bb199a..99e7dad8a85a 100644
--- a/arch/arm/mach-s5pv310/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv310/include/mach/irqs.h
@@ -3,7 +3,7 @@
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 4 * http://www.samsung.com/
5 * 5 *
6 * S5PV210 - IRQ definitions 6 * S5PV310 - IRQ definitions
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -60,6 +60,9 @@
60#define IRQ_TIMER3_VIC COMBINER_IRQ(22, 3) 60#define IRQ_TIMER3_VIC COMBINER_IRQ(22, 3)
61#define IRQ_TIMER4_VIC COMBINER_IRQ(22, 4) 61#define IRQ_TIMER4_VIC COMBINER_IRQ(22, 4)
62 62
63#define IRQ_RTC_ALARM COMBINER_IRQ(23, 0)
64#define IRQ_RTC_TIC COMBINER_IRQ(23, 1)
65
63#define IRQ_UART0 COMBINER_IRQ(26, 0) 66#define IRQ_UART0 COMBINER_IRQ(26, 0)
64#define IRQ_UART1 COMBINER_IRQ(26, 1) 67#define IRQ_UART1 COMBINER_IRQ(26, 1)
65#define IRQ_UART2 COMBINER_IRQ(26, 2) 68#define IRQ_UART2 COMBINER_IRQ(26, 2)
@@ -67,13 +70,46 @@
67#define IRQ_UART4 COMBINER_IRQ(26, 4) 70#define IRQ_UART4 COMBINER_IRQ(26, 4)
68 71
69#define IRQ_IIC COMBINER_IRQ(27, 0) 72#define IRQ_IIC COMBINER_IRQ(27, 0)
73#define IRQ_IIC1 COMBINER_IRQ(27, 1)
74#define IRQ_IIC2 COMBINER_IRQ(27, 2)
75#define IRQ_IIC3 COMBINER_IRQ(27, 3)
76#define IRQ_IIC4 COMBINER_IRQ(27, 4)
77#define IRQ_IIC5 COMBINER_IRQ(27, 5)
78#define IRQ_IIC6 COMBINER_IRQ(27, 6)
79#define IRQ_IIC7 COMBINER_IRQ(27, 7)
80
81#define IRQ_HSMMC0 COMBINER_IRQ(29, 0)
82#define IRQ_HSMMC1 COMBINER_IRQ(29, 1)
83#define IRQ_HSMMC2 COMBINER_IRQ(29, 2)
84#define IRQ_HSMMC3 COMBINER_IRQ(29, 3)
70 85
71#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0) 86#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0)
72 87
73/* Set the default NR_IRQS */ 88#define IRQ_EINT4 COMBINER_IRQ(37, 0)
89#define IRQ_EINT5 COMBINER_IRQ(37, 1)
90#define IRQ_EINT6 COMBINER_IRQ(37, 2)
91#define IRQ_EINT7 COMBINER_IRQ(37, 3)
92#define IRQ_EINT8 COMBINER_IRQ(38, 0)
93
94#define IRQ_EINT9 COMBINER_IRQ(38, 1)
95#define IRQ_EINT10 COMBINER_IRQ(38, 2)
96#define IRQ_EINT11 COMBINER_IRQ(38, 3)
97#define IRQ_EINT12 COMBINER_IRQ(38, 4)
98#define IRQ_EINT13 COMBINER_IRQ(38, 5)
99#define IRQ_EINT14 COMBINER_IRQ(38, 6)
100#define IRQ_EINT15 COMBINER_IRQ(38, 7)
101
102#define IRQ_EINT16_31 COMBINER_IRQ(39, 0)
74 103
75#define NR_IRQS COMBINER_IRQ(MAX_COMBINER_NR, 0) 104#define MAX_COMBINER_NR 40
105
106#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0)
107
108#define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE + 0)
109#define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE + 16)
110
111/* Set the default NR_IRQS */
76 112
77#define MAX_COMBINER_NR 39 113#define NR_IRQS (S5P_IRQ_EINT_BASE + 32)
78 114
79#endif /* __ASM_ARCH_IRQS_H */ 115#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h
index aff6d23624bb..7acf4e77e92e 100644
--- a/arch/arm/mach-s5pv310/include/mach/map.h
+++ b/arch/arm/mach-s5pv310/include/mach/map.h
@@ -25,6 +25,8 @@
25 25
26#define S5PV310_PA_SYSRAM (0x02025000) 26#define S5PV310_PA_SYSRAM (0x02025000)
27 27
28#define S5PV310_PA_SROM_BANK(x) (0x04000000 + ((x) * 0x01000000))
29
28#define S5PC210_PA_ONENAND (0x0C000000) 30#define S5PC210_PA_ONENAND (0x0C000000)
29#define S5P_PA_ONENAND S5PC210_PA_ONENAND 31#define S5P_PA_ONENAND S5PC210_PA_ONENAND
30 32
@@ -34,12 +36,13 @@
34#define S5PV310_PA_CHIPID (0x10000000) 36#define S5PV310_PA_CHIPID (0x10000000)
35#define S5P_PA_CHIPID S5PV310_PA_CHIPID 37#define S5P_PA_CHIPID S5PV310_PA_CHIPID
36 38
37#define S5PV310_PA_SYSCON (0x10020000) 39#define S5PV310_PA_SYSCON (0x10010000)
38#define S5P_PA_SYSCON S5PV310_PA_SYSCON 40#define S5P_PA_SYSCON S5PV310_PA_SYSCON
39 41
40#define S5PV310_PA_CMU (0x10030000) 42#define S5PV310_PA_CMU (0x10030000)
41 43
42#define S5PV310_PA_WATCHDOG (0x10060000) 44#define S5PV310_PA_WATCHDOG (0x10060000)
45#define S5PV310_PA_RTC (0x10070000)
43 46
44#define S5PV310_PA_COMBINER (0x10448000) 47#define S5PV310_PA_COMBINER (0x10448000)
45 48
@@ -55,6 +58,8 @@
55 58
56#define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000)) 59#define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
57 60
61#define S5PV310_PA_SROMC (0x12570000)
62
58#define S5PV310_PA_UART (0x13800000) 63#define S5PV310_PA_UART (0x13800000)
59 64
60#define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET)) 65#define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET))
@@ -66,7 +71,7 @@
66 71
67#define S5P_SZ_UART SZ_256 72#define S5P_SZ_UART SZ_256
68 73
69#define S5PV310_PA_IIC0 (0x13860000) 74#define S5PV310_PA_IIC(x) (0x13860000 + ((x) * 0x10000))
70 75
71#define S5PV310_PA_TIMER (0x139D0000) 76#define S5PV310_PA_TIMER (0x139D0000)
72#define S5P_PA_TIMER S5PV310_PA_TIMER 77#define S5P_PA_TIMER S5PV310_PA_TIMER
@@ -80,7 +85,15 @@
80#define S3C_PA_HSMMC1 S5PV310_PA_HSMMC(1) 85#define S3C_PA_HSMMC1 S5PV310_PA_HSMMC(1)
81#define S3C_PA_HSMMC2 S5PV310_PA_HSMMC(2) 86#define S3C_PA_HSMMC2 S5PV310_PA_HSMMC(2)
82#define S3C_PA_HSMMC3 S5PV310_PA_HSMMC(3) 87#define S3C_PA_HSMMC3 S5PV310_PA_HSMMC(3)
83#define S3C_PA_IIC S5PV310_PA_IIC0 88#define S3C_PA_IIC S5PV310_PA_IIC(0)
89#define S3C_PA_IIC1 S5PV310_PA_IIC(1)
90#define S3C_PA_IIC2 S5PV310_PA_IIC(2)
91#define S3C_PA_IIC3 S5PV310_PA_IIC(3)
92#define S3C_PA_IIC4 S5PV310_PA_IIC(4)
93#define S3C_PA_IIC5 S5PV310_PA_IIC(5)
94#define S3C_PA_IIC6 S5PV310_PA_IIC(6)
95#define S3C_PA_IIC7 S5PV310_PA_IIC(7)
96#define S3C_PA_RTC S5PV310_PA_RTC
84#define S3C_PA_WDT S5PV310_PA_WATCHDOG 97#define S3C_PA_WDT S5PV310_PA_WATCHDOG
85 98
86#endif /* __ASM_ARCH_MAP_H */ 99#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-clock.h b/arch/arm/mach-s5pv310/include/mach/regs-clock.h
index 4013553cd9be..f1028cad9788 100644
--- a/arch/arm/mach-s5pv310/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv310/include/mach/regs-clock.h
@@ -26,11 +26,23 @@
26 26
27#define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210) 27#define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210)
28#define S5P_CLKSRC_TOP1 S5P_CLKREG(0x0C214) 28#define S5P_CLKSRC_TOP1 S5P_CLKREG(0x0C214)
29 29#define S5P_CLKSRC_CAM S5P_CLKREG(0x0C220)
30#define S5P_CLKSRC_IMAGE S5P_CLKREG(0x0C230)
31#define S5P_CLKSRC_LCD0 S5P_CLKREG(0x0C234)
32#define S5P_CLKSRC_LCD1 S5P_CLKREG(0x0C238)
33#define S5P_CLKSRC_FSYS S5P_CLKREG(0x0C240)
30#define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250) 34#define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250)
35#define S5P_CLKSRC_PERIL1 S5P_CLKREG(0x0C254)
31 36
32#define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510) 37#define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510)
33 38#define S5P_CLKDIV_CAM S5P_CLKREG(0x0C520)
39#define S5P_CLKDIV_IMAGE S5P_CLKREG(0x0C530)
40#define S5P_CLKDIV_LCD0 S5P_CLKREG(0x0C534)
41#define S5P_CLKDIV_LCD1 S5P_CLKREG(0x0C538)
42#define S5P_CLKDIV_FSYS0 S5P_CLKREG(0x0C540)
43#define S5P_CLKDIV_FSYS1 S5P_CLKREG(0x0C544)
44#define S5P_CLKDIV_FSYS2 S5P_CLKREG(0x0C548)
45#define S5P_CLKDIV_FSYS3 S5P_CLKREG(0x0C54C)
34#define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x0C550) 46#define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x0C550)
35#define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x0C554) 47#define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x0C554)
36#define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558) 48#define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558)
@@ -38,9 +50,21 @@
38#define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560) 50#define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560)
39#define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564) 51#define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564)
40 52
53#define S5P_CLKSRC_MASK_TOP S5P_CLKREG(0x0C310)
54#define S5P_CLKSRC_MASK_CAM S5P_CLKREG(0x0C320)
55#define S5P_CLKSRC_MASK_LCD0 S5P_CLKREG(0x0C334)
56#define S5P_CLKSRC_MASK_LCD1 S5P_CLKREG(0x0C338)
57#define S5P_CLKSRC_MASK_FSYS S5P_CLKREG(0x0C340)
41#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350) 58#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350)
59#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354)
42 60
61#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920)
62#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930)
63#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934)
64#define S5P_CLKGATE_IP_LCD1 S5P_CLKREG(0x0C938)
65#define S5P_CLKGATE_IP_FSYS S5P_CLKREG(0x0C940)
43#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950) 66#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950)
67#define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960)
44 68
45#define S5P_CLKSRC_CORE S5P_CLKREG(0x10200) 69#define S5P_CLKSRC_CORE S5P_CLKREG(0x10200)
46#define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500) 70#define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500)
@@ -60,4 +84,8 @@
60 84
61#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800) 85#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800)
62 86
87/* Compatibility defines */
88
89#define S5P_EPLL_CON S5P_EPLL_CON0
90
63#endif /* __ASM_ARCH_REGS_CLOCK_H */ 91#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-gpio.h b/arch/arm/mach-s5pv310/include/mach/regs-gpio.h
new file mode 100644
index 000000000000..82e9e0c9d452
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/regs-gpio.h
@@ -0,0 +1,42 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/regs-gpio.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV310 - GPIO (including EINT) register definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_REGS_GPIO_H
14#define __ASM_ARCH_REGS_GPIO_H __FILE__
15
16#include <mach/map.h>
17#include <mach/irqs.h>
18
19#define S5PV310_EINT40CON (S5P_VA_GPIO2 + 0xE00)
20#define S5P_EINT_CON(x) (S5PV310_EINT40CON + ((x) * 0x4))
21
22#define S5PV310_EINT40FLTCON0 (S5P_VA_GPIO2 + 0xE80)
23#define S5P_EINT_FLTCON(x) (S5PV310_EINT40FLTCON0 + ((x) * 0x4))
24
25#define S5PV310_EINT40MASK (S5P_VA_GPIO2 + 0xF00)
26#define S5P_EINT_MASK(x) (S5PV310_EINT40MASK + ((x) * 0x4))
27
28#define S5PV310_EINT40PEND (S5P_VA_GPIO2 + 0xF40)
29#define S5P_EINT_PEND(x) (S5PV310_EINT40PEND + ((x) * 0x4))
30
31#define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3)
32
33#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
34
35#define EINT_MODE S3C_GPIO_SFN(0xf)
36
37#define EINT_GPIO_0(x) S5PV310_GPX0(x)
38#define EINT_GPIO_1(x) S5PV310_GPX1(x)
39#define EINT_GPIO_2(x) S5PV310_GPX2(x)
40#define EINT_GPIO_3(x) S5PV310_GPX3(x)
41
42#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-srom.h b/arch/arm/mach-s5pv310/include/mach/regs-srom.h
new file mode 100644
index 000000000000..1898b3e10550
--- /dev/null
+++ b/arch/arm/mach-s5pv310/include/mach/regs-srom.h
@@ -0,0 +1,50 @@
1/* linux/arch/arm/mach-s5pv310/include/mach/regs-srom.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV310 - SROMC register definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_REGS_SROM_H
14#define __ASM_ARCH_REGS_SROM_H __FILE__
15
16#include <mach/map.h>
17
18#define S5PV310_SROMREG(x) (S5P_VA_SROMC + (x))
19
20#define S5PV310_SROM_BW S5PV310_SROMREG(0x0)
21#define S5PV310_SROM_BC0 S5PV310_SROMREG(0x4)
22#define S5PV310_SROM_BC1 S5PV310_SROMREG(0x8)
23#define S5PV310_SROM_BC2 S5PV310_SROMREG(0xc)
24#define S5PV310_SROM_BC3 S5PV310_SROMREG(0x10)
25
26/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
27
28#define S5PV310_SROM_BW__DATAWIDTH__SHIFT 0
29#define S5PV310_SROM_BW__ADDRMODE__SHIFT 1
30#define S5PV310_SROM_BW__WAITENABLE__SHIFT 2
31#define S5PV310_SROM_BW__BYTEENABLE__SHIFT 3
32
33#define S5PV310_SROM_BW__CS_MASK 0xf
34
35#define S5PV310_SROM_BW__NCS0__SHIFT 0
36#define S5PV310_SROM_BW__NCS1__SHIFT 4
37#define S5PV310_SROM_BW__NCS2__SHIFT 8
38#define S5PV310_SROM_BW__NCS3__SHIFT 12
39
40/* applies to same to BCS0 - BCS3 */
41
42#define S5PV310_SROM_BCX__PMC__SHIFT 0
43#define S5PV310_SROM_BCX__TACP__SHIFT 4
44#define S5PV310_SROM_BCX__TCAH__SHIFT 8
45#define S5PV310_SROM_BCX__TCOH__SHIFT 12
46#define S5PV310_SROM_BCX__TACC__SHIFT 16
47#define S5PV310_SROM_BCX__TCOS__SHIFT 24
48#define S5PV310_SROM_BCX__TACS__SHIFT 28
49
50#endif /* __ASM_ARCH_REGS_SROM_H */
diff --git a/arch/arm/mach-s5pv310/include/mach/vmalloc.h b/arch/arm/mach-s5pv310/include/mach/vmalloc.h
index 256f221edf3a..65759fb97581 100644
--- a/arch/arm/mach-s5pv310/include/mach/vmalloc.h
+++ b/arch/arm/mach-s5pv310/include/mach/vmalloc.h
@@ -17,6 +17,6 @@
17#ifndef __ASM_ARCH_VMALLOC_H 17#ifndef __ASM_ARCH_VMALLOC_H
18#define __ASM_ARCH_VMALLOC_H __FILE__ 18#define __ASM_ARCH_VMALLOC_H __FILE__
19 19
20#define VMALLOC_END (0xF0000000UL) 20#define VMALLOC_END 0xF6000000UL
21 21
22#endif /* __ASM_ARCH_VMALLOC_H */ 22#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pv310/irq-combiner.c b/arch/arm/mach-s5pv310/irq-combiner.c
index 0f7052164f23..c3f88c3faf6c 100644
--- a/arch/arm/mach-s5pv310/irq-combiner.c
+++ b/arch/arm/mach-s5pv310/irq-combiner.c
@@ -66,11 +66,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
66 if (status == 0) 66 if (status == 0)
67 goto out; 67 goto out;
68 68
69 for (combiner_irq = 0; combiner_irq < 32; combiner_irq++) { 69 combiner_irq = __ffs(status);
70 if (status & 0x1)
71 break;
72 status >>= 1;
73 }
74 70
75 cascade_irq = combiner_irq + (chip_data->irq_offset & ~31); 71 cascade_irq = combiner_irq + (chip_data->irq_offset & ~31);
76 if (unlikely(cascade_irq >= NR_IRQS)) 72 if (unlikely(cascade_irq >= NR_IRQS))
diff --git a/arch/arm/mach-s5pv310/irq-eint.c b/arch/arm/mach-s5pv310/irq-eint.c
new file mode 100644
index 000000000000..5877503e92c3
--- /dev/null
+++ b/arch/arm/mach-s5pv310/irq-eint.c
@@ -0,0 +1,228 @@
1/* linux/arch/arm/mach-s5pv310/irq-eint.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5PV310 - IRQ EINT support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/io.h>
17#include <linux/sysdev.h>
18#include <linux/gpio.h>
19
20#include <plat/pm.h>
21#include <plat/cpu.h>
22#include <plat/gpio-cfg.h>
23
24#include <mach/regs-gpio.h>
25
26static DEFINE_SPINLOCK(eint_lock);
27
28static unsigned int eint0_15_data[16];
29
30static unsigned int s5pv310_get_irq_nr(unsigned int number)
31{
32 u32 ret = 0;
33
34 switch (number) {
35 case 0 ... 3:
36 ret = (number + IRQ_EINT0);
37 break;
38 case 4 ... 7:
39 ret = (number + (IRQ_EINT4 - 4));
40 break;
41 case 8 ... 15:
42 ret = (number + (IRQ_EINT8 - 8));
43 break;
44 default:
45 printk(KERN_ERR "number available : %d\n", number);
46 }
47
48 return ret;
49}
50
51static inline void s5pv310_irq_eint_mask(unsigned int irq)
52{
53 u32 mask;
54
55 spin_lock(&eint_lock);
56 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq)));
57 mask |= eint_irq_to_bit(irq);
58 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq)));
59 spin_unlock(&eint_lock);
60}
61
62static void s5pv310_irq_eint_unmask(unsigned int irq)
63{
64 u32 mask;
65
66 spin_lock(&eint_lock);
67 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq)));
68 mask &= ~(eint_irq_to_bit(irq));
69 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq)));
70 spin_unlock(&eint_lock);
71}
72
73static inline void s5pv310_irq_eint_ack(unsigned int irq)
74{
75 __raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq)));
76}
77
78static void s5pv310_irq_eint_maskack(unsigned int irq)
79{
80 s5pv310_irq_eint_mask(irq);
81 s5pv310_irq_eint_ack(irq);
82}
83
84static int s5pv310_irq_eint_set_type(unsigned int irq, unsigned int type)
85{
86 int offs = EINT_OFFSET(irq);
87 int shift;
88 u32 ctrl, mask;
89 u32 newvalue = 0;
90
91 switch (type) {
92 case IRQ_TYPE_EDGE_RISING:
93 newvalue = S5P_IRQ_TYPE_EDGE_RISING;
94 break;
95
96 case IRQ_TYPE_EDGE_FALLING:
97 newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
98 break;
99
100 case IRQ_TYPE_EDGE_BOTH:
101 newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
102 break;
103
104 case IRQ_TYPE_LEVEL_LOW:
105 newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
106 break;
107
108 case IRQ_TYPE_LEVEL_HIGH:
109 newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
110 break;
111
112 default:
113 printk(KERN_ERR "No such irq type %d", type);
114 return -EINVAL;
115 }
116
117 shift = (offs & 0x7) * 4;
118 mask = 0x7 << shift;
119
120 spin_lock(&eint_lock);
121 ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(irq)));
122 ctrl &= ~mask;
123 ctrl |= newvalue << shift;
124 __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(irq)));
125 spin_unlock(&eint_lock);
126
127 switch (offs) {
128 case 0 ... 7:
129 s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
130 break;
131 case 8 ... 15:
132 s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
133 break;
134 case 16 ... 23:
135 s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
136 break;
137 case 24 ... 31:
138 s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
139 break;
140 default:
141 printk(KERN_ERR "No such irq number %d", offs);
142 }
143
144 return 0;
145}
146
147static struct irq_chip s5pv310_irq_eint = {
148 .name = "s5pv310-eint",
149 .mask = s5pv310_irq_eint_mask,
150 .unmask = s5pv310_irq_eint_unmask,
151 .mask_ack = s5pv310_irq_eint_maskack,
152 .ack = s5pv310_irq_eint_ack,
153 .set_type = s5pv310_irq_eint_set_type,
154#ifdef CONFIG_PM
155 .set_wake = s3c_irqext_wake,
156#endif
157};
158
159/* s5pv310_irq_demux_eint
160 *
161 * This function demuxes the IRQ from from EINTs 16 to 31.
162 * It is designed to be inlined into the specific handler
163 * s5p_irq_demux_eintX_Y.
164 *
165 * Each EINT pend/mask registers handle eight of them.
166 */
167static inline void s5pv310_irq_demux_eint(unsigned int start)
168{
169 unsigned int irq;
170
171 u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
172 u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
173
174 status &= ~mask;
175 status &= 0xff;
176
177 while (status) {
178 irq = fls(status) - 1;
179 generic_handle_irq(irq + start);
180 status &= ~(1 << irq);
181 }
182}
183
184static void s5pv310_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
185{
186 s5pv310_irq_demux_eint(IRQ_EINT(16));
187 s5pv310_irq_demux_eint(IRQ_EINT(24));
188}
189
190static void s5pv310_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
191{
192 u32 *irq_data = get_irq_data(irq);
193 struct irq_chip *chip = get_irq_chip(irq);
194
195 chip->mask(irq);
196
197 if (chip->ack)
198 chip->ack(irq);
199
200 generic_handle_irq(*irq_data);
201
202 chip->unmask(irq);
203}
204
205int __init s5pv310_init_irq_eint(void)
206{
207 int irq;
208
209 for (irq = 0 ; irq <= 31 ; irq++) {
210 set_irq_chip(IRQ_EINT(irq), &s5pv310_irq_eint);
211 set_irq_handler(IRQ_EINT(irq), handle_level_irq);
212 set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
213 }
214
215 set_irq_chained_handler(IRQ_EINT16_31, s5pv310_irq_demux_eint16_31);
216
217 for (irq = 0 ; irq <= 15 ; irq++) {
218 eint0_15_data[irq] = IRQ_EINT(irq);
219
220 set_irq_data(s5pv310_get_irq_nr(irq), &eint0_15_data[irq]);
221 set_irq_chained_handler(s5pv310_get_irq_nr(irq),
222 s5pv310_irq_eint0_15);
223 }
224
225 return 0;
226}
227
228arch_initcall(s5pv310_init_irq_eint);
diff --git a/arch/arm/mach-s5pv310/mach-smdkc210.c b/arch/arm/mach-s5pv310/mach-smdkc210.c
new file mode 100644
index 000000000000..2b8d4fc52d7c
--- /dev/null
+++ b/arch/arm/mach-s5pv310/mach-smdkc210.c
@@ -0,0 +1,202 @@
1/* linux/arch/arm/mach-s5pv310/mach-smdkc210.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/serial_core.h>
12#include <linux/gpio.h>
13#include <linux/mmc/host.h>
14#include <linux/platform_device.h>
15#include <linux/smsc911x.h>
16#include <linux/io.h>
17
18#include <asm/mach/arch.h>
19#include <asm/mach-types.h>
20
21#include <plat/regs-serial.h>
22#include <plat/s5pv310.h>
23#include <plat/cpu.h>
24#include <plat/devs.h>
25#include <plat/sdhci.h>
26
27#include <mach/map.h>
28#include <mach/regs-srom.h>
29
30/* Following are default values for UCON, ULCON and UFCON UART registers */
31#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
32 S3C2410_UCON_RXILEVEL | \
33 S3C2410_UCON_TXIRQMODE | \
34 S3C2410_UCON_RXIRQMODE | \
35 S3C2410_UCON_RXFIFO_TOI | \
36 S3C2443_UCON_RXERR_IRQEN)
37
38#define SMDKC210_ULCON_DEFAULT S3C2410_LCON_CS8
39
40#define SMDKC210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
41 S5PV210_UFCON_TXTRIG4 | \
42 S5PV210_UFCON_RXTRIG4)
43
44static struct s3c2410_uartcfg smdkc210_uartcfgs[] __initdata = {
45 [0] = {
46 .hwport = 0,
47 .flags = 0,
48 .ucon = SMDKC210_UCON_DEFAULT,
49 .ulcon = SMDKC210_ULCON_DEFAULT,
50 .ufcon = SMDKC210_UFCON_DEFAULT,
51 },
52 [1] = {
53 .hwport = 1,
54 .flags = 0,
55 .ucon = SMDKC210_UCON_DEFAULT,
56 .ulcon = SMDKC210_ULCON_DEFAULT,
57 .ufcon = SMDKC210_UFCON_DEFAULT,
58 },
59 [2] = {
60 .hwport = 2,
61 .flags = 0,
62 .ucon = SMDKC210_UCON_DEFAULT,
63 .ulcon = SMDKC210_ULCON_DEFAULT,
64 .ufcon = SMDKC210_UFCON_DEFAULT,
65 },
66 [3] = {
67 .hwport = 3,
68 .flags = 0,
69 .ucon = SMDKC210_UCON_DEFAULT,
70 .ulcon = SMDKC210_ULCON_DEFAULT,
71 .ufcon = SMDKC210_UFCON_DEFAULT,
72 },
73};
74
75static struct s3c_sdhci_platdata smdkc210_hsmmc0_pdata __initdata = {
76 .cd_type = S3C_SDHCI_CD_GPIO,
77 .ext_cd_gpio = S5PV310_GPK0(2),
78 .ext_cd_gpio_invert = 1,
79 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
80#ifdef CONFIG_S5PV310_SDHCI_CH0_8BIT
81 .max_width = 8,
82 .host_caps = MMC_CAP_8_BIT_DATA,
83#endif
84};
85
86static struct s3c_sdhci_platdata smdkc210_hsmmc1_pdata __initdata = {
87 .cd_type = S3C_SDHCI_CD_GPIO,
88 .ext_cd_gpio = S5PV310_GPK0(2),
89 .ext_cd_gpio_invert = 1,
90 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
91};
92
93static struct s3c_sdhci_platdata smdkc210_hsmmc2_pdata __initdata = {
94 .cd_type = S3C_SDHCI_CD_GPIO,
95 .ext_cd_gpio = S5PV310_GPK2(2),
96 .ext_cd_gpio_invert = 1,
97 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
98#ifdef CONFIG_S5PV310_SDHCI_CH2_8BIT
99 .max_width = 8,
100 .host_caps = MMC_CAP_8_BIT_DATA,
101#endif
102};
103
104static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = {
105 .cd_type = S3C_SDHCI_CD_GPIO,
106 .ext_cd_gpio = S5PV310_GPK2(2),
107 .ext_cd_gpio_invert = 1,
108 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
109};
110
111static struct resource smdkc210_smsc911x_resources[] = {
112 [0] = {
113 .start = S5PV310_PA_SROM_BANK(1),
114 .end = S5PV310_PA_SROM_BANK(1) + SZ_64K - 1,
115 .flags = IORESOURCE_MEM,
116 },
117 [1] = {
118 .start = IRQ_EINT(5),
119 .end = IRQ_EINT(5),
120 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
121 },
122};
123
124static struct smsc911x_platform_config smsc9215_config = {
125 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
126 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
127 .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
128 .phy_interface = PHY_INTERFACE_MODE_MII,
129 .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
130};
131
132static struct platform_device smdkc210_smsc911x = {
133 .name = "smsc911x",
134 .id = -1,
135 .num_resources = ARRAY_SIZE(smdkc210_smsc911x_resources),
136 .resource = smdkc210_smsc911x_resources,
137 .dev = {
138 .platform_data = &smsc9215_config,
139 },
140};
141
142static struct platform_device *smdkc210_devices[] __initdata = {
143 &s3c_device_hsmmc0,
144 &s3c_device_hsmmc1,
145 &s3c_device_hsmmc2,
146 &s3c_device_hsmmc3,
147 &s3c_device_rtc,
148 &s3c_device_wdt,
149 &smdkc210_smsc911x,
150};
151
152static void __init smdkc210_smsc911x_init(void)
153{
154 u32 cs1;
155
156 /* configure nCS1 width to 16 bits */
157 cs1 = __raw_readl(S5PV310_SROM_BW) &
158 ~(S5PV310_SROM_BW__CS_MASK <<
159 S5PV310_SROM_BW__NCS1__SHIFT);
160 cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) |
161 (1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) |
162 (1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) <<
163 S5PV310_SROM_BW__NCS1__SHIFT;
164 __raw_writel(cs1, S5PV310_SROM_BW);
165
166 /* set timing for nCS1 suitable for ethernet chip */
167 __raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) |
168 (0x9 << S5PV310_SROM_BCX__TACP__SHIFT) |
169 (0xc << S5PV310_SROM_BCX__TCAH__SHIFT) |
170 (0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) |
171 (0x6 << S5PV310_SROM_BCX__TACC__SHIFT) |
172 (0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) |
173 (0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1);
174}
175
176static void __init smdkc210_map_io(void)
177{
178 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
179 s3c24xx_init_clocks(24000000);
180 s3c24xx_init_uarts(smdkc210_uartcfgs, ARRAY_SIZE(smdkc210_uartcfgs));
181}
182
183static void __init smdkc210_machine_init(void)
184{
185 smdkc210_smsc911x_init();
186
187 s3c_sdhci0_set_platdata(&smdkc210_hsmmc0_pdata);
188 s3c_sdhci1_set_platdata(&smdkc210_hsmmc1_pdata);
189 s3c_sdhci2_set_platdata(&smdkc210_hsmmc2_pdata);
190 s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata);
191
192 platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
193}
194
195MACHINE_START(SMDKC210, "SMDKC210")
196 /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
197 .boot_params = S5P_PA_SDRAM + 0x100,
198 .init_irq = s5pv310_init_irq,
199 .map_io = smdkc210_map_io,
200 .init_machine = smdkc210_machine_init,
201 .timer = &s5pv310_timer,
202MACHINE_END
diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.c b/arch/arm/mach-s5pv310/mach-smdkv310.c
index 46215a14b3bb..35826d66632c 100644
--- a/arch/arm/mach-s5pv310/mach-smdkv310.c
+++ b/arch/arm/mach-s5pv310/mach-smdkv310.c
@@ -9,16 +9,23 @@
9*/ 9*/
10 10
11#include <linux/serial_core.h> 11#include <linux/serial_core.h>
12#include <linux/gpio.h>
13#include <linux/mmc/host.h>
14#include <linux/platform_device.h>
15#include <linux/smsc911x.h>
16#include <linux/io.h>
12 17
13#include <asm/mach/arch.h> 18#include <asm/mach/arch.h>
14#include <asm/mach-types.h> 19#include <asm/mach-types.h>
15#include <asm/hardware/cache-l2x0.h>
16 20
17#include <plat/regs-serial.h> 21#include <plat/regs-serial.h>
18#include <plat/s5pv310.h> 22#include <plat/s5pv310.h>
19#include <plat/cpu.h> 23#include <plat/cpu.h>
24#include <plat/devs.h>
25#include <plat/sdhci.h>
20 26
21#include <mach/map.h> 27#include <mach/map.h>
28#include <mach/regs-srom.h>
22 29
23/* Following are default values for UCON, ULCON and UFCON UART registers */ 30/* Following are default values for UCON, ULCON and UFCON UART registers */
24#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 31#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -65,6 +72,107 @@ static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
65 }, 72 },
66}; 73};
67 74
75static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
76 .cd_type = S3C_SDHCI_CD_GPIO,
77 .ext_cd_gpio = S5PV310_GPK0(2),
78 .ext_cd_gpio_invert = 1,
79 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
80#ifdef CONFIG_S5PV310_SDHCI_CH0_8BIT
81 .max_width = 8,
82 .host_caps = MMC_CAP_8_BIT_DATA,
83#endif
84};
85
86static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
87 .cd_type = S3C_SDHCI_CD_GPIO,
88 .ext_cd_gpio = S5PV310_GPK0(2),
89 .ext_cd_gpio_invert = 1,
90 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
91};
92
93static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
94 .cd_type = S3C_SDHCI_CD_GPIO,
95 .ext_cd_gpio = S5PV310_GPK2(2),
96 .ext_cd_gpio_invert = 1,
97 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
98#ifdef CONFIG_S5PV310_SDHCI_CH2_8BIT
99 .max_width = 8,
100 .host_caps = MMC_CAP_8_BIT_DATA,
101#endif
102};
103
104static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
105 .cd_type = S3C_SDHCI_CD_GPIO,
106 .ext_cd_gpio = S5PV310_GPK2(2),
107 .ext_cd_gpio_invert = 1,
108 .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
109};
110
111static struct resource smdkv310_smsc911x_resources[] = {
112 [0] = {
113 .start = S5PV310_PA_SROM_BANK(1),
114 .end = S5PV310_PA_SROM_BANK(1) + SZ_64K - 1,
115 .flags = IORESOURCE_MEM,
116 },
117 [1] = {
118 .start = IRQ_EINT(5),
119 .end = IRQ_EINT(5),
120 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
121 },
122};
123
124static struct smsc911x_platform_config smsc9215_config = {
125 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
126 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
127 .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
128 .phy_interface = PHY_INTERFACE_MODE_MII,
129 .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
130};
131
132static struct platform_device smdkv310_smsc911x = {
133 .name = "smsc911x",
134 .id = -1,
135 .num_resources = ARRAY_SIZE(smdkv310_smsc911x_resources),
136 .resource = smdkv310_smsc911x_resources,
137 .dev = {
138 .platform_data = &smsc9215_config,
139 },
140};
141
142static struct platform_device *smdkv310_devices[] __initdata = {
143 &s3c_device_hsmmc0,
144 &s3c_device_hsmmc1,
145 &s3c_device_hsmmc2,
146 &s3c_device_hsmmc3,
147 &s3c_device_rtc,
148 &s3c_device_wdt,
149 &smdkv310_smsc911x,
150};
151
152static void __init smdkv310_smsc911x_init(void)
153{
154 u32 cs1;
155
156 /* configure nCS1 width to 16 bits */
157 cs1 = __raw_readl(S5PV310_SROM_BW) &
158 ~(S5PV310_SROM_BW__CS_MASK <<
159 S5PV310_SROM_BW__NCS1__SHIFT);
160 cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) |
161 (1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) |
162 (1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) <<
163 S5PV310_SROM_BW__NCS1__SHIFT;
164 __raw_writel(cs1, S5PV310_SROM_BW);
165
166 /* set timing for nCS1 suitable for ethernet chip */
167 __raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) |
168 (0x9 << S5PV310_SROM_BCX__TACP__SHIFT) |
169 (0xc << S5PV310_SROM_BCX__TCAH__SHIFT) |
170 (0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) |
171 (0x6 << S5PV310_SROM_BCX__TACC__SHIFT) |
172 (0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) |
173 (0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1);
174}
175
68static void __init smdkv310_map_io(void) 176static void __init smdkv310_map_io(void)
69{ 177{
70 s5p_init_io(NULL, 0, S5P_VA_CHIPID); 178 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -74,9 +182,14 @@ static void __init smdkv310_map_io(void)
74 182
75static void __init smdkv310_machine_init(void) 183static void __init smdkv310_machine_init(void)
76{ 184{
77#ifdef CONFIG_CACHE_L2X0 185 smdkv310_smsc911x_init();
78 l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff); 186
79#endif 187 s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
188 s3c_sdhci1_set_platdata(&smdkv310_hsmmc1_pdata);
189 s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
190 s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
191
192 platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
80} 193}
81 194
82MACHINE_START(SMDKV310, "SMDKV310") 195MACHINE_START(SMDKV310, "SMDKV310")
diff --git a/arch/arm/mach-s5pv310/mach-universal_c210.c b/arch/arm/mach-s5pv310/mach-universal_c210.c
index d7c2ec770f88..16d8fc00cafd 100644
--- a/arch/arm/mach-s5pv310/mach-universal_c210.c
+++ b/arch/arm/mach-s5pv310/mach-universal_c210.c
@@ -7,15 +7,20 @@
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8*/ 8*/
9 9
10#include <linux/platform_device.h>
10#include <linux/serial_core.h> 11#include <linux/serial_core.h>
12#include <linux/input.h>
13#include <linux/i2c.h>
14#include <linux/gpio_keys.h>
15#include <linux/gpio.h>
11 16
12#include <asm/mach/arch.h> 17#include <asm/mach/arch.h>
13#include <asm/mach-types.h> 18#include <asm/mach-types.h>
14#include <asm/hardware/cache-l2x0.h>
15 19
16#include <plat/regs-serial.h> 20#include <plat/regs-serial.h>
17#include <plat/s5pv310.h> 21#include <plat/s5pv310.h>
18#include <plat/cpu.h> 22#include <plat/cpu.h>
23#include <plat/devs.h>
19 24
20#include <mach/map.h> 25#include <mach/map.h>
21 26
@@ -60,6 +65,72 @@ static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
60 }, 65 },
61}; 66};
62 67
68static struct gpio_keys_button universal_gpio_keys_tables[] = {
69 {
70 .code = KEY_VOLUMEUP,
71 .gpio = S5PV310_GPX2(0), /* XEINT16 */
72 .desc = "gpio-keys: KEY_VOLUMEUP",
73 .type = EV_KEY,
74 .active_low = 1,
75 .debounce_interval = 1,
76 }, {
77 .code = KEY_VOLUMEDOWN,
78 .gpio = S5PV310_GPX2(1), /* XEINT17 */
79 .desc = "gpio-keys: KEY_VOLUMEDOWN",
80 .type = EV_KEY,
81 .active_low = 1,
82 .debounce_interval = 1,
83 }, {
84 .code = KEY_CONFIG,
85 .gpio = S5PV310_GPX2(2), /* XEINT18 */
86 .desc = "gpio-keys: KEY_CONFIG",
87 .type = EV_KEY,
88 .active_low = 1,
89 .debounce_interval = 1,
90 }, {
91 .code = KEY_CAMERA,
92 .gpio = S5PV310_GPX2(3), /* XEINT19 */
93 .desc = "gpio-keys: KEY_CAMERA",
94 .type = EV_KEY,
95 .active_low = 1,
96 .debounce_interval = 1,
97 }, {
98 .code = KEY_OK,
99 .gpio = S5PV310_GPX3(5), /* XEINT29 */
100 .desc = "gpio-keys: KEY_OK",
101 .type = EV_KEY,
102 .active_low = 1,
103 .debounce_interval = 1,
104 },
105};
106
107static struct gpio_keys_platform_data universal_gpio_keys_data = {
108 .buttons = universal_gpio_keys_tables,
109 .nbuttons = ARRAY_SIZE(universal_gpio_keys_tables),
110};
111
112static struct platform_device universal_gpio_keys = {
113 .name = "gpio-keys",
114 .dev = {
115 .platform_data = &universal_gpio_keys_data,
116 },
117};
118
119/* I2C0 */
120static struct i2c_board_info i2c0_devs[] __initdata = {
121 /* Camera, To be updated */
122};
123
124/* I2C1 */
125static struct i2c_board_info i2c1_devs[] __initdata = {
126 /* Gyro, To be updated */
127};
128
129static struct platform_device *universal_devices[] __initdata = {
130 &universal_gpio_keys,
131 &s5p_device_onenand,
132};
133
63static void __init universal_map_io(void) 134static void __init universal_map_io(void)
64{ 135{
65 s5p_init_io(NULL, 0, S5P_VA_CHIPID); 136 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -69,9 +140,11 @@ static void __init universal_map_io(void)
69 140
70static void __init universal_machine_init(void) 141static void __init universal_machine_init(void)
71{ 142{
72#ifdef CONFIG_CACHE_L2X0 143 i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
73 l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff); 144 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
74#endif 145
146 /* Last */
147 platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
75} 148}
76 149
77MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") 150MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
diff --git a/arch/arm/mach-s5pv310/setup-i2c0.c b/arch/arm/mach-s5pv310/setup-i2c0.c
index 436712807383..f47f8f3152ec 100644
--- a/arch/arm/mach-s5pv310/setup-i2c0.c
+++ b/arch/arm/mach-s5pv310/setup-i2c0.c
@@ -21,8 +21,6 @@ struct platform_device; /* don't need the contents */
21 21
22void s3c_i2c0_cfg_gpio(struct platform_device *dev) 22void s3c_i2c0_cfg_gpio(struct platform_device *dev)
23{ 23{
24 s3c_gpio_cfgpin(S5PV310_GPD1(0), S3C_GPIO_SFN(2)); 24 s3c_gpio_cfgall_range(S5PV310_GPD1(0), 2,
25 s3c_gpio_setpull(S5PV310_GPD1(0), S3C_GPIO_PULL_UP); 25 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
26 s3c_gpio_cfgpin(S5PV310_GPD1(1), S3C_GPIO_SFN(2));
27 s3c_gpio_setpull(S5PV310_GPD1(1), S3C_GPIO_PULL_UP);
28} 26}
diff --git a/arch/arm/mach-s5pv310/setup-i2c1.c b/arch/arm/mach-s5pv310/setup-i2c1.c
index 1ecd5bc35b5a..9d07e4e2f14c 100644
--- a/arch/arm/mach-s5pv310/setup-i2c1.c
+++ b/arch/arm/mach-s5pv310/setup-i2c1.c
@@ -18,8 +18,6 @@ struct platform_device; /* don't need the contents */
18 18
19void s3c_i2c1_cfg_gpio(struct platform_device *dev) 19void s3c_i2c1_cfg_gpio(struct platform_device *dev)
20{ 20{
21 s3c_gpio_cfgpin(S5PV310_GPD1(2), S3C_GPIO_SFN(2)); 21 s3c_gpio_cfgall_range(S5PV310_GPD1(2), 2,
22 s3c_gpio_setpull(S5PV310_GPD1(2), S3C_GPIO_PULL_UP); 22 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
23 s3c_gpio_cfgpin(S5PV310_GPD1(3), S3C_GPIO_SFN(2));
24 s3c_gpio_setpull(S5PV310_GPD1(3), S3C_GPIO_PULL_UP);
25} 23}
diff --git a/arch/arm/mach-s5pv310/setup-i2c2.c b/arch/arm/mach-s5pv310/setup-i2c2.c
index 4c0d8def660a..4163b1233daf 100644
--- a/arch/arm/mach-s5pv310/setup-i2c2.c
+++ b/arch/arm/mach-s5pv310/setup-i2c2.c
@@ -18,8 +18,6 @@ struct platform_device; /* don't need the contents */
18 18
19void s3c_i2c2_cfg_gpio(struct platform_device *dev) 19void s3c_i2c2_cfg_gpio(struct platform_device *dev)
20{ 20{
21 s3c_gpio_cfgpin(S5PV310_GPA0(6), S3C_GPIO_SFN(3)); 21 s3c_gpio_cfgall_range(S5PV310_GPA0(6), 2,
22 s3c_gpio_setpull(S5PV310_GPA0(6), S3C_GPIO_PULL_UP); 22 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
23 s3c_gpio_cfgpin(S5PV310_GPA0(7), S3C_GPIO_SFN(3));
24 s3c_gpio_setpull(S5PV310_GPA0(7), S3C_GPIO_PULL_UP);
25} 23}
diff --git a/arch/arm/mach-s5pv310/setup-i2c3.c b/arch/arm/mach-s5pv310/setup-i2c3.c
new file mode 100644
index 000000000000..180f153d2a20
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c3.c
@@ -0,0 +1,23 @@
1/*
2 * linux/arch/arm/mach-s5pv310/setup-i2c3.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 *
6 * I2C3 GPIO configuration.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13struct platform_device; /* don't need the contents */
14
15#include <linux/gpio.h>
16#include <plat/iic.h>
17#include <plat/gpio-cfg.h>
18
19void s3c_i2c3_cfg_gpio(struct platform_device *dev)
20{
21 s3c_gpio_cfgall_range(S5PV310_GPA1(2), 2,
22 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
23}
diff --git a/arch/arm/mach-s5pv310/setup-i2c4.c b/arch/arm/mach-s5pv310/setup-i2c4.c
new file mode 100644
index 000000000000..909e8dfc5316
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c4.c
@@ -0,0 +1,23 @@
1/*
2 * linux/arch/arm/mach-s5pv310/setup-i2c4.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 *
6 * I2C4 GPIO configuration.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13struct platform_device; /* don't need the contents */
14
15#include <linux/gpio.h>
16#include <plat/iic.h>
17#include <plat/gpio-cfg.h>
18
19void s3c_i2c4_cfg_gpio(struct platform_device *dev)
20{
21 s3c_gpio_cfgall_range(S5PV310_GPB(2), 2,
22 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
23}
diff --git a/arch/arm/mach-s5pv310/setup-i2c5.c b/arch/arm/mach-s5pv310/setup-i2c5.c
new file mode 100644
index 000000000000..5d0fa4ac0283
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c5.c
@@ -0,0 +1,23 @@
1/*
2 * linux/arch/arm/mach-s5pv310/setup-i2c5.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 *
6 * I2C5 GPIO configuration.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13struct platform_device; /* don't need the contents */
14
15#include <linux/gpio.h>
16#include <plat/iic.h>
17#include <plat/gpio-cfg.h>
18
19void s3c_i2c5_cfg_gpio(struct platform_device *dev)
20{
21 s3c_gpio_cfgall_range(S5PV310_GPB(6), 2,
22 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
23}
diff --git a/arch/arm/mach-s5pv310/setup-i2c6.c b/arch/arm/mach-s5pv310/setup-i2c6.c
new file mode 100644
index 000000000000..34aafab92ac4
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c6.c
@@ -0,0 +1,23 @@
1/*
2 * linux/arch/arm/mach-s5pv310/setup-i2c6.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 *
6 * I2C6 GPIO configuration.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13struct platform_device; /* don't need the contents */
14
15#include <linux/gpio.h>
16#include <plat/iic.h>
17#include <plat/gpio-cfg.h>
18
19void s3c_i2c6_cfg_gpio(struct platform_device *dev)
20{
21 s3c_gpio_cfgall_range(S5PV310_GPC1(3), 2,
22 S3C_GPIO_SFN(4), S3C_GPIO_PULL_UP);
23}
diff --git a/arch/arm/mach-s5pv310/setup-i2c7.c b/arch/arm/mach-s5pv310/setup-i2c7.c
new file mode 100644
index 000000000000..9b25b8d18920
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-i2c7.c
@@ -0,0 +1,23 @@
1/*
2 * linux/arch/arm/mach-s5pv310/setup-i2c7.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 *
6 * I2C7 GPIO configuration.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13struct platform_device; /* don't need the contents */
14
15#include <linux/gpio.h>
16#include <plat/iic.h>
17#include <plat/gpio-cfg.h>
18
19void s3c_i2c7_cfg_gpio(struct platform_device *dev)
20{
21 s3c_gpio_cfgall_range(S5PV310_GPD0(2), 2,
22 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
23}
diff --git a/arch/arm/mach-s5pv310/setup-sdhci-gpio.c b/arch/arm/mach-s5pv310/setup-sdhci-gpio.c
new file mode 100644
index 000000000000..86d38cc49135
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-sdhci-gpio.c
@@ -0,0 +1,152 @@
1/* linux/arch/arm/mach-s5pv310/setup-sdhci-gpio.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV310 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/io.h>
18#include <linux/gpio.h>
19#include <linux/mmc/host.h>
20#include <linux/mmc/card.h>
21
22#include <plat/gpio-cfg.h>
23#include <plat/regs-sdhci.h>
24#include <plat/sdhci.h>
25
26void s5pv310_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
27{
28 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
29 unsigned int gpio;
30
31 /* Set all the necessary GPK0[0:1] pins to special-function 2 */
32 for (gpio = S5PV310_GPK0(0); gpio < S5PV310_GPK0(2); gpio++) {
33 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
34 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
35 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
36 }
37
38 switch (width) {
39 case 8:
40 for (gpio = S5PV310_GPK1(3); gpio <= S5PV310_GPK1(6); gpio++) {
41 /* Data pin GPK1[3:6] to special-funtion 3 */
42 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
43 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
44 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
45 }
46 case 4:
47 for (gpio = S5PV310_GPK0(3); gpio <= S5PV310_GPK0(6); gpio++) {
48 /* Data pin GPK0[3:6] to special-funtion 2 */
49 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
50 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
51 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
52 }
53 default:
54 break;
55 }
56
57 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
58 s3c_gpio_cfgpin(S5PV310_GPK0(2), S3C_GPIO_SFN(2));
59 s3c_gpio_setpull(S5PV310_GPK0(2), S3C_GPIO_PULL_UP);
60 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
61 }
62}
63
64void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
65{
66 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
67 unsigned int gpio;
68
69 /* Set all the necessary GPK1[0:1] pins to special-function 2 */
70 for (gpio = S5PV310_GPK1(0); gpio < S5PV310_GPK1(2); gpio++) {
71 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
72 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
73 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
74 }
75
76 for (gpio = S5PV310_GPK1(3); gpio <= S5PV310_GPK1(6); gpio++) {
77 /* Data pin GPK1[3:6] to special-function 2 */
78 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
79 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
80 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
81 }
82
83 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
84 s3c_gpio_cfgpin(S5PV310_GPK1(2), S3C_GPIO_SFN(2));
85 s3c_gpio_setpull(S5PV310_GPK1(2), S3C_GPIO_PULL_UP);
86 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
87 }
88}
89
90void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
91{
92 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
93 unsigned int gpio;
94
95 /* Set all the necessary GPK2[0:1] pins to special-function 2 */
96 for (gpio = S5PV310_GPK2(0); gpio < S5PV310_GPK2(2); gpio++) {
97 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
98 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
99 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
100 }
101
102 switch (width) {
103 case 8:
104 for (gpio = S5PV310_GPK3(3); gpio <= S5PV310_GPK3(6); gpio++) {
105 /* Data pin GPK3[3:6] to special-function 3 */
106 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
107 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
108 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
109 }
110 case 4:
111 for (gpio = S5PV310_GPK2(3); gpio <= S5PV310_GPK2(6); gpio++) {
112 /* Data pin GPK2[3:6] to special-function 2 */
113 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
114 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
115 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
116 }
117 default:
118 break;
119 }
120
121 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
122 s3c_gpio_cfgpin(S5PV310_GPK2(2), S3C_GPIO_SFN(2));
123 s3c_gpio_setpull(S5PV310_GPK2(2), S3C_GPIO_PULL_UP);
124 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
125 }
126}
127
128void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
129{
130 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
131 unsigned int gpio;
132
133 /* Set all the necessary GPK3[0:1] pins to special-function 2 */
134 for (gpio = S5PV310_GPK3(0); gpio < S5PV310_GPK3(2); gpio++) {
135 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
136 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
137 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
138 }
139
140 for (gpio = S5PV310_GPK3(3); gpio <= S5PV310_GPK3(6); gpio++) {
141 /* Data pin GPK3[3:6] to special-function 2 */
142 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
143 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
144 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
145 }
146
147 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
148 s3c_gpio_cfgpin(S5PV310_GPK3(2), S3C_GPIO_SFN(2));
149 s3c_gpio_setpull(S5PV310_GPK3(2), S3C_GPIO_PULL_UP);
150 s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
151 }
152}
diff --git a/arch/arm/mach-s5pv310/setup-sdhci.c b/arch/arm/mach-s5pv310/setup-sdhci.c
new file mode 100644
index 000000000000..db8358fc4662
--- /dev/null
+++ b/arch/arm/mach-s5pv310/setup-sdhci.c
@@ -0,0 +1,69 @@
1/* linux/arch/arm/mach-s5pv310/setup-sdhci.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV310 - Helper functions for settign up SDHCI device(s) (HSMMC)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/io.h>
18
19#include <linux/mmc/card.h>
20#include <linux/mmc/host.h>
21
22#include <plat/regs-sdhci.h>
23
24/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
25
26char *s5pv310_hsmmc_clksrcs[4] = {
27 [0] = NULL,
28 [1] = NULL,
29 [2] = "sclk_mmc", /* mmc_bus */
30 [3] = NULL,
31};
32
33void s5pv310_setup_sdhci_cfg_card(struct platform_device *dev, void __iomem *r,
34 struct mmc_ios *ios, struct mmc_card *card)
35{
36 u32 ctrl2, ctrl3;
37
38 /* don't need to alter anything acording to card-type */
39
40 ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
41
42 /* select base clock source to HCLK */
43
44 ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
45
46 /*
47 * clear async mode, enable conflict mask, rx feedback ctrl, SD
48 * clk hold and no use debounce count
49 */
50
51 ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
52 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
53 S3C_SDHCI_CTRL2_ENFBCLKRX |
54 S3C_SDHCI_CTRL2_DFCNT_NONE |
55 S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
56
57 /* Tx and Rx feedback clock delay control */
58
59 if (ios->clock < 25 * 1000000)
60 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
61 S3C_SDHCI_CTRL3_FCSEL2 |
62 S3C_SDHCI_CTRL3_FCSEL1 |
63 S3C_SDHCI_CTRL3_FCSEL0);
64 else
65 ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
66
67 writel(ctrl2, r + S3C_SDHCI_CONTROL2);
68 writel(ctrl3, r + S3C_SDHCI_CONTROL3);
69}
diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
index c0a13ef5436f..96f7dc103b59 100644
--- a/arch/arm/mach-sa1100/cpu-sa1100.c
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c
@@ -184,16 +184,15 @@ static int sa1100_target(struct cpufreq_policy *policy,
184{ 184{
185 unsigned int cur = sa11x0_getspeed(0); 185 unsigned int cur = sa11x0_getspeed(0);
186 unsigned int new_ppcr; 186 unsigned int new_ppcr;
187
188 struct cpufreq_freqs freqs; 187 struct cpufreq_freqs freqs;
188
189 new_ppcr = sa11x0_freq_to_ppcr(target_freq);
189 switch(relation){ 190 switch(relation){
190 case CPUFREQ_RELATION_L: 191 case CPUFREQ_RELATION_L:
191 new_ppcr = sa11x0_freq_to_ppcr(target_freq);
192 if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max) 192 if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max)
193 new_ppcr--; 193 new_ppcr--;
194 break; 194 break;
195 case CPUFREQ_RELATION_H: 195 case CPUFREQ_RELATION_H:
196 new_ppcr = sa11x0_freq_to_ppcr(target_freq);
197 if ((sa11x0_ppcr_to_freq(new_ppcr) > target_freq) && 196 if ((sa11x0_ppcr_to_freq(new_ppcr) > target_freq) &&
198 (sa11x0_ppcr_to_freq(new_ppcr - 1) >= policy->min)) 197 (sa11x0_ppcr_to_freq(new_ppcr - 1) >= policy->min))
199 new_ppcr--; 198 new_ppcr--;
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 22a2b44ddb7b..46ca4d4abf91 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -30,7 +30,6 @@
30#include <linux/mtd/mtd.h> 30#include <linux/mtd/mtd.h>
31#include <linux/mtd/partitions.h> 31#include <linux/mtd/partitions.h>
32#include <linux/mtd/physmap.h> 32#include <linux/mtd/physmap.h>
33#include <linux/mmc/host.h>
34#include <linux/mmc/sh_mmcif.h> 33#include <linux/mmc/sh_mmcif.h>
35#include <linux/i2c.h> 34#include <linux/i2c.h>
36#include <linux/i2c/tsc2007.h> 35#include <linux/i2c/tsc2007.h>
@@ -44,6 +43,10 @@
44#include <linux/input/sh_keysc.h> 43#include <linux/input/sh_keysc.h>
45#include <linux/usb/r8a66597.h> 44#include <linux/usb/r8a66597.h>
46 45
46#include <media/sh_mobile_ceu.h>
47#include <media/sh_mobile_csi2.h>
48#include <media/soc_camera.h>
49
47#include <sound/sh_fsi.h> 50#include <sound/sh_fsi.h>
48 51
49#include <video/sh_mobile_hdmi.h> 52#include <video/sh_mobile_hdmi.h>
@@ -250,7 +253,7 @@ static int slot_cn7_get_cd(struct platform_device *pdev)
250/* SH_MMCIF */ 253/* SH_MMCIF */
251static struct resource sh_mmcif_resources[] = { 254static struct resource sh_mmcif_resources[] = {
252 [0] = { 255 [0] = {
253 .name = "SH_MMCIF", 256 .name = "MMCIF",
254 .start = 0xE6BD0000, 257 .start = 0xE6BD0000,
255 .end = 0xE6BD00FF, 258 .end = 0xE6BD00FF,
256 .flags = IORESOURCE_MEM, 259 .flags = IORESOURCE_MEM,
@@ -390,10 +393,40 @@ static struct platform_device usb1_host_device = {
390 .resource = usb1_host_resources, 393 .resource = usb1_host_resources,
391}; 394};
392 395
396const static struct fb_videomode ap4evb_lcdc_modes[] = {
397 {
398#ifdef CONFIG_AP4EVB_QHD
399 .name = "R63302(QHD)",
400 .xres = 544,
401 .yres = 961,
402 .left_margin = 72,
403 .right_margin = 600,
404 .hsync_len = 16,
405 .upper_margin = 8,
406 .lower_margin = 8,
407 .vsync_len = 2,
408 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
409#else
410 .name = "WVGA Panel",
411 .xres = 800,
412 .yres = 480,
413 .left_margin = 220,
414 .right_margin = 110,
415 .hsync_len = 70,
416 .upper_margin = 20,
417 .lower_margin = 5,
418 .vsync_len = 5,
419 .sync = 0,
420#endif
421 },
422};
423
393static struct sh_mobile_lcdc_info lcdc_info = { 424static struct sh_mobile_lcdc_info lcdc_info = {
394 .ch[0] = { 425 .ch[0] = {
395 .chan = LCDC_CHAN_MAINLCD, 426 .chan = LCDC_CHAN_MAINLCD,
396 .bpp = 16, 427 .bpp = 16,
428 .lcd_cfg = ap4evb_lcdc_modes,
429 .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
397 } 430 }
398}; 431};
399 432
@@ -532,27 +565,6 @@ static struct platform_device *qhd_devices[] __initdata = {
532 565
533/* FSI */ 566/* FSI */
534#define IRQ_FSI evt2irq(0x1840) 567#define IRQ_FSI evt2irq(0x1840)
535#define FSIACKCR 0xE6150018
536static void fsiackcr_init(struct clk *clk)
537{
538 u32 status = __raw_readl(clk->enable_reg);
539
540 /* use external clock */
541 status &= ~0x000000ff;
542 status |= 0x00000080;
543 __raw_writel(status, clk->enable_reg);
544}
545
546static struct clk_ops fsiackcr_clk_ops = {
547 .init = fsiackcr_init,
548};
549
550static struct clk fsiackcr_clk = {
551 .ops = &fsiackcr_clk_ops,
552 .enable_reg = (void __iomem *)FSIACKCR,
553 .rate = 0, /* unknown */
554};
555
556static struct sh_fsi_platform_info fsi_info = { 568static struct sh_fsi_platform_info fsi_info = {
557 .porta_flags = SH_FSI_BRS_INV | 569 .porta_flags = SH_FSI_BRS_INV |
558 SH_FSI_OUT_SLAVE_MODE | 570 SH_FSI_OUT_SLAVE_MODE |
@@ -592,26 +604,6 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
592 .interface_type = RGB24, 604 .interface_type = RGB24,
593 .clock_divider = 1, 605 .clock_divider = 1,
594 .flags = LCDC_FLAGS_DWPOL, 606 .flags = LCDC_FLAGS_DWPOL,
595 .lcd_cfg = {
596 .name = "HDMI",
597 /* So far only 720p is supported */
598 .xres = 1280,
599 .yres = 720,
600 /*
601 * If left and right margins are not multiples of 8,
602 * LDHAJR will be adjusted accordingly by the LCDC
603 * driver. Until we start using EDID, these values
604 * might have to be adjusted for different monitors.
605 */
606 .left_margin = 200,
607 .right_margin = 88,
608 .hsync_len = 48,
609 .upper_margin = 20,
610 .lower_margin = 5,
611 .vsync_len = 5,
612 .pixclock = 13468,
613 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
614 },
615 } 607 }
616}; 608};
617 609
@@ -623,7 +615,7 @@ static struct resource lcdc1_resources[] = {
623 .flags = IORESOURCE_MEM, 615 .flags = IORESOURCE_MEM,
624 }, 616 },
625 [1] = { 617 [1] = {
626 .start = intcs_evt2irq(0x17a0), 618 .start = intcs_evt2irq(0x1780),
627 .flags = IORESOURCE_IRQ, 619 .flags = IORESOURCE_IRQ,
628 }, 620 },
629}; 621};
@@ -704,6 +696,95 @@ static struct platform_device leds_device = {
704 }, 696 },
705}; 697};
706 698
699static struct i2c_board_info imx074_info = {
700 I2C_BOARD_INFO("imx074", 0x1a),
701};
702
703struct soc_camera_link imx074_link = {
704 .bus_id = 0,
705 .board_info = &imx074_info,
706 .i2c_adapter_id = 0,
707 .module_name = "imx074",
708};
709
710static struct platform_device ap4evb_camera = {
711 .name = "soc-camera-pdrv",
712 .id = 0,
713 .dev = {
714 .platform_data = &imx074_link,
715 },
716};
717
718static struct sh_csi2_client_config csi2_clients[] = {
719 {
720 .phy = SH_CSI2_PHY_MAIN,
721 .lanes = 3,
722 .channel = 0,
723 .pdev = &ap4evb_camera,
724 },
725};
726
727static struct sh_csi2_pdata csi2_info = {
728 .type = SH_CSI2C,
729 .clients = csi2_clients,
730 .num_clients = ARRAY_SIZE(csi2_clients),
731 .flags = SH_CSI2_ECC | SH_CSI2_CRC,
732};
733
734static struct resource csi2_resources[] = {
735 [0] = {
736 .name = "CSI2",
737 .start = 0xffc90000,
738 .end = 0xffc90fff,
739 .flags = IORESOURCE_MEM,
740 },
741 [1] = {
742 .start = intcs_evt2irq(0x17a0),
743 .flags = IORESOURCE_IRQ,
744 },
745};
746
747static struct platform_device csi2_device = {
748 .name = "sh-mobile-csi2",
749 .id = 0,
750 .num_resources = ARRAY_SIZE(csi2_resources),
751 .resource = csi2_resources,
752 .dev = {
753 .platform_data = &csi2_info,
754 },
755};
756
757static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
758 .flags = SH_CEU_FLAG_USE_8BIT_BUS,
759 .csi2_dev = &csi2_device.dev,
760};
761
762static struct resource ceu_resources[] = {
763 [0] = {
764 .name = "CEU",
765 .start = 0xfe910000,
766 .end = 0xfe91009f,
767 .flags = IORESOURCE_MEM,
768 },
769 [1] = {
770 .start = intcs_evt2irq(0x880),
771 .flags = IORESOURCE_IRQ,
772 },
773 [2] = {
774 /* place holder for contiguous memory */
775 },
776};
777
778static struct platform_device ceu_device = {
779 .name = "sh_mobile_ceu",
780 .id = 0, /* "ceu0" clock */
781 .num_resources = ARRAY_SIZE(ceu_resources),
782 .resource = ceu_resources,
783 .dev = {
784 .platform_data = &sh_mobile_ceu_info,
785 },
786};
787
707static struct platform_device *ap4evb_devices[] __initdata = { 788static struct platform_device *ap4evb_devices[] __initdata = {
708 &leds_device, 789 &leds_device,
709 &nor_flash_device, 790 &nor_flash_device,
@@ -716,6 +797,9 @@ static struct platform_device *ap4evb_devices[] __initdata = {
716 &lcdc1_device, 797 &lcdc1_device,
717 &lcdc_device, 798 &lcdc_device,
718 &hdmi_device, 799 &hdmi_device,
800 &csi2_device,
801 &ceu_device,
802 &ap4evb_camera,
719}; 803};
720 804
721static int __init hdmi_init_pm_clock(void) 805static int __init hdmi_init_pm_clock(void)
@@ -730,22 +814,22 @@ static int __init hdmi_init_pm_clock(void)
730 goto out; 814 goto out;
731 } 815 }
732 816
733 ret = clk_set_parent(&pllc2_clk, &dv_clki_div2_clk); 817 ret = clk_set_parent(&sh7372_pllc2_clk, &sh7372_dv_clki_div2_clk);
734 if (ret < 0) { 818 if (ret < 0) {
735 pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, pllc2_clk.usecount); 819 pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, sh7372_pllc2_clk.usecount);
736 goto out; 820 goto out;
737 } 821 }
738 822
739 pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&pllc2_clk)); 823 pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&sh7372_pllc2_clk));
740 824
741 rate = clk_round_rate(&pllc2_clk, 594000000); 825 rate = clk_round_rate(&sh7372_pllc2_clk, 594000000);
742 if (rate < 0) { 826 if (rate < 0) {
743 pr_err("Cannot get suitable rate: %ld\n", rate); 827 pr_err("Cannot get suitable rate: %ld\n", rate);
744 ret = rate; 828 ret = rate;
745 goto out; 829 goto out;
746 } 830 }
747 831
748 ret = clk_set_rate(&pllc2_clk, rate); 832 ret = clk_set_rate(&sh7372_pllc2_clk, rate);
749 if (ret < 0) { 833 if (ret < 0) {
750 pr_err("Cannot set rate %ld: %d\n", rate, ret); 834 pr_err("Cannot set rate %ld: %d\n", rate, ret);
751 goto out; 835 goto out;
@@ -753,7 +837,7 @@ static int __init hdmi_init_pm_clock(void)
753 837
754 pr_debug("PLLC2 set frequency %lu\n", rate); 838 pr_debug("PLLC2 set frequency %lu\n", rate);
755 839
756 ret = clk_set_parent(hdmi_ick, &pllc2_clk); 840 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
757 if (ret < 0) { 841 if (ret < 0) {
758 pr_err("Cannot set HDMI parent: %d\n", ret); 842 pr_err("Cannot set HDMI parent: %d\n", ret);
759 goto out; 843 goto out;
@@ -767,11 +851,51 @@ out:
767 851
768device_initcall(hdmi_init_pm_clock); 852device_initcall(hdmi_init_pm_clock);
769 853
854#define FSIACK_DUMMY_RATE 48000
855static int __init fsi_init_pm_clock(void)
856{
857 struct clk *fsia_ick;
858 int ret;
859
860 /*
861 * FSIACK is connected to AK4642,
862 * and the rate is depend on playing sound rate.
863 * So, set dummy rate (= 48k) here
864 */
865 ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
866 if (ret < 0) {
867 pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
868 return ret;
869 }
870
871 fsia_ick = clk_get(&fsi_device.dev, "icka");
872 if (IS_ERR(fsia_ick)) {
873 ret = PTR_ERR(fsia_ick);
874 pr_err("Cannot get FSI ICK: %d\n", ret);
875 return ret;
876 }
877
878 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
879 if (ret < 0) {
880 pr_err("Cannot set FSI-A parent: %d\n", ret);
881 goto out;
882 }
883
884 ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
885 if (ret < 0)
886 pr_err("Cannot set FSI-A rate: %d\n", ret);
887
888out:
889 clk_put(fsia_ick);
890
891 return ret;
892}
893device_initcall(fsi_init_pm_clock);
894
770/* 895/*
771 * FIXME !! 896 * FIXME !!
772 * 897 *
773 * gpio_no_direction 898 * gpio_no_direction
774 * gpio_pull_up
775 * are quick_hack. 899 * are quick_hack.
776 * 900 *
777 * current gpio frame work doesn't have 901 * current gpio frame work doesn't have
@@ -783,49 +907,37 @@ static void __init gpio_no_direction(u32 addr)
783 __raw_writeb(0x00, addr); 907 __raw_writeb(0x00, addr);
784} 908}
785 909
786static void __init gpio_pull_up(u32 addr)
787{
788 u8 data = __raw_readb(addr);
789
790 data &= 0x0F;
791 data |= 0xC0;
792 __raw_writeb(data, addr);
793}
794
795/* TouchScreen */ 910/* TouchScreen */
911#ifdef CONFIG_AP4EVB_QHD
912# define GPIO_TSC_IRQ GPIO_FN_IRQ28_123
913# define GPIO_TSC_PORT GPIO_PORT123
914#else /* WVGA */
915# define GPIO_TSC_IRQ GPIO_FN_IRQ7_40
916# define GPIO_TSC_PORT GPIO_PORT40
917#endif
918
796#define IRQ28 evt2irq(0x3380) /* IRQ28A */ 919#define IRQ28 evt2irq(0x3380) /* IRQ28A */
797#define IRQ7 evt2irq(0x02e0) /* IRQ7A */ 920#define IRQ7 evt2irq(0x02e0) /* IRQ7A */
798static int ts_get_pendown_state(void) 921static int ts_get_pendown_state(void)
799{ 922{
800 int val1, val2; 923 int val;
801 924
802 gpio_free(GPIO_FN_IRQ28_123); 925 gpio_free(GPIO_TSC_IRQ);
803 gpio_free(GPIO_FN_IRQ7_40);
804 926
805 gpio_request(GPIO_PORT123, NULL); 927 gpio_request(GPIO_TSC_PORT, NULL);
806 gpio_request(GPIO_PORT40, NULL);
807 928
808 gpio_direction_input(GPIO_PORT123); 929 gpio_direction_input(GPIO_TSC_PORT);
809 gpio_direction_input(GPIO_PORT40);
810 930
811 val1 = gpio_get_value(GPIO_PORT123); 931 val = gpio_get_value(GPIO_TSC_PORT);
812 val2 = gpio_get_value(GPIO_PORT40);
813 932
814 gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */ 933 gpio_request(GPIO_TSC_IRQ, NULL);
815 gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */
816 934
817 return val1 ^ val2; 935 return !val;
818} 936}
819 937
820#define PORT40CR 0xE6051028
821#define PORT123CR 0xE605007B
822static int ts_init(void) 938static int ts_init(void)
823{ 939{
824 gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */ 940 gpio_request(GPIO_TSC_IRQ, NULL);
825 gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */
826
827 gpio_pull_up(PORT40CR);
828 gpio_pull_up(PORT123CR);
829 941
830 return 0; 942 return 0;
831} 943}
@@ -974,14 +1086,6 @@ static void __init ap4evb_init(void)
974 clk_put(clk); 1086 clk_put(clk);
975 } 1087 }
976 1088
977 /* change parent of FSI A */
978 clk = clk_get(NULL, "fsia_clk");
979 if (!IS_ERR(clk)) {
980 clk_register(&fsiackcr_clk);
981 clk_set_parent(clk, &fsiackcr_clk);
982 clk_put(clk);
983 }
984
985 /* 1089 /*
986 * set irq priority, to avoid sound chopping 1090 * set irq priority, to avoid sound chopping
987 * when NFS rootfs is used 1091 * when NFS rootfs is used
@@ -996,8 +1100,10 @@ static void __init ap4evb_init(void)
996 ARRAY_SIZE(i2c1_devices)); 1100 ARRAY_SIZE(i2c1_devices));
997 1101
998#ifdef CONFIG_AP4EVB_QHD 1102#ifdef CONFIG_AP4EVB_QHD
1103
999 /* 1104 /*
1000 * QHD 1105 * For QHD Panel (MIPI-DSI, CONFIG_AP4EVB_QHD=y) and
1106 * IRQ28 for Touch Panel, set dip switches S3, S43 as OFF, ON.
1001 */ 1107 */
1002 1108
1003 /* enable KEYSC */ 1109 /* enable KEYSC */
@@ -1023,17 +1129,6 @@ static void __init ap4evb_init(void)
1023 lcdc_info.ch[0].interface_type = RGB24; 1129 lcdc_info.ch[0].interface_type = RGB24;
1024 lcdc_info.ch[0].clock_divider = 1; 1130 lcdc_info.ch[0].clock_divider = 1;
1025 lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL; 1131 lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL;
1026 lcdc_info.ch[0].lcd_cfg.name = "R63302(QHD)";
1027 lcdc_info.ch[0].lcd_cfg.xres = 544;
1028 lcdc_info.ch[0].lcd_cfg.yres = 961;
1029 lcdc_info.ch[0].lcd_cfg.left_margin = 72;
1030 lcdc_info.ch[0].lcd_cfg.right_margin = 600;
1031 lcdc_info.ch[0].lcd_cfg.hsync_len = 16;
1032 lcdc_info.ch[0].lcd_cfg.upper_margin = 8;
1033 lcdc_info.ch[0].lcd_cfg.lower_margin = 8;
1034 lcdc_info.ch[0].lcd_cfg.vsync_len = 2;
1035 lcdc_info.ch[0].lcd_cfg.sync = FB_SYNC_VERT_HIGH_ACT |
1036 FB_SYNC_HOR_HIGH_ACT;
1037 lcdc_info.ch[0].lcd_size_cfg.width = 44; 1132 lcdc_info.ch[0].lcd_size_cfg.width = 44;
1038 lcdc_info.ch[0].lcd_size_cfg.height = 79; 1133 lcdc_info.ch[0].lcd_size_cfg.height = 79;
1039 1134
@@ -1041,8 +1136,10 @@ static void __init ap4evb_init(void)
1041 1136
1042#else 1137#else
1043 /* 1138 /*
1044 * WVGA 1139 * For WVGA Panel (18-bit RGB, CONFIG_AP4EVB_WVGA=y) and
1140 * IRQ7 for Touch Panel, set dip switches S3, S43 to ON, OFF.
1045 */ 1141 */
1142
1046 gpio_request(GPIO_FN_LCDD17, NULL); 1143 gpio_request(GPIO_FN_LCDD17, NULL);
1047 gpio_request(GPIO_FN_LCDD16, NULL); 1144 gpio_request(GPIO_FN_LCDD16, NULL);
1048 gpio_request(GPIO_FN_LCDD15, NULL); 1145 gpio_request(GPIO_FN_LCDD15, NULL);
@@ -1074,16 +1171,6 @@ static void __init ap4evb_init(void)
1074 lcdc_info.ch[0].interface_type = RGB18; 1171 lcdc_info.ch[0].interface_type = RGB18;
1075 lcdc_info.ch[0].clock_divider = 2; 1172 lcdc_info.ch[0].clock_divider = 2;
1076 lcdc_info.ch[0].flags = 0; 1173 lcdc_info.ch[0].flags = 0;
1077 lcdc_info.ch[0].lcd_cfg.name = "WVGA Panel";
1078 lcdc_info.ch[0].lcd_cfg.xres = 800;
1079 lcdc_info.ch[0].lcd_cfg.yres = 480;
1080 lcdc_info.ch[0].lcd_cfg.left_margin = 220;
1081 lcdc_info.ch[0].lcd_cfg.right_margin = 110;
1082 lcdc_info.ch[0].lcd_cfg.hsync_len = 70;
1083 lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
1084 lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
1085 lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
1086 lcdc_info.ch[0].lcd_cfg.sync = 0;
1087 lcdc_info.ch[0].lcd_size_cfg.width = 152; 1174 lcdc_info.ch[0].lcd_size_cfg.width = 152;
1088 lcdc_info.ch[0].lcd_size_cfg.height = 91; 1175 lcdc_info.ch[0].lcd_size_cfg.height = 91;
1089 1176
@@ -1094,6 +1181,23 @@ static void __init ap4evb_init(void)
1094 i2c_register_board_info(0, &tsc_device, 1); 1181 i2c_register_board_info(0, &tsc_device, 1);
1095#endif /* CONFIG_AP4EVB_QHD */ 1182#endif /* CONFIG_AP4EVB_QHD */
1096 1183
1184 /* CEU */
1185
1186 /*
1187 * TODO: reserve memory for V4L2 DMA buffers, when a suitable API
1188 * becomes available
1189 */
1190
1191 /* MIPI-CSI stuff */
1192 gpio_request(GPIO_FN_VIO_CKO, NULL);
1193
1194 clk = clk_get(NULL, "vck1_clk");
1195 if (!IS_ERR(clk)) {
1196 clk_set_rate(clk, clk_round_rate(clk, 13000000));
1197 clk_enable(clk);
1198 clk_put(clk);
1199 }
1200
1097 sh7372_add_standard_devices(); 1201 sh7372_add_standard_devices();
1098 1202
1099 /* HDMI */ 1203 /* HDMI */
@@ -1116,7 +1220,7 @@ static void __init ap4evb_timer_init(void)
1116 shmobile_timer.init(); 1220 shmobile_timer.init();
1117 1221
1118 /* External clock source */ 1222 /* External clock source */
1119 clk_set_rate(&dv_clki_clk, 27000000); 1223 clk_set_rate(&sh7372_dv_clki_clk, 27000000);
1120} 1224}
1121 1225
1122static struct sys_timer ap4evb_timer = { 1226static struct sys_timer ap4evb_timer = {
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
index b6454c9f2abb..9f78729098f2 100644
--- a/arch/arm/mach-shmobile/clock-sh7367.c
+++ b/arch/arm/mach-shmobile/clock-sh7367.c
@@ -321,7 +321,7 @@ static struct clk_lookup lookups[] = {
321 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */ 321 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */
322 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */ 322 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */
323 CLKDEV_DEV_ID("sh_siu", &mstp_clks[SYMSTP231]), /* SIU */ 323 CLKDEV_DEV_ID("sh_siu", &mstp_clks[SYMSTP231]), /* SIU */
324 CLKDEV_CON_ID("cmt1", &mstp_clks[SYMSTP229]), /* CMT10 */ 324 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[SYMSTP229]), /* CMT10 */
325 CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */ 325 CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */
326 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */ 326 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */
327 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */ 327 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 759468992ad2..8565aefa21fd 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -51,7 +51,7 @@
51#define SMSTPCR4 0xe6150140 51#define SMSTPCR4 0xe6150140
52 52
53/* Platforms must set frequency on their DV_CLKI pin */ 53/* Platforms must set frequency on their DV_CLKI pin */
54struct clk dv_clki_clk = { 54struct clk sh7372_dv_clki_clk = {
55}; 55};
56 56
57/* Fixed 32 KHz root clock from EXTALR pin */ 57/* Fixed 32 KHz root clock from EXTALR pin */
@@ -86,9 +86,9 @@ static struct clk_ops div2_clk_ops = {
86}; 86};
87 87
88/* Divide dv_clki by two */ 88/* Divide dv_clki by two */
89struct clk dv_clki_div2_clk = { 89struct clk sh7372_dv_clki_div2_clk = {
90 .ops = &div2_clk_ops, 90 .ops = &div2_clk_ops,
91 .parent = &dv_clki_clk, 91 .parent = &sh7372_dv_clki_clk,
92}; 92};
93 93
94/* Divide extal1 by two */ 94/* Divide extal1 by two */
@@ -150,7 +150,7 @@ static struct clk pllc1_div2_clk = {
150static struct clk *pllc2_parent[] = { 150static struct clk *pllc2_parent[] = {
151 [0] = &extal1_div2_clk, 151 [0] = &extal1_div2_clk,
152 [1] = &extal2_div2_clk, 152 [1] = &extal2_div2_clk,
153 [2] = &dv_clki_div2_clk, 153 [2] = &sh7372_dv_clki_div2_clk,
154}; 154};
155 155
156/* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */ 156/* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
@@ -284,7 +284,7 @@ static struct clk_ops pllc2_clk_ops = {
284 .set_parent = pllc2_set_parent, 284 .set_parent = pllc2_set_parent,
285}; 285};
286 286
287struct clk pllc2_clk = { 287struct clk sh7372_pllc2_clk = {
288 .ops = &pllc2_clk_ops, 288 .ops = &pllc2_clk_ops,
289 .parent = &extal1_div2_clk, 289 .parent = &extal1_div2_clk,
290 .freq_table = pllc2_freq_table, 290 .freq_table = pllc2_freq_table,
@@ -292,19 +292,28 @@ struct clk pllc2_clk = {
292 .parent_num = ARRAY_SIZE(pllc2_parent), 292 .parent_num = ARRAY_SIZE(pllc2_parent),
293}; 293};
294 294
295/* External input clock (pin name: FSIACK/FSIBCK ) */
296struct clk sh7372_fsiack_clk = {
297};
298
299struct clk sh7372_fsibck_clk = {
300};
301
295static struct clk *main_clks[] = { 302static struct clk *main_clks[] = {
296 &dv_clki_clk, 303 &sh7372_dv_clki_clk,
297 &r_clk, 304 &r_clk,
298 &sh7372_extal1_clk, 305 &sh7372_extal1_clk,
299 &sh7372_extal2_clk, 306 &sh7372_extal2_clk,
300 &dv_clki_div2_clk, 307 &sh7372_dv_clki_div2_clk,
301 &extal1_div2_clk, 308 &extal1_div2_clk,
302 &extal2_div2_clk, 309 &extal2_div2_clk,
303 &extal2_div4_clk, 310 &extal2_div4_clk,
304 &pllc0_clk, 311 &pllc0_clk,
305 &pllc1_clk, 312 &pllc1_clk,
306 &pllc1_div2_clk, 313 &pllc1_div2_clk,
307 &pllc2_clk, 314 &sh7372_pllc2_clk,
315 &sh7372_fsiack_clk,
316 &sh7372_fsibck_clk,
308}; 317};
309 318
310static void div4_kick(struct clk *clk) 319static void div4_kick(struct clk *clk)
@@ -357,7 +366,7 @@ static struct clk div4_clks[DIV4_NR] = {
357}; 366};
358 367
359enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO, 368enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
360 DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU, 369 DIV6_SUB, DIV6_SPU,
361 DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P, 370 DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
362 DIV6_NR }; 371 DIV6_NR };
363 372
@@ -367,8 +376,6 @@ static struct clk div6_clks[DIV6_NR] = {
367 [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), 376 [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
368 [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0), 377 [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
369 [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0), 378 [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
370 [DIV6_FSIA] = SH_CLK_DIV6(&pllc1_div2_clk, FSIACKCR, 0),
371 [DIV6_FSIB] = SH_CLK_DIV6(&pllc1_div2_clk, FSIBCKCR, 0),
372 [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0), 379 [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
373 [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), 380 [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
374 [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0), 381 [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
@@ -377,24 +384,42 @@ static struct clk div6_clks[DIV6_NR] = {
377 [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0), 384 [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
378}; 385};
379 386
380enum { DIV6_HDMI, DIV6_REPARENT_NR }; 387enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
381 388
382/* Indices are important - they are the actual src selecting values */ 389/* Indices are important - they are the actual src selecting values */
383static struct clk *hdmi_parent[] = { 390static struct clk *hdmi_parent[] = {
384 [0] = &pllc1_div2_clk, 391 [0] = &pllc1_div2_clk,
385 [1] = &pllc2_clk, 392 [1] = &sh7372_pllc2_clk,
386 [2] = &dv_clki_clk, 393 [2] = &sh7372_dv_clki_clk,
387 [3] = NULL, /* pllc2_div4 not implemented yet */ 394 [3] = NULL, /* pllc2_div4 not implemented yet */
388}; 395};
389 396
397static struct clk *fsiackcr_parent[] = {
398 [0] = &pllc1_div2_clk,
399 [1] = &sh7372_pllc2_clk,
400 [2] = &sh7372_fsiack_clk, /* external input for FSI A */
401 [3] = NULL, /* setting prohibited */
402};
403
404static struct clk *fsibckcr_parent[] = {
405 [0] = &pllc1_div2_clk,
406 [1] = &sh7372_pllc2_clk,
407 [2] = &sh7372_fsibck_clk, /* external input for FSI B */
408 [3] = NULL, /* setting prohibited */
409};
410
390static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { 411static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
391 [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0, 412 [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
392 hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2), 413 hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
414 [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0,
415 fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
416 [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0,
417 fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
393}; 418};
394 419
395enum { MSTP001, 420enum { MSTP001,
396 MSTP131, MSTP130, 421 MSTP131, MSTP130,
397 MSTP129, MSTP128, MSTP127, MSTP126, 422 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
398 MSTP118, MSTP117, MSTP116, 423 MSTP118, MSTP117, MSTP116,
399 MSTP106, MSTP101, MSTP100, 424 MSTP106, MSTP101, MSTP100,
400 MSTP223, 425 MSTP223,
@@ -414,6 +439,7 @@ static struct clk mstp_clks[MSTP_NR] = {
414 [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */ 439 [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
415 [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */ 440 [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
416 [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */ 441 [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
442 [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
417 [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */ 443 [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
418 [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ 444 [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
419 [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ 445 [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
@@ -429,7 +455,7 @@ static struct clk mstp_clks[MSTP_NR] = {
429 [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ 455 [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
430 [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ 456 [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
431 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ 457 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
432 [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSIA */ 458 [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
433 [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ 459 [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
434 [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ 460 [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
435 [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ 461 [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
@@ -445,10 +471,11 @@ static struct clk mstp_clks[MSTP_NR] = {
445 471
446#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } 472#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
447#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } 473#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
474#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
448 475
449static struct clk_lookup lookups[] = { 476static struct clk_lookup lookups[] = {
450 /* main clocks */ 477 /* main clocks */
451 CLKDEV_CON_ID("dv_clki_div2_clk", &dv_clki_div2_clk), 478 CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
452 CLKDEV_CON_ID("r_clk", &r_clk), 479 CLKDEV_CON_ID("r_clk", &r_clk),
453 CLKDEV_CON_ID("extal1", &sh7372_extal1_clk), 480 CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
454 CLKDEV_CON_ID("extal2", &sh7372_extal2_clk), 481 CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
@@ -458,7 +485,7 @@ static struct clk_lookup lookups[] = {
458 CLKDEV_CON_ID("pllc0_clk", &pllc0_clk), 485 CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
459 CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), 486 CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
460 CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), 487 CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
461 CLKDEV_CON_ID("pllc2_clk", &pllc2_clk), 488 CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
462 489
463 /* DIV4 clocks */ 490 /* DIV4 clocks */
464 CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), 491 CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
@@ -483,8 +510,8 @@ static struct clk_lookup lookups[] = {
483 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), 510 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
484 CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), 511 CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
485 CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), 512 CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
486 CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FSIA]), 513 CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FSIA]),
487 CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FSIB]), 514 CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FSIB]),
488 CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), 515 CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
489 CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), 516 CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
490 CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), 517 CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
@@ -501,6 +528,8 @@ static struct clk_lookup lookups[] = {
501 CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ 528 CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
502 CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */ 529 CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
503 CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */ 530 CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
531 CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
532 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
504 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ 533 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
505 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ 534 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
506 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ 535 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
@@ -516,7 +545,7 @@ static struct clk_lookup lookups[] = {
516 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ 545 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
517 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ 546 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
518 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ 547 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
519 CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */ 548 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
520 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ 549 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
521 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ 550 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
522 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */ 551 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */
@@ -531,7 +560,10 @@ static struct clk_lookup lookups[] = {
531 CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ 560 CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
532 CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ 561 CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
533 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ 562 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
534 {.con_id = "ick", .dev_id = "sh-mobile-hdmi", .clk = &div6_reparent_clks[DIV6_HDMI]}, 563
564 CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
565 CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
566 CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
535}; 567};
536 568
537void __init sh7372_clock_init(void) 569void __init sh7372_clock_init(void)
@@ -548,7 +580,7 @@ void __init sh7372_clock_init(void)
548 ret = sh_clk_div6_register(div6_clks, DIV6_NR); 580 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
549 581
550 if (!ret) 582 if (!ret)
551 ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_NR); 583 ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
552 584
553 if (!ret) 585 if (!ret)
554 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); 586 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c
index e007c28cf0a8..f91395aeb9ab 100644
--- a/arch/arm/mach-shmobile/clock-sh7377.c
+++ b/arch/arm/mach-shmobile/clock-sh7377.c
@@ -333,7 +333,7 @@ static struct clk_lookup lookups[] = {
333 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ 333 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
334 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ 334 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
335 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */ 335 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
336 CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */ 336 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
337 CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */ 337 CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */
338 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ 338 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
339 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */ 339 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index 33e9700ded7e..147775a94bce 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -457,8 +457,12 @@ enum {
457 SHDMA_SLAVE_SDHI2_TX, 457 SHDMA_SLAVE_SDHI2_TX,
458}; 458};
459 459
460extern struct clk dv_clki_clk; 460extern struct clk sh7372_extal1_clk;
461extern struct clk dv_clki_div2_clk; 461extern struct clk sh7372_extal2_clk;
462extern struct clk pllc2_clk; 462extern struct clk sh7372_dv_clki_clk;
463extern struct clk sh7372_dv_clki_div2_clk;
464extern struct clk sh7372_pllc2_clk;
465extern struct clk sh7372_fsiack_clk;
466extern struct clk sh7372_fsibck_clk;
463 467
464#endif /* __ASM_SH7372_H__ */ 468#endif /* __ASM_SH7372_H__ */
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c
index e3551b56cd03..4cd3cae38e72 100644
--- a/arch/arm/mach-shmobile/intc-sh7372.c
+++ b/arch/arm/mach-shmobile/intc-sh7372.c
@@ -369,9 +369,13 @@ enum {
369 INTCS, 369 INTCS,
370 370
371 /* interrupt sources INTCS */ 371 /* interrupt sources INTCS */
372
373 /* IRQ0S - IRQ31S */
372 VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3, 374 VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3,
373 RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3, 375 RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3,
374 CEU, BEU_BEU0, BEU_BEU1, BEU_BEU2, 376 CEU, BEU_BEU0, BEU_BEU1, BEU_BEU2,
377 /* MFI */
378 /* BBIF2 */
375 VPU, 379 VPU,
376 TSIF1, 380 TSIF1,
377 _3DG_SGX530, 381 _3DG_SGX530,
@@ -379,13 +383,17 @@ enum {
379 IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, 383 IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
380 IPMMU_IPMMUR, IPMMU_IPMMUR2, 384 IPMMU_IPMMUR, IPMMU_IPMMUR2,
381 RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR, 385 RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR,
386 /* KEYSC */
387 /* TTI20 */
382 MSIOF, 388 MSIOF,
383 IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0, 389 IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
384 TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, 390 TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
385 CMT0, 391 CMT0,
386 TSIF0, 392 TSIF0,
393 /* CMT2 */
387 LMB, 394 LMB,
388 CTI, 395 CTI,
396 /* RWDT0 */
389 ICB, 397 ICB,
390 JPU_JPEG, 398 JPU_JPEG,
391 LCDC, 399 LCDC,
@@ -397,11 +405,17 @@ enum {
397 CSIRX, 405 CSIRX,
398 DSITX_DSITX0, 406 DSITX_DSITX0,
399 DSITX_DSITX1, 407 DSITX_DSITX1,
408 /* SPU2 */
409 /* FSI */
410 /* FMSI */
411 /* HDMI */
400 TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2, 412 TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2,
401 CMT4, 413 CMT4,
402 DSITX1_DSITX1_0, 414 DSITX1_DSITX1_0,
403 DSITX1_DSITX1_1, 415 DSITX1_DSITX1_1,
416 /* MFIS2 */
404 CPORTS2R, 417 CPORTS2R,
418 /* CEC */
405 JPU6E, 419 JPU6E,
406 420
407 /* interrupt groups INTCS */ 421 /* interrupt groups INTCS */
@@ -410,12 +424,15 @@ enum {
410}; 424};
411 425
412static struct intc_vect intcs_vectors[] = { 426static struct intc_vect intcs_vectors[] = {
427 /* IRQ0S - IRQ31S */
413 INTCS_VECT(VEU_VEU0, 0x700), INTCS_VECT(VEU_VEU1, 0x720), 428 INTCS_VECT(VEU_VEU0, 0x700), INTCS_VECT(VEU_VEU1, 0x720),
414 INTCS_VECT(VEU_VEU2, 0x740), INTCS_VECT(VEU_VEU3, 0x760), 429 INTCS_VECT(VEU_VEU2, 0x740), INTCS_VECT(VEU_VEU3, 0x760),
415 INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820), 430 INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820),
416 INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860), 431 INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860),
417 INTCS_VECT(CEU, 0x880), INTCS_VECT(BEU_BEU0, 0x8a0), 432 INTCS_VECT(CEU, 0x880), INTCS_VECT(BEU_BEU0, 0x8a0),
418 INTCS_VECT(BEU_BEU1, 0x8c0), INTCS_VECT(BEU_BEU2, 0x8e0), 433 INTCS_VECT(BEU_BEU1, 0x8c0), INTCS_VECT(BEU_BEU2, 0x8e0),
434 /* MFI */
435 /* BBIF2 */
419 INTCS_VECT(VPU, 0x980), 436 INTCS_VECT(VPU, 0x980),
420 INTCS_VECT(TSIF1, 0x9a0), 437 INTCS_VECT(TSIF1, 0x9a0),
421 INTCS_VECT(_3DG_SGX530, 0x9e0), 438 INTCS_VECT(_3DG_SGX530, 0x9e0),
@@ -425,14 +442,19 @@ static struct intc_vect intcs_vectors[] = {
425 INTCS_VECT(IPMMU_IPMMUR, 0xb00), INTCS_VECT(IPMMU_IPMMUR2, 0xb20), 442 INTCS_VECT(IPMMU_IPMMUR, 0xb00), INTCS_VECT(IPMMU_IPMMUR2, 0xb20),
426 INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0), 443 INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0),
427 INTCS_VECT(RTDMAC_2_DADERR, 0xbc0), 444 INTCS_VECT(RTDMAC_2_DADERR, 0xbc0),
445 /* KEYSC */
446 /* TTI20 */
447 INTCS_VECT(MSIOF, 0x0d20),
428 INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20), 448 INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20),
429 INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60), 449 INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60),
430 INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0), 450 INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0),
431 INTCS_VECT(TMU_TUNI2, 0xec0), 451 INTCS_VECT(TMU_TUNI2, 0xec0),
432 INTCS_VECT(CMT0, 0xf00), 452 INTCS_VECT(CMT0, 0xf00),
433 INTCS_VECT(TSIF0, 0xf20), 453 INTCS_VECT(TSIF0, 0xf20),
454 /* CMT2 */
434 INTCS_VECT(LMB, 0xf60), 455 INTCS_VECT(LMB, 0xf60),
435 INTCS_VECT(CTI, 0x400), 456 INTCS_VECT(CTI, 0x400),
457 /* RWDT0 */
436 INTCS_VECT(ICB, 0x480), 458 INTCS_VECT(ICB, 0x480),
437 INTCS_VECT(JPU_JPEG, 0x560), 459 INTCS_VECT(JPU_JPEG, 0x560),
438 INTCS_VECT(LCDC, 0x580), 460 INTCS_VECT(LCDC, 0x580),
@@ -446,12 +468,18 @@ static struct intc_vect intcs_vectors[] = {
446 INTCS_VECT(CSIRX, 0x17a0), 468 INTCS_VECT(CSIRX, 0x17a0),
447 INTCS_VECT(DSITX_DSITX0, 0x17c0), 469 INTCS_VECT(DSITX_DSITX0, 0x17c0),
448 INTCS_VECT(DSITX_DSITX1, 0x17e0), 470 INTCS_VECT(DSITX_DSITX1, 0x17e0),
471 /* SPU2 */
472 /* FSI */
473 /* FMSI */
474 /* HDMI */
449 INTCS_VECT(TMU1_TUNI0, 0x1900), INTCS_VECT(TMU1_TUNI1, 0x1920), 475 INTCS_VECT(TMU1_TUNI0, 0x1900), INTCS_VECT(TMU1_TUNI1, 0x1920),
450 INTCS_VECT(TMU1_TUNI2, 0x1940), 476 INTCS_VECT(TMU1_TUNI2, 0x1940),
451 INTCS_VECT(CMT4, 0x1980), 477 INTCS_VECT(CMT4, 0x1980),
452 INTCS_VECT(DSITX1_DSITX1_0, 0x19a0), 478 INTCS_VECT(DSITX1_DSITX1_0, 0x19a0),
453 INTCS_VECT(DSITX1_DSITX1_1, 0x19c0), 479 INTCS_VECT(DSITX1_DSITX1_1, 0x19c0),
480 /* MFIS2 */
454 INTCS_VECT(CPORTS2R, 0x1a20), 481 INTCS_VECT(CPORTS2R, 0x1a20),
482 /* CEC */
455 INTCS_VECT(JPU6E, 0x1a80), 483 INTCS_VECT(JPU6E, 0x1a80),
456 484
457 INTC_VECT(INTCS, 0xf80), 485 INTC_VECT(INTCS, 0xf80),
diff --git a/arch/arm/mach-shmobile/pfc-sh7372.c b/arch/arm/mach-shmobile/pfc-sh7372.c
index ec420353f8e3..9c265dae138a 100644
--- a/arch/arm/mach-shmobile/pfc-sh7372.c
+++ b/arch/arm/mach-shmobile/pfc-sh7372.c
@@ -166,12 +166,12 @@ enum {
166 MSIOF2_TSYNC_MARK, MSIOF2_TSCK_MARK, MSIOF2_RXD_MARK, 166 MSIOF2_TSYNC_MARK, MSIOF2_TSCK_MARK, MSIOF2_RXD_MARK,
167 MSIOF2_TXD_MARK, 167 MSIOF2_TXD_MARK,
168 168
169 /* MSIOF3 */ 169 /* BBIF1 */
170 BBIF1_RXD_MARK, BBIF1_TSYNC_MARK, BBIF1_TSCK_MARK, 170 BBIF1_RXD_MARK, BBIF1_TSYNC_MARK, BBIF1_TSCK_MARK,
171 BBIF1_TXD_MARK, BBIF1_RSCK_MARK, BBIF1_RSYNC_MARK, 171 BBIF1_TXD_MARK, BBIF1_RSCK_MARK, BBIF1_RSYNC_MARK,
172 BBIF1_FLOW_MARK, BB_RX_FLOW_N_MARK, 172 BBIF1_FLOW_MARK, BB_RX_FLOW_N_MARK,
173 173
174 /* MSIOF4 */ 174 /* BBIF2 */
175 BBIF2_TSCK1_MARK, BBIF2_TSYNC1_MARK, 175 BBIF2_TSCK1_MARK, BBIF2_TSYNC1_MARK,
176 BBIF2_TXD1_MARK, BBIF2_RXD_MARK, 176 BBIF2_TXD1_MARK, BBIF2_RXD_MARK,
177 177
@@ -976,12 +976,12 @@ static struct pinmux_gpio pinmux_gpios[] = {
976 GPIO_FN(MSIOF2_TSYNC), GPIO_FN(MSIOF2_TSCK), GPIO_FN(MSIOF2_RXD), 976 GPIO_FN(MSIOF2_TSYNC), GPIO_FN(MSIOF2_TSCK), GPIO_FN(MSIOF2_RXD),
977 GPIO_FN(MSIOF2_TXD), 977 GPIO_FN(MSIOF2_TXD),
978 978
979 /* MSIOF3 */ 979 /* BBIF1 */
980 GPIO_FN(BBIF1_RXD), GPIO_FN(BBIF1_TSYNC), GPIO_FN(BBIF1_TSCK), 980 GPIO_FN(BBIF1_RXD), GPIO_FN(BBIF1_TSYNC), GPIO_FN(BBIF1_TSCK),
981 GPIO_FN(BBIF1_TXD), GPIO_FN(BBIF1_RSCK), GPIO_FN(BBIF1_RSYNC), 981 GPIO_FN(BBIF1_TXD), GPIO_FN(BBIF1_RSCK), GPIO_FN(BBIF1_RSYNC),
982 GPIO_FN(BBIF1_FLOW), GPIO_FN(BB_RX_FLOW_N), 982 GPIO_FN(BBIF1_FLOW), GPIO_FN(BB_RX_FLOW_N),
983 983
984 /* MSIOF4 */ 984 /* BBIF2 */
985 GPIO_FN(BBIF2_TSCK1), GPIO_FN(BBIF2_TSYNC1), 985 GPIO_FN(BBIF2_TSCK1), GPIO_FN(BBIF2_TSYNC1),
986 GPIO_FN(BBIF2_TXD1), GPIO_FN(BBIF2_RXD), 986 GPIO_FN(BBIF2_TXD1), GPIO_FN(BBIF2_RXD),
987 987
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c
index 3148c11a550e..003008c18360 100644
--- a/arch/arm/mach-shmobile/setup-sh7367.c
+++ b/arch/arm/mach-shmobile/setup-sh7367.c
@@ -154,7 +154,6 @@ static struct sh_timer_config cmt10_platform_data = {
154 .name = "CMT10", 154 .name = "CMT10",
155 .channel_offset = 0x10, 155 .channel_offset = 0x10,
156 .timer_bit = 0, 156 .timer_bit = 0,
157 .clk = "r_clk",
158 .clockevent_rating = 125, 157 .clockevent_rating = 125,
159 .clocksource_rating = 125, 158 .clocksource_rating = 125,
160}; 159};
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index e26686c9d0b6..564a6d0be473 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -158,7 +158,6 @@ static struct sh_timer_config cmt10_platform_data = {
158 .name = "CMT10", 158 .name = "CMT10",
159 .channel_offset = 0x10, 159 .channel_offset = 0x10,
160 .timer_bit = 0, 160 .timer_bit = 0,
161 .clk = "cmt1",
162 .clockevent_rating = 125, 161 .clockevent_rating = 125,
163 .clocksource_rating = 125, 162 .clocksource_rating = 125,
164}; 163};
@@ -186,6 +185,67 @@ static struct platform_device cmt10_device = {
186 .num_resources = ARRAY_SIZE(cmt10_resources), 185 .num_resources = ARRAY_SIZE(cmt10_resources),
187}; 186};
188 187
188/* TMU */
189static struct sh_timer_config tmu00_platform_data = {
190 .name = "TMU00",
191 .channel_offset = 0x4,
192 .timer_bit = 0,
193 .clockevent_rating = 200,
194};
195
196static struct resource tmu00_resources[] = {
197 [0] = {
198 .name = "TMU00",
199 .start = 0xfff60008,
200 .end = 0xfff60013,
201 .flags = IORESOURCE_MEM,
202 },
203 [1] = {
204 .start = intcs_evt2irq(0xe80), /* TMU_TUNI0 */
205 .flags = IORESOURCE_IRQ,
206 },
207};
208
209static struct platform_device tmu00_device = {
210 .name = "sh_tmu",
211 .id = 0,
212 .dev = {
213 .platform_data = &tmu00_platform_data,
214 },
215 .resource = tmu00_resources,
216 .num_resources = ARRAY_SIZE(tmu00_resources),
217};
218
219static struct sh_timer_config tmu01_platform_data = {
220 .name = "TMU01",
221 .channel_offset = 0x10,
222 .timer_bit = 1,
223 .clocksource_rating = 200,
224};
225
226static struct resource tmu01_resources[] = {
227 [0] = {
228 .name = "TMU01",
229 .start = 0xfff60014,
230 .end = 0xfff6001f,
231 .flags = IORESOURCE_MEM,
232 },
233 [1] = {
234 .start = intcs_evt2irq(0xea0), /* TMU_TUNI1 */
235 .flags = IORESOURCE_IRQ,
236 },
237};
238
239static struct platform_device tmu01_device = {
240 .name = "sh_tmu",
241 .id = 1,
242 .dev = {
243 .platform_data = &tmu01_platform_data,
244 },
245 .resource = tmu01_resources,
246 .num_resources = ARRAY_SIZE(tmu01_resources),
247};
248
189/* I2C */ 249/* I2C */
190static struct resource iic0_resources[] = { 250static struct resource iic0_resources[] = {
191 [0] = { 251 [0] = {
@@ -419,14 +479,14 @@ static struct resource sh7372_dmae0_resources[] = {
419 }, 479 },
420 { 480 {
421 /* DMA error IRQ */ 481 /* DMA error IRQ */
422 .start = 246, 482 .start = evt2irq(0x20c0),
423 .end = 246, 483 .end = evt2irq(0x20c0),
424 .flags = IORESOURCE_IRQ, 484 .flags = IORESOURCE_IRQ,
425 }, 485 },
426 { 486 {
427 /* IRQ for channels 0-5 */ 487 /* IRQ for channels 0-5 */
428 .start = 240, 488 .start = evt2irq(0x2000),
429 .end = 245, 489 .end = evt2irq(0x20a0),
430 .flags = IORESOURCE_IRQ, 490 .flags = IORESOURCE_IRQ,
431 }, 491 },
432}; 492};
@@ -447,14 +507,14 @@ static struct resource sh7372_dmae1_resources[] = {
447 }, 507 },
448 { 508 {
449 /* DMA error IRQ */ 509 /* DMA error IRQ */
450 .start = 254, 510 .start = evt2irq(0x21c0),
451 .end = 254, 511 .end = evt2irq(0x21c0),
452 .flags = IORESOURCE_IRQ, 512 .flags = IORESOURCE_IRQ,
453 }, 513 },
454 { 514 {
455 /* IRQ for channels 0-5 */ 515 /* IRQ for channels 0-5 */
456 .start = 248, 516 .start = evt2irq(0x2100),
457 .end = 253, 517 .end = evt2irq(0x21a0),
458 .flags = IORESOURCE_IRQ, 518 .flags = IORESOURCE_IRQ,
459 }, 519 },
460}; 520};
@@ -475,14 +535,14 @@ static struct resource sh7372_dmae2_resources[] = {
475 }, 535 },
476 { 536 {
477 /* DMA error IRQ */ 537 /* DMA error IRQ */
478 .start = 262, 538 .start = evt2irq(0x22c0),
479 .end = 262, 539 .end = evt2irq(0x22c0),
480 .flags = IORESOURCE_IRQ, 540 .flags = IORESOURCE_IRQ,
481 }, 541 },
482 { 542 {
483 /* IRQ for channels 0-5 */ 543 /* IRQ for channels 0-5 */
484 .start = 256, 544 .start = evt2irq(0x2200),
485 .end = 261, 545 .end = evt2irq(0x22a0),
486 .flags = IORESOURCE_IRQ, 546 .flags = IORESOURCE_IRQ,
487 }, 547 },
488}; 548};
@@ -526,6 +586,11 @@ static struct platform_device *sh7372_early_devices[] __initdata = {
526 &scif5_device, 586 &scif5_device,
527 &scif6_device, 587 &scif6_device,
528 &cmt10_device, 588 &cmt10_device,
589 &tmu00_device,
590 &tmu01_device,
591};
592
593static struct platform_device *sh7372_late_devices[] __initdata = {
529 &iic0_device, 594 &iic0_device,
530 &iic1_device, 595 &iic1_device,
531 &dma0_device, 596 &dma0_device,
@@ -537,6 +602,9 @@ void __init sh7372_add_standard_devices(void)
537{ 602{
538 platform_add_devices(sh7372_early_devices, 603 platform_add_devices(sh7372_early_devices,
539 ARRAY_SIZE(sh7372_early_devices)); 604 ARRAY_SIZE(sh7372_early_devices));
605
606 platform_add_devices(sh7372_late_devices,
607 ARRAY_SIZE(sh7372_late_devices));
540} 608}
541 609
542void __init sh7372_add_early_devices(void) 610void __init sh7372_add_early_devices(void)
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c
index bb4adf17dbf4..575dbd6c2f1d 100644
--- a/arch/arm/mach-shmobile/setup-sh7377.c
+++ b/arch/arm/mach-shmobile/setup-sh7377.c
@@ -172,7 +172,6 @@ static struct sh_timer_config cmt10_platform_data = {
172 .name = "CMT10", 172 .name = "CMT10",
173 .channel_offset = 0x10, 173 .channel_offset = 0x10,
174 .timer_bit = 0, 174 .timer_bit = 0,
175 .clk = "r_clk",
176 .clockevent_rating = 125, 175 .clockevent_rating = 125,
177 .clocksource_rating = 125, 176 .clocksource_rating = 125,
178}; 177};
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index e0fd747e447a..73fb1a551ec6 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -10,6 +10,7 @@
10#include <linux/io.h> 10#include <linux/io.h>
11#include <linux/clk.h> 11#include <linux/clk.h>
12 12
13#include <asm/cacheflush.h>
13#include <asm/hardware/cache-l2x0.h> 14#include <asm/hardware/cache-l2x0.h>
14#include <asm/hardware/gic.h> 15#include <asm/hardware/gic.h>
15#include <asm/mach/map.h> 16#include <asm/mach/map.h>
@@ -71,6 +72,46 @@ void __init ux500_init_irq(void)
71} 72}
72 73
73#ifdef CONFIG_CACHE_L2X0 74#ifdef CONFIG_CACHE_L2X0
75static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask)
76{
77 /* wait for the operation to complete */
78 while (readl(reg) & mask)
79 ;
80}
81
82static inline void ux500_cache_sync(void)
83{
84 void __iomem *base = __io_address(UX500_L2CC_BASE);
85 writel(0, base + L2X0_CACHE_SYNC);
86 ux500_cache_wait(base + L2X0_CACHE_SYNC, 1);
87}
88
89/*
90 * The L2 cache cannot be turned off in the non-secure world.
91 * Dummy until a secure service is in place.
92 */
93static void ux500_l2x0_disable(void)
94{
95}
96
97/*
98 * This is only called when doing a kexec, just after turning off the L2
99 * and L1 cache, and it is surrounded by a spinlock in the generic version.
100 * However, we're not really turning off the L2 cache right now and the
101 * PL310 does not support exclusive accesses (used to implement the spinlock).
102 * So, the invalidation needs to be done without the spinlock.
103 */
104static void ux500_l2x0_inv_all(void)
105{
106 void __iomem *l2x0_base = __io_address(UX500_L2CC_BASE);
107 uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */
108
109 /* invalidate all ways */
110 writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
111 ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
112 ux500_cache_sync();
113}
114
74static int ux500_l2x0_init(void) 115static int ux500_l2x0_init(void)
75{ 116{
76 void __iomem *l2x0_base; 117 void __iomem *l2x0_base;
@@ -80,6 +121,10 @@ static int ux500_l2x0_init(void)
80 /* 64KB way size, 8 way associativity, force WA */ 121 /* 64KB way size, 8 way associativity, force WA */
81 l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); 122 l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
82 123
124 /* Override invalidate function */
125 outer_cache.disable = ux500_l2x0_disable;
126 outer_cache.inv_all = ux500_l2x0_inv_all;
127
83 return 0; 128 return 0;
84} 129}
85early_initcall(ux500_l2x0_init); 130early_initcall(ux500_l2x0_init);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index a0a2928ae4dd..4414a01e1e8a 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -779,6 +779,14 @@ config CACHE_L2X0
779 help 779 help
780 This option enables the L2x0 PrimeCell. 780 This option enables the L2x0 PrimeCell.
781 781
782config CACHE_PL310
783 bool
784 depends on CACHE_L2X0
785 default y if CPU_V7 && !CPU_V6
786 help
787 This option enables optimisations for the PL310 cache
788 controller.
789
782config CACHE_TAUROS2 790config CACHE_TAUROS2
783 bool "Enable the Tauros2 L2 cache controller" 791 bool "Enable the Tauros2 L2 cache controller"
784 depends on (ARCH_DOVE || ARCH_MMP) 792 depends on (ARCH_DOVE || ARCH_MMP)
diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S
index 7148e53e6078..1fa6f71470de 100644
--- a/arch/arm/mm/cache-fa.S
+++ b/arch/arm/mm/cache-fa.S
@@ -38,6 +38,17 @@
38#define CACHE_DLIMIT (CACHE_DSIZE * 2) 38#define CACHE_DLIMIT (CACHE_DSIZE * 2)
39 39
40/* 40/*
41 * flush_icache_all()
42 *
43 * Unconditionally clean and invalidate the entire icache.
44 */
45ENTRY(fa_flush_icache_all)
46 mov r0, #0
47 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
48 mov pc, lr
49ENDPROC(fa_flush_icache_all)
50
51/*
41 * flush_user_cache_all() 52 * flush_user_cache_all()
42 * 53 *
43 * Clean and invalidate all cache entries in a particular address 54 * Clean and invalidate all cache entries in a particular address
@@ -233,6 +244,7 @@ ENDPROC(fa_dma_unmap_area)
233 244
234 .type fa_cache_fns, #object 245 .type fa_cache_fns, #object
235ENTRY(fa_cache_fns) 246ENTRY(fa_cache_fns)
247 .long fa_flush_icache_all
236 .long fa_flush_kern_cache_all 248 .long fa_flush_kern_cache_all
237 .long fa_flush_user_cache_all 249 .long fa_flush_user_cache_all
238 .long fa_flush_user_cache_range 250 .long fa_flush_user_cache_range
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 9982eb385c0f..170c9bb95866 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -28,14 +28,24 @@
28static void __iomem *l2x0_base; 28static void __iomem *l2x0_base;
29static DEFINE_SPINLOCK(l2x0_lock); 29static DEFINE_SPINLOCK(l2x0_lock);
30static uint32_t l2x0_way_mask; /* Bitmask of active ways */ 30static uint32_t l2x0_way_mask; /* Bitmask of active ways */
31static uint32_t l2x0_size;
31 32
32static inline void cache_wait(void __iomem *reg, unsigned long mask) 33static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
33{ 34{
34 /* wait for the operation to complete */ 35 /* wait for cache operation by line or way to complete */
35 while (readl_relaxed(reg) & mask) 36 while (readl_relaxed(reg) & mask)
36 ; 37 ;
37} 38}
38 39
40#ifdef CONFIG_CACHE_PL310
41static inline void cache_wait(void __iomem *reg, unsigned long mask)
42{
43 /* cache operations by line are atomic on PL310 */
44}
45#else
46#define cache_wait cache_wait_way
47#endif
48
39static inline void cache_sync(void) 49static inline void cache_sync(void)
40{ 50{
41 void __iomem *base = l2x0_base; 51 void __iomem *base = l2x0_base;
@@ -103,14 +113,40 @@ static void l2x0_cache_sync(void)
103 spin_unlock_irqrestore(&l2x0_lock, flags); 113 spin_unlock_irqrestore(&l2x0_lock, flags);
104} 114}
105 115
106static inline void l2x0_inv_all(void) 116static void l2x0_flush_all(void)
117{
118 unsigned long flags;
119
120 /* clean all ways */
121 spin_lock_irqsave(&l2x0_lock, flags);
122 writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
123 cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
124 cache_sync();
125 spin_unlock_irqrestore(&l2x0_lock, flags);
126}
127
128static void l2x0_clean_all(void)
129{
130 unsigned long flags;
131
132 /* clean all ways */
133 spin_lock_irqsave(&l2x0_lock, flags);
134 writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
135 cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
136 cache_sync();
137 spin_unlock_irqrestore(&l2x0_lock, flags);
138}
139
140static void l2x0_inv_all(void)
107{ 141{
108 unsigned long flags; 142 unsigned long flags;
109 143
110 /* invalidate all ways */ 144 /* invalidate all ways */
111 spin_lock_irqsave(&l2x0_lock, flags); 145 spin_lock_irqsave(&l2x0_lock, flags);
146 /* Invalidating when L2 is enabled is a nono */
147 BUG_ON(readl(l2x0_base + L2X0_CTRL) & 1);
112 writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); 148 writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
113 cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); 149 cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
114 cache_sync(); 150 cache_sync();
115 spin_unlock_irqrestore(&l2x0_lock, flags); 151 spin_unlock_irqrestore(&l2x0_lock, flags);
116} 152}
@@ -159,6 +195,11 @@ static void l2x0_clean_range(unsigned long start, unsigned long end)
159 void __iomem *base = l2x0_base; 195 void __iomem *base = l2x0_base;
160 unsigned long flags; 196 unsigned long flags;
161 197
198 if ((end - start) >= l2x0_size) {
199 l2x0_clean_all();
200 return;
201 }
202
162 spin_lock_irqsave(&l2x0_lock, flags); 203 spin_lock_irqsave(&l2x0_lock, flags);
163 start &= ~(CACHE_LINE_SIZE - 1); 204 start &= ~(CACHE_LINE_SIZE - 1);
164 while (start < end) { 205 while (start < end) {
@@ -184,6 +225,11 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
184 void __iomem *base = l2x0_base; 225 void __iomem *base = l2x0_base;
185 unsigned long flags; 226 unsigned long flags;
186 227
228 if ((end - start) >= l2x0_size) {
229 l2x0_flush_all();
230 return;
231 }
232
187 spin_lock_irqsave(&l2x0_lock, flags); 233 spin_lock_irqsave(&l2x0_lock, flags);
188 start &= ~(CACHE_LINE_SIZE - 1); 234 start &= ~(CACHE_LINE_SIZE - 1);
189 while (start < end) { 235 while (start < end) {
@@ -206,10 +252,20 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
206 spin_unlock_irqrestore(&l2x0_lock, flags); 252 spin_unlock_irqrestore(&l2x0_lock, flags);
207} 253}
208 254
255static void l2x0_disable(void)
256{
257 unsigned long flags;
258
259 spin_lock_irqsave(&l2x0_lock, flags);
260 writel(0, l2x0_base + L2X0_CTRL);
261 spin_unlock_irqrestore(&l2x0_lock, flags);
262}
263
209void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) 264void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
210{ 265{
211 __u32 aux; 266 __u32 aux;
212 __u32 cache_id; 267 __u32 cache_id;
268 __u32 way_size = 0;
213 int ways; 269 int ways;
214 const char *type; 270 const char *type;
215 271
@@ -244,6 +300,13 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
244 l2x0_way_mask = (1 << ways) - 1; 300 l2x0_way_mask = (1 << ways) - 1;
245 301
246 /* 302 /*
303 * L2 cache Size = Way size * Number of ways
304 */
305 way_size = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17;
306 way_size = 1 << (way_size + 3);
307 l2x0_size = ways * way_size * SZ_1K;
308
309 /*
247 * Check if l2x0 controller is already enabled. 310 * Check if l2x0 controller is already enabled.
248 * If you are booting from non-secure mode 311 * If you are booting from non-secure mode
249 * accessing the below registers will fault. 312 * accessing the below registers will fault.
@@ -263,8 +326,11 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
263 outer_cache.clean_range = l2x0_clean_range; 326 outer_cache.clean_range = l2x0_clean_range;
264 outer_cache.flush_range = l2x0_flush_range; 327 outer_cache.flush_range = l2x0_flush_range;
265 outer_cache.sync = l2x0_cache_sync; 328 outer_cache.sync = l2x0_cache_sync;
329 outer_cache.flush_all = l2x0_flush_all;
330 outer_cache.inv_all = l2x0_inv_all;
331 outer_cache.disable = l2x0_disable;
266 332
267 printk(KERN_INFO "%s cache controller enabled\n", type); 333 printk(KERN_INFO "%s cache controller enabled\n", type);
268 printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n", 334 printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
269 ways, cache_id, aux); 335 ways, cache_id, aux, l2x0_size);
270} 336}
diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S
index c2ff3c599fee..2e2bc406a18d 100644
--- a/arch/arm/mm/cache-v3.S
+++ b/arch/arm/mm/cache-v3.S
@@ -13,6 +13,15 @@
13#include "proc-macros.S" 13#include "proc-macros.S"
14 14
15/* 15/*
16 * flush_icache_all()
17 *
18 * Unconditionally clean and invalidate the entire icache.
19 */
20ENTRY(v3_flush_icache_all)
21 mov pc, lr
22ENDPROC(v3_flush_icache_all)
23
24/*
16 * flush_user_cache_all() 25 * flush_user_cache_all()
17 * 26 *
18 * Invalidate all cache entries in a particular address 27 * Invalidate all cache entries in a particular address
@@ -122,6 +131,7 @@ ENDPROC(v3_dma_map_area)
122 131
123 .type v3_cache_fns, #object 132 .type v3_cache_fns, #object
124ENTRY(v3_cache_fns) 133ENTRY(v3_cache_fns)
134 .long v3_flush_icache_all
125 .long v3_flush_kern_cache_all 135 .long v3_flush_kern_cache_all
126 .long v3_flush_user_cache_all 136 .long v3_flush_user_cache_all
127 .long v3_flush_user_cache_range 137 .long v3_flush_user_cache_range
diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S
index 4810f7e3e813..a8fefb523f19 100644
--- a/arch/arm/mm/cache-v4.S
+++ b/arch/arm/mm/cache-v4.S
@@ -13,6 +13,15 @@
13#include "proc-macros.S" 13#include "proc-macros.S"
14 14
15/* 15/*
16 * flush_icache_all()
17 *
18 * Unconditionally clean and invalidate the entire icache.
19 */
20ENTRY(v4_flush_icache_all)
21 mov pc, lr
22ENDPROC(v4_flush_icache_all)
23
24/*
16 * flush_user_cache_all() 25 * flush_user_cache_all()
17 * 26 *
18 * Invalidate all cache entries in a particular address 27 * Invalidate all cache entries in a particular address
@@ -134,6 +143,7 @@ ENDPROC(v4_dma_map_area)
134 143
135 .type v4_cache_fns, #object 144 .type v4_cache_fns, #object
136ENTRY(v4_cache_fns) 145ENTRY(v4_cache_fns)
146 .long v4_flush_icache_all
137 .long v4_flush_kern_cache_all 147 .long v4_flush_kern_cache_all
138 .long v4_flush_user_cache_all 148 .long v4_flush_user_cache_all
139 .long v4_flush_user_cache_range 149 .long v4_flush_user_cache_range
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S
index df8368afa102..d3644db467b7 100644
--- a/arch/arm/mm/cache-v4wb.S
+++ b/arch/arm/mm/cache-v4wb.S
@@ -51,6 +51,17 @@ flush_base:
51 .text 51 .text
52 52
53/* 53/*
54 * flush_icache_all()
55 *
56 * Unconditionally clean and invalidate the entire icache.
57 */
58ENTRY(v4wb_flush_icache_all)
59 mov r0, #0
60 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
61 mov pc, lr
62ENDPROC(v4wb_flush_icache_all)
63
64/*
54 * flush_user_cache_all() 65 * flush_user_cache_all()
55 * 66 *
56 * Clean and invalidate all cache entries in a particular address 67 * Clean and invalidate all cache entries in a particular address
@@ -244,6 +255,7 @@ ENDPROC(v4wb_dma_unmap_area)
244 255
245 .type v4wb_cache_fns, #object 256 .type v4wb_cache_fns, #object
246ENTRY(v4wb_cache_fns) 257ENTRY(v4wb_cache_fns)
258 .long v4wb_flush_icache_all
247 .long v4wb_flush_kern_cache_all 259 .long v4wb_flush_kern_cache_all
248 .long v4wb_flush_user_cache_all 260 .long v4wb_flush_user_cache_all
249 .long v4wb_flush_user_cache_range 261 .long v4wb_flush_user_cache_range
diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S
index 45c70312f43b..49c2b66cf3dd 100644
--- a/arch/arm/mm/cache-v4wt.S
+++ b/arch/arm/mm/cache-v4wt.S
@@ -41,6 +41,17 @@
41#define CACHE_DLIMIT 16384 41#define CACHE_DLIMIT 16384
42 42
43/* 43/*
44 * flush_icache_all()
45 *
46 * Unconditionally clean and invalidate the entire icache.
47 */
48ENTRY(v4wt_flush_icache_all)
49 mov r0, #0
50 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
51 mov pc, lr
52ENDPROC(v4wt_flush_icache_all)
53
54/*
44 * flush_user_cache_all() 55 * flush_user_cache_all()
45 * 56 *
46 * Invalidate all cache entries in a particular address 57 * Invalidate all cache entries in a particular address
@@ -188,6 +199,7 @@ ENDPROC(v4wt_dma_map_area)
188 199
189 .type v4wt_cache_fns, #object 200 .type v4wt_cache_fns, #object
190ENTRY(v4wt_cache_fns) 201ENTRY(v4wt_cache_fns)
202 .long v4wt_flush_icache_all
191 .long v4wt_flush_kern_cache_all 203 .long v4wt_flush_kern_cache_all
192 .long v4wt_flush_user_cache_all 204 .long v4wt_flush_user_cache_all
193 .long v4wt_flush_user_cache_range 205 .long v4wt_flush_user_cache_range
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index c493d7244d3d..83e59f870426 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -66,6 +66,30 @@ static int do_adjust_pte(struct vm_area_struct *vma, unsigned long address,
66 return ret; 66 return ret;
67} 67}
68 68
69#if USE_SPLIT_PTLOCKS
70/*
71 * If we are using split PTE locks, then we need to take the page
72 * lock here. Otherwise we are using shared mm->page_table_lock
73 * which is already locked, thus cannot take it.
74 */
75static inline void do_pte_lock(spinlock_t *ptl)
76{
77 /*
78 * Use nested version here to indicate that we are already
79 * holding one similar spinlock.
80 */
81 spin_lock_nested(ptl, SINGLE_DEPTH_NESTING);
82}
83
84static inline void do_pte_unlock(spinlock_t *ptl)
85{
86 spin_unlock(ptl);
87}
88#else /* !USE_SPLIT_PTLOCKS */
89static inline void do_pte_lock(spinlock_t *ptl) {}
90static inline void do_pte_unlock(spinlock_t *ptl) {}
91#endif /* USE_SPLIT_PTLOCKS */
92
69static int adjust_pte(struct vm_area_struct *vma, unsigned long address, 93static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
70 unsigned long pfn) 94 unsigned long pfn)
71{ 95{
@@ -90,11 +114,11 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
90 */ 114 */
91 ptl = pte_lockptr(vma->vm_mm, pmd); 115 ptl = pte_lockptr(vma->vm_mm, pmd);
92 pte = pte_offset_map(pmd, address); 116 pte = pte_offset_map(pmd, address);
93 spin_lock(ptl); 117 do_pte_lock(ptl);
94 118
95 ret = do_adjust_pte(vma, address, pfn, pte); 119 ret = do_adjust_pte(vma, address, pfn, pte);
96 120
97 spin_unlock(ptl); 121 do_pte_unlock(ptl);
98 pte_unmap(pte); 122 pte_unmap(pte);
99 123
100 return ret; 124 return ret;
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 7fd9b5eb177f..5164069ced42 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -18,6 +18,7 @@
18#include <linux/highmem.h> 18#include <linux/highmem.h>
19#include <linux/gfp.h> 19#include <linux/gfp.h>
20#include <linux/memblock.h> 20#include <linux/memblock.h>
21#include <linux/sort.h>
21 22
22#include <asm/mach-types.h> 23#include <asm/mach-types.h>
23#include <asm/sections.h> 24#include <asm/sections.h>
@@ -121,9 +122,10 @@ void show_mem(void)
121 printk("%d pages swap cached\n", cached); 122 printk("%d pages swap cached\n", cached);
122} 123}
123 124
124static void __init find_limits(struct meminfo *mi, 125static void __init find_limits(unsigned long *min, unsigned long *max_low,
125 unsigned long *min, unsigned long *max_low, unsigned long *max_high) 126 unsigned long *max_high)
126{ 127{
128 struct meminfo *mi = &meminfo;
127 int i; 129 int i;
128 130
129 *min = -1UL; 131 *min = -1UL;
@@ -147,14 +149,13 @@ static void __init find_limits(struct meminfo *mi,
147 } 149 }
148} 150}
149 151
150static void __init arm_bootmem_init(struct meminfo *mi, 152static void __init arm_bootmem_init(unsigned long start_pfn,
151 unsigned long start_pfn, unsigned long end_pfn) 153 unsigned long end_pfn)
152{ 154{
153 struct memblock_region *reg; 155 struct memblock_region *reg;
154 unsigned int boot_pages; 156 unsigned int boot_pages;
155 phys_addr_t bitmap; 157 phys_addr_t bitmap;
156 pg_data_t *pgdat; 158 pg_data_t *pgdat;
157 int i;
158 159
159 /* 160 /*
160 * Allocate the bootmem bitmap page. This must be in a region 161 * Allocate the bootmem bitmap page. This must be in a region
@@ -172,30 +173,39 @@ static void __init arm_bootmem_init(struct meminfo *mi,
172 pgdat = NODE_DATA(0); 173 pgdat = NODE_DATA(0);
173 init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn); 174 init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn);
174 175
175 for_each_bank(i, mi) { 176 /* Free the lowmem regions from memblock into bootmem. */
176 struct membank *bank = &mi->bank[i]; 177 for_each_memblock(memory, reg) {
177 if (!bank->highmem) 178 unsigned long start = memblock_region_memory_base_pfn(reg);
178 free_bootmem(bank_phys_start(bank), bank_phys_size(bank)); 179 unsigned long end = memblock_region_memory_end_pfn(reg);
180
181 if (end >= end_pfn)
182 end = end_pfn;
183 if (start >= end)
184 break;
185
186 free_bootmem(__pfn_to_phys(start), (end - start) << PAGE_SHIFT);
179 } 187 }
180 188
181 /* 189 /* Reserve the lowmem memblock reserved regions in bootmem. */
182 * Reserve the memblock reserved regions in bootmem.
183 */
184 for_each_memblock(reserved, reg) { 190 for_each_memblock(reserved, reg) {
185 phys_addr_t start = memblock_region_reserved_base_pfn(reg); 191 unsigned long start = memblock_region_reserved_base_pfn(reg);
186 phys_addr_t end = memblock_region_reserved_end_pfn(reg); 192 unsigned long end = memblock_region_reserved_end_pfn(reg);
187 if (start >= start_pfn && end <= end_pfn) 193
188 reserve_bootmem_node(pgdat, __pfn_to_phys(start), 194 if (end >= end_pfn)
189 (end - start) << PAGE_SHIFT, 195 end = end_pfn;
190 BOOTMEM_DEFAULT); 196 if (start >= end)
197 break;
198
199 reserve_bootmem(__pfn_to_phys(start),
200 (end - start) << PAGE_SHIFT, BOOTMEM_DEFAULT);
191 } 201 }
192} 202}
193 203
194static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min, 204static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
195 unsigned long max_low, unsigned long max_high) 205 unsigned long max_high)
196{ 206{
197 unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; 207 unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
198 int i; 208 struct memblock_region *reg;
199 209
200 /* 210 /*
201 * initialise the zones. 211 * initialise the zones.
@@ -217,13 +227,20 @@ static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min,
217 * holes = node_size - sum(bank_sizes) 227 * holes = node_size - sum(bank_sizes)
218 */ 228 */
219 memcpy(zhole_size, zone_size, sizeof(zhole_size)); 229 memcpy(zhole_size, zone_size, sizeof(zhole_size));
220 for_each_bank(i, mi) { 230 for_each_memblock(memory, reg) {
221 int idx = 0; 231 unsigned long start = memblock_region_memory_base_pfn(reg);
232 unsigned long end = memblock_region_memory_end_pfn(reg);
233
234 if (start < max_low) {
235 unsigned long low_end = min(end, max_low);
236 zhole_size[0] -= low_end - start;
237 }
222#ifdef CONFIG_HIGHMEM 238#ifdef CONFIG_HIGHMEM
223 if (mi->bank[i].highmem) 239 if (end > max_low) {
224 idx = ZONE_HIGHMEM; 240 unsigned long high_start = max(start, max_low);
241 zhole_size[ZONE_HIGHMEM] -= end - high_start;
242 }
225#endif 243#endif
226 zhole_size[idx] -= bank_pfn_size(&mi->bank[i]);
227 } 244 }
228 245
229 /* 246 /*
@@ -256,10 +273,19 @@ static void arm_memory_present(void)
256} 273}
257#endif 274#endif
258 275
276static int __init meminfo_cmp(const void *_a, const void *_b)
277{
278 const struct membank *a = _a, *b = _b;
279 long cmp = bank_pfn_start(a) - bank_pfn_start(b);
280 return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
281}
282
259void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) 283void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
260{ 284{
261 int i; 285 int i;
262 286
287 sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
288
263 memblock_init(); 289 memblock_init();
264 for (i = 0; i < mi->nr_banks; i++) 290 for (i = 0; i < mi->nr_banks; i++)
265 memblock_add(mi->bank[i].start, mi->bank[i].size); 291 memblock_add(mi->bank[i].start, mi->bank[i].size);
@@ -292,14 +318,13 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
292 318
293void __init bootmem_init(void) 319void __init bootmem_init(void)
294{ 320{
295 struct meminfo *mi = &meminfo;
296 unsigned long min, max_low, max_high; 321 unsigned long min, max_low, max_high;
297 322
298 max_low = max_high = 0; 323 max_low = max_high = 0;
299 324
300 find_limits(mi, &min, &max_low, &max_high); 325 find_limits(&min, &max_low, &max_high);
301 326
302 arm_bootmem_init(mi, min, max_low); 327 arm_bootmem_init(min, max_low);
303 328
304 /* 329 /*
305 * Sparsemem tries to allocate bootmem in memory_present(), 330 * Sparsemem tries to allocate bootmem in memory_present(),
@@ -317,7 +342,7 @@ void __init bootmem_init(void)
317 * the sparse mem_map arrays initialized by sparse_init() 342 * the sparse mem_map arrays initialized by sparse_init()
318 * for memmap_init_zone(), otherwise all PFNs are invalid. 343 * for memmap_init_zone(), otherwise all PFNs are invalid.
319 */ 344 */
320 arm_bootmem_free(mi, min, max_low, max_high); 345 arm_bootmem_free(min, max_low, max_high);
321 346
322 high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1; 347 high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1;
323 348
@@ -411,6 +436,56 @@ static void __init free_unused_memmap(struct meminfo *mi)
411 } 436 }
412} 437}
413 438
439static void __init free_highpages(void)
440{
441#ifdef CONFIG_HIGHMEM
442 unsigned long max_low = max_low_pfn + PHYS_PFN_OFFSET;
443 struct memblock_region *mem, *res;
444
445 /* set highmem page free */
446 for_each_memblock(memory, mem) {
447 unsigned long start = memblock_region_memory_base_pfn(mem);
448 unsigned long end = memblock_region_memory_end_pfn(mem);
449
450 /* Ignore complete lowmem entries */
451 if (end <= max_low)
452 continue;
453
454 /* Truncate partial highmem entries */
455 if (start < max_low)
456 start = max_low;
457
458 /* Find and exclude any reserved regions */
459 for_each_memblock(reserved, res) {
460 unsigned long res_start, res_end;
461
462 res_start = memblock_region_reserved_base_pfn(res);
463 res_end = memblock_region_reserved_end_pfn(res);
464
465 if (res_end < start)
466 continue;
467 if (res_start < start)
468 res_start = start;
469 if (res_start > end)
470 res_start = end;
471 if (res_end > end)
472 res_end = end;
473 if (res_start != start)
474 totalhigh_pages += free_area(start, res_start,
475 NULL);
476 start = res_end;
477 if (start == end)
478 break;
479 }
480
481 /* And now free anything which remains */
482 if (start < end)
483 totalhigh_pages += free_area(start, end, NULL);
484 }
485 totalram_pages += totalhigh_pages;
486#endif
487}
488
414/* 489/*
415 * mem_init() marks the free areas in the mem_map and tells us how much 490 * mem_init() marks the free areas in the mem_map and tells us how much
416 * memory is free. This is done after various parts of the system have 491 * memory is free. This is done after various parts of the system have
@@ -419,6 +494,7 @@ static void __init free_unused_memmap(struct meminfo *mi)
419void __init mem_init(void) 494void __init mem_init(void)
420{ 495{
421 unsigned long reserved_pages, free_pages; 496 unsigned long reserved_pages, free_pages;
497 struct memblock_region *reg;
422 int i; 498 int i;
423#ifdef CONFIG_HAVE_TCM 499#ifdef CONFIG_HAVE_TCM
424 /* These pointers are filled in on TCM detection */ 500 /* These pointers are filled in on TCM detection */
@@ -439,16 +515,7 @@ void __init mem_init(void)
439 __phys_to_pfn(__pa(swapper_pg_dir)), NULL); 515 __phys_to_pfn(__pa(swapper_pg_dir)), NULL);
440#endif 516#endif
441 517
442#ifdef CONFIG_HIGHMEM 518 free_highpages();
443 /* set highmem page free */
444 for_each_bank (i, &meminfo) {
445 unsigned long start = bank_pfn_start(&meminfo.bank[i]);
446 unsigned long end = bank_pfn_end(&meminfo.bank[i]);
447 if (start >= max_low_pfn + PHYS_PFN_OFFSET)
448 totalhigh_pages += free_area(start, end, NULL);
449 }
450 totalram_pages += totalhigh_pages;
451#endif
452 519
453 reserved_pages = free_pages = 0; 520 reserved_pages = free_pages = 0;
454 521
@@ -478,9 +545,11 @@ void __init mem_init(void)
478 */ 545 */
479 printk(KERN_INFO "Memory:"); 546 printk(KERN_INFO "Memory:");
480 num_physpages = 0; 547 num_physpages = 0;
481 for (i = 0; i < meminfo.nr_banks; i++) { 548 for_each_memblock(memory, reg) {
482 num_physpages += bank_pfn_size(&meminfo.bank[i]); 549 unsigned long pages = memblock_region_memory_end_pfn(reg) -
483 printk(" %ldMB", bank_phys_size(&meminfo.bank[i]) >> 20); 550 memblock_region_memory_base_pfn(reg);
551 num_physpages += pages;
552 printk(" %ldMB", pages >> (20 - PAGE_SHIFT));
484 } 553 }
485 printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); 554 printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
486 555
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index c32f731d56d3..72ad3e1f56cf 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -14,7 +14,6 @@
14#include <linux/mman.h> 14#include <linux/mman.h>
15#include <linux/nodemask.h> 15#include <linux/nodemask.h>
16#include <linux/memblock.h> 16#include <linux/memblock.h>
17#include <linux/sort.h>
18#include <linux/fs.h> 17#include <linux/fs.h>
19 18
20#include <asm/cputype.h> 19#include <asm/cputype.h>
@@ -265,17 +264,17 @@ static struct mem_type mem_types[] = {
265 .domain = DOMAIN_KERNEL, 264 .domain = DOMAIN_KERNEL,
266 }, 265 },
267 [MT_MEMORY_DTCM] = { 266 [MT_MEMORY_DTCM] = {
268 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | 267 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
269 L_PTE_DIRTY | L_PTE_WRITE, 268 L_PTE_WRITE,
270 .prot_l1 = PMD_TYPE_TABLE, 269 .prot_l1 = PMD_TYPE_TABLE,
271 .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, 270 .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
272 .domain = DOMAIN_KERNEL, 271 .domain = DOMAIN_KERNEL,
273 }, 272 },
274 [MT_MEMORY_ITCM] = { 273 [MT_MEMORY_ITCM] = {
275 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 274 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
276 L_PTE_USER | L_PTE_EXEC, 275 L_PTE_WRITE | L_PTE_EXEC,
277 .prot_l1 = PMD_TYPE_TABLE, 276 .prot_l1 = PMD_TYPE_TABLE,
278 .domain = DOMAIN_IO, 277 .domain = DOMAIN_KERNEL,
279 }, 278 },
280}; 279};
281 280
@@ -745,13 +744,14 @@ static int __init early_vmalloc(char *arg)
745} 744}
746early_param("vmalloc", early_vmalloc); 745early_param("vmalloc", early_vmalloc);
747 746
748phys_addr_t lowmem_end_addr; 747static phys_addr_t lowmem_limit __initdata = 0;
749 748
750static void __init sanity_check_meminfo(void) 749static void __init sanity_check_meminfo(void)
751{ 750{
752 int i, j, highmem = 0; 751 int i, j, highmem = 0;
753 752
754 lowmem_end_addr = __pa(vmalloc_min - 1) + 1; 753 lowmem_limit = __pa(vmalloc_min - 1) + 1;
754 memblock_set_current_limit(lowmem_limit);
755 755
756 for (i = 0, j = 0; i < meminfo.nr_banks; i++) { 756 for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
757 struct membank *bank = &meminfo.bank[j]; 757 struct membank *bank = &meminfo.bank[j];
@@ -852,6 +852,7 @@ static void __init sanity_check_meminfo(void)
852static inline void prepare_page_table(void) 852static inline void prepare_page_table(void)
853{ 853{
854 unsigned long addr; 854 unsigned long addr;
855 phys_addr_t end;
855 856
856 /* 857 /*
857 * Clear out all the mappings below the kernel image. 858 * Clear out all the mappings below the kernel image.
@@ -867,10 +868,17 @@ static inline void prepare_page_table(void)
867 pmd_clear(pmd_off_k(addr)); 868 pmd_clear(pmd_off_k(addr));
868 869
869 /* 870 /*
871 * Find the end of the first block of lowmem.
872 */
873 end = memblock.memory.regions[0].base + memblock.memory.regions[0].size;
874 if (end >= lowmem_limit)
875 end = lowmem_limit;
876
877 /*
870 * Clear out all the kernel space mappings, except for the first 878 * Clear out all the kernel space mappings, except for the first
871 * memory bank, up to the end of the vmalloc region. 879 * memory bank, up to the end of the vmalloc region.
872 */ 880 */
873 for (addr = __phys_to_virt(bank_phys_end(&meminfo.bank[0])); 881 for (addr = __phys_to_virt(end);
874 addr < VMALLOC_END; addr += PGDIR_SIZE) 882 addr < VMALLOC_END; addr += PGDIR_SIZE)
875 pmd_clear(pmd_off_k(addr)); 883 pmd_clear(pmd_off_k(addr));
876} 884}
@@ -987,37 +995,28 @@ static void __init kmap_init(void)
987#endif 995#endif
988} 996}
989 997
990static inline void map_memory_bank(struct membank *bank)
991{
992 struct map_desc map;
993
994 map.pfn = bank_pfn_start(bank);
995 map.virtual = __phys_to_virt(bank_phys_start(bank));
996 map.length = bank_phys_size(bank);
997 map.type = MT_MEMORY;
998
999 create_mapping(&map);
1000}
1001
1002static void __init map_lowmem(void) 998static void __init map_lowmem(void)
1003{ 999{
1004 struct meminfo *mi = &meminfo; 1000 struct memblock_region *reg;
1005 int i;
1006 1001
1007 /* Map all the lowmem memory banks. */ 1002 /* Map all the lowmem memory banks. */
1008 for (i = 0; i < mi->nr_banks; i++) { 1003 for_each_memblock(memory, reg) {
1009 struct membank *bank = &mi->bank[i]; 1004 phys_addr_t start = reg->base;
1005 phys_addr_t end = start + reg->size;
1006 struct map_desc map;
1007
1008 if (end > lowmem_limit)
1009 end = lowmem_limit;
1010 if (start >= end)
1011 break;
1010 1012
1011 if (!bank->highmem) 1013 map.pfn = __phys_to_pfn(start);
1012 map_memory_bank(bank); 1014 map.virtual = __phys_to_virt(start);
1013 } 1015 map.length = end - start;
1014} 1016 map.type = MT_MEMORY;
1015 1017
1016static int __init meminfo_cmp(const void *_a, const void *_b) 1018 create_mapping(&map);
1017{ 1019 }
1018 const struct membank *a = _a, *b = _b;
1019 long cmp = bank_pfn_start(a) - bank_pfn_start(b);
1020 return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
1021} 1020}
1022 1021
1023/* 1022/*
@@ -1028,8 +1027,6 @@ void __init paging_init(struct machine_desc *mdesc)
1028{ 1027{
1029 void *zero_page; 1028 void *zero_page;
1030 1029
1031 sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
1032
1033 build_mem_type_table(); 1030 build_mem_type_table();
1034 sanity_check_meminfo(); 1031 sanity_check_meminfo();
1035 prepare_page_table(); 1032 prepare_page_table();
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index a6f5f8475b96..bcf748d9f4e2 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -119,6 +119,20 @@ ENTRY(cpu_arm1020_do_idle)
119/* ================================= CACHE ================================ */ 119/* ================================= CACHE ================================ */
120 120
121 .align 5 121 .align 5
122
123/*
124 * flush_icache_all()
125 *
126 * Unconditionally clean and invalidate the entire icache.
127 */
128ENTRY(arm1020_flush_icache_all)
129#ifndef CONFIG_CPU_ICACHE_DISABLE
130 mov r0, #0
131 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
132#endif
133 mov pc, lr
134ENDPROC(arm1020_flush_icache_all)
135
122/* 136/*
123 * flush_user_cache_all() 137 * flush_user_cache_all()
124 * 138 *
@@ -351,6 +365,7 @@ ENTRY(arm1020_dma_unmap_area)
351ENDPROC(arm1020_dma_unmap_area) 365ENDPROC(arm1020_dma_unmap_area)
352 366
353ENTRY(arm1020_cache_fns) 367ENTRY(arm1020_cache_fns)
368 .long arm1020_flush_icache_all
354 .long arm1020_flush_kern_cache_all 369 .long arm1020_flush_kern_cache_all
355 .long arm1020_flush_user_cache_all 370 .long arm1020_flush_user_cache_all
356 .long arm1020_flush_user_cache_range 371 .long arm1020_flush_user_cache_range
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index afc06b9c3133..ab7ec26657ea 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -119,6 +119,20 @@ ENTRY(cpu_arm1020e_do_idle)
119/* ================================= CACHE ================================ */ 119/* ================================= CACHE ================================ */
120 120
121 .align 5 121 .align 5
122
123/*
124 * flush_icache_all()
125 *
126 * Unconditionally clean and invalidate the entire icache.
127 */
128ENTRY(arm1020e_flush_icache_all)
129#ifndef CONFIG_CPU_ICACHE_DISABLE
130 mov r0, #0
131 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
132#endif
133 mov pc, lr
134ENDPROC(arm1020e_flush_icache_all)
135
122/* 136/*
123 * flush_user_cache_all() 137 * flush_user_cache_all()
124 * 138 *
@@ -337,6 +351,7 @@ ENTRY(arm1020e_dma_unmap_area)
337ENDPROC(arm1020e_dma_unmap_area) 351ENDPROC(arm1020e_dma_unmap_area)
338 352
339ENTRY(arm1020e_cache_fns) 353ENTRY(arm1020e_cache_fns)
354 .long arm1020e_flush_icache_all
340 .long arm1020e_flush_kern_cache_all 355 .long arm1020e_flush_kern_cache_all
341 .long arm1020e_flush_user_cache_all 356 .long arm1020e_flush_user_cache_all
342 .long arm1020e_flush_user_cache_range 357 .long arm1020e_flush_user_cache_range
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 8915e0ba3fe5..831c5e54e22f 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -108,6 +108,20 @@ ENTRY(cpu_arm1022_do_idle)
108/* ================================= CACHE ================================ */ 108/* ================================= CACHE ================================ */
109 109
110 .align 5 110 .align 5
111
112/*
113 * flush_icache_all()
114 *
115 * Unconditionally clean and invalidate the entire icache.
116 */
117ENTRY(arm1022_flush_icache_all)
118#ifndef CONFIG_CPU_ICACHE_DISABLE
119 mov r0, #0
120 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
121#endif
122 mov pc, lr
123ENDPROC(arm1022_flush_icache_all)
124
111/* 125/*
112 * flush_user_cache_all() 126 * flush_user_cache_all()
113 * 127 *
@@ -326,6 +340,7 @@ ENTRY(arm1022_dma_unmap_area)
326ENDPROC(arm1022_dma_unmap_area) 340ENDPROC(arm1022_dma_unmap_area)
327 341
328ENTRY(arm1022_cache_fns) 342ENTRY(arm1022_cache_fns)
343 .long arm1022_flush_icache_all
329 .long arm1022_flush_kern_cache_all 344 .long arm1022_flush_kern_cache_all
330 .long arm1022_flush_user_cache_all 345 .long arm1022_flush_user_cache_all
331 .long arm1022_flush_user_cache_range 346 .long arm1022_flush_user_cache_range
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index ff446c5d476f..e3f7e9a166bf 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -108,6 +108,20 @@ ENTRY(cpu_arm1026_do_idle)
108/* ================================= CACHE ================================ */ 108/* ================================= CACHE ================================ */
109 109
110 .align 5 110 .align 5
111
112/*
113 * flush_icache_all()
114 *
115 * Unconditionally clean and invalidate the entire icache.
116 */
117ENTRY(arm1026_flush_icache_all)
118#ifndef CONFIG_CPU_ICACHE_DISABLE
119 mov r0, #0
120 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
121#endif
122 mov pc, lr
123ENDPROC(arm1026_flush_icache_all)
124
111/* 125/*
112 * flush_user_cache_all() 126 * flush_user_cache_all()
113 * 127 *
@@ -320,6 +334,7 @@ ENTRY(arm1026_dma_unmap_area)
320ENDPROC(arm1026_dma_unmap_area) 334ENDPROC(arm1026_dma_unmap_area)
321 335
322ENTRY(arm1026_cache_fns) 336ENTRY(arm1026_cache_fns)
337 .long arm1026_flush_icache_all
323 .long arm1026_flush_kern_cache_all 338 .long arm1026_flush_kern_cache_all
324 .long arm1026_flush_user_cache_all 339 .long arm1026_flush_user_cache_all
325 .long arm1026_flush_user_cache_range 340 .long arm1026_flush_user_cache_range
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index fecf570939f3..6109f278a904 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -110,6 +110,17 @@ ENTRY(cpu_arm920_do_idle)
110#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH 110#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
111 111
112/* 112/*
113 * flush_icache_all()
114 *
115 * Unconditionally clean and invalidate the entire icache.
116 */
117ENTRY(arm920_flush_icache_all)
118 mov r0, #0
119 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
120 mov pc, lr
121ENDPROC(arm920_flush_icache_all)
122
123/*
113 * flush_user_cache_all() 124 * flush_user_cache_all()
114 * 125 *
115 * Invalidate all cache entries in a particular address 126 * Invalidate all cache entries in a particular address
@@ -305,6 +316,7 @@ ENTRY(arm920_dma_unmap_area)
305ENDPROC(arm920_dma_unmap_area) 316ENDPROC(arm920_dma_unmap_area)
306 317
307ENTRY(arm920_cache_fns) 318ENTRY(arm920_cache_fns)
319 .long arm920_flush_icache_all
308 .long arm920_flush_kern_cache_all 320 .long arm920_flush_kern_cache_all
309 .long arm920_flush_user_cache_all 321 .long arm920_flush_user_cache_all
310 .long arm920_flush_user_cache_range 322 .long arm920_flush_user_cache_range
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index e3cbf87c9480..bb2f0f46a5e6 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -112,6 +112,17 @@ ENTRY(cpu_arm922_do_idle)
112#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH 112#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
113 113
114/* 114/*
115 * flush_icache_all()
116 *
117 * Unconditionally clean and invalidate the entire icache.
118 */
119ENTRY(arm922_flush_icache_all)
120 mov r0, #0
121 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
122 mov pc, lr
123ENDPROC(arm922_flush_icache_all)
124
125/*
115 * flush_user_cache_all() 126 * flush_user_cache_all()
116 * 127 *
117 * Clean and invalidate all cache entries in a particular 128 * Clean and invalidate all cache entries in a particular
@@ -307,6 +318,7 @@ ENTRY(arm922_dma_unmap_area)
307ENDPROC(arm922_dma_unmap_area) 318ENDPROC(arm922_dma_unmap_area)
308 319
309ENTRY(arm922_cache_fns) 320ENTRY(arm922_cache_fns)
321 .long arm922_flush_icache_all
310 .long arm922_flush_kern_cache_all 322 .long arm922_flush_kern_cache_all
311 .long arm922_flush_user_cache_all 323 .long arm922_flush_user_cache_all
312 .long arm922_flush_user_cache_range 324 .long arm922_flush_user_cache_range
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 572424c867b5..c13e01accfe2 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -145,6 +145,17 @@ ENTRY(cpu_arm925_do_idle)
145 mov pc, lr 145 mov pc, lr
146 146
147/* 147/*
148 * flush_icache_all()
149 *
150 * Unconditionally clean and invalidate the entire icache.
151 */
152ENTRY(arm925_flush_icache_all)
153 mov r0, #0
154 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
155 mov pc, lr
156ENDPROC(arm925_flush_icache_all)
157
158/*
148 * flush_user_cache_all() 159 * flush_user_cache_all()
149 * 160 *
150 * Clean and invalidate all cache entries in a particular 161 * Clean and invalidate all cache entries in a particular
@@ -362,6 +373,7 @@ ENTRY(arm925_dma_unmap_area)
362ENDPROC(arm925_dma_unmap_area) 373ENDPROC(arm925_dma_unmap_area)
363 374
364ENTRY(arm925_cache_fns) 375ENTRY(arm925_cache_fns)
376 .long arm925_flush_icache_all
365 .long arm925_flush_kern_cache_all 377 .long arm925_flush_kern_cache_all
366 .long arm925_flush_user_cache_all 378 .long arm925_flush_user_cache_all
367 .long arm925_flush_user_cache_range 379 .long arm925_flush_user_cache_range
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 63d168b4ebe6..42eb4315740b 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -111,6 +111,17 @@ ENTRY(cpu_arm926_do_idle)
111 mov pc, lr 111 mov pc, lr
112 112
113/* 113/*
114 * flush_icache_all()
115 *
116 * Unconditionally clean and invalidate the entire icache.
117 */
118ENTRY(arm926_flush_icache_all)
119 mov r0, #0
120 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
121 mov pc, lr
122ENDPROC(arm926_flush_icache_all)
123
124/*
114 * flush_user_cache_all() 125 * flush_user_cache_all()
115 * 126 *
116 * Clean and invalidate all cache entries in a particular 127 * Clean and invalidate all cache entries in a particular
@@ -325,6 +336,7 @@ ENTRY(arm926_dma_unmap_area)
325ENDPROC(arm926_dma_unmap_area) 336ENDPROC(arm926_dma_unmap_area)
326 337
327ENTRY(arm926_cache_fns) 338ENTRY(arm926_cache_fns)
339 .long arm926_flush_icache_all
328 .long arm926_flush_kern_cache_all 340 .long arm926_flush_kern_cache_all
329 .long arm926_flush_user_cache_all 341 .long arm926_flush_user_cache_all
330 .long arm926_flush_user_cache_range 342 .long arm926_flush_user_cache_range
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index f6a62822418e..7b11cdb9935f 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -68,6 +68,17 @@ ENTRY(cpu_arm940_do_idle)
68 mov pc, lr 68 mov pc, lr
69 69
70/* 70/*
71 * flush_icache_all()
72 *
73 * Unconditionally clean and invalidate the entire icache.
74 */
75ENTRY(arm940_flush_icache_all)
76 mov r0, #0
77 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
78 mov pc, lr
79ENDPROC(arm940_flush_icache_all)
80
81/*
71 * flush_user_cache_all() 82 * flush_user_cache_all()
72 */ 83 */
73ENTRY(arm940_flush_user_cache_all) 84ENTRY(arm940_flush_user_cache_all)
@@ -254,6 +265,7 @@ ENTRY(arm940_dma_unmap_area)
254ENDPROC(arm940_dma_unmap_area) 265ENDPROC(arm940_dma_unmap_area)
255 266
256ENTRY(arm940_cache_fns) 267ENTRY(arm940_cache_fns)
268 .long arm940_flush_icache_all
257 .long arm940_flush_kern_cache_all 269 .long arm940_flush_kern_cache_all
258 .long arm940_flush_user_cache_all 270 .long arm940_flush_user_cache_all
259 .long arm940_flush_user_cache_range 271 .long arm940_flush_user_cache_range
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index ea2e7f2eb95b..1a5bbf080342 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -75,6 +75,17 @@ ENTRY(cpu_arm946_do_idle)
75 mov pc, lr 75 mov pc, lr
76 76
77/* 77/*
78 * flush_icache_all()
79 *
80 * Unconditionally clean and invalidate the entire icache.
81 */
82ENTRY(arm946_flush_icache_all)
83 mov r0, #0
84 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
85 mov pc, lr
86ENDPROC(arm946_flush_icache_all)
87
88/*
78 * flush_user_cache_all() 89 * flush_user_cache_all()
79 */ 90 */
80ENTRY(arm946_flush_user_cache_all) 91ENTRY(arm946_flush_user_cache_all)
@@ -296,6 +307,7 @@ ENTRY(arm946_dma_unmap_area)
296ENDPROC(arm946_dma_unmap_area) 307ENDPROC(arm946_dma_unmap_area)
297 308
298ENTRY(arm946_cache_fns) 309ENTRY(arm946_cache_fns)
310 .long arm946_flush_icache_all
299 .long arm946_flush_kern_cache_all 311 .long arm946_flush_kern_cache_all
300 .long arm946_flush_user_cache_all 312 .long arm946_flush_user_cache_all
301 .long arm946_flush_user_cache_range 313 .long arm946_flush_user_cache_range
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index 578da69200cf..b4597edbff97 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -124,6 +124,17 @@ ENTRY(cpu_feroceon_do_idle)
124 mov pc, lr 124 mov pc, lr
125 125
126/* 126/*
127 * flush_icache_all()
128 *
129 * Unconditionally clean and invalidate the entire icache.
130 */
131ENTRY(feroceon_flush_icache_all)
132 mov r0, #0
133 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
134 mov pc, lr
135ENDPROC(feroceon_flush_icache_all)
136
137/*
127 * flush_user_cache_all() 138 * flush_user_cache_all()
128 * 139 *
129 * Clean and invalidate all cache entries in a particular 140 * Clean and invalidate all cache entries in a particular
@@ -401,6 +412,7 @@ ENTRY(feroceon_dma_unmap_area)
401ENDPROC(feroceon_dma_unmap_area) 412ENDPROC(feroceon_dma_unmap_area)
402 413
403ENTRY(feroceon_cache_fns) 414ENTRY(feroceon_cache_fns)
415 .long feroceon_flush_icache_all
404 .long feroceon_flush_kern_cache_all 416 .long feroceon_flush_kern_cache_all
405 .long feroceon_flush_user_cache_all 417 .long feroceon_flush_user_cache_all
406 .long feroceon_flush_user_cache_range 418 .long feroceon_flush_user_cache_range
@@ -412,6 +424,7 @@ ENTRY(feroceon_cache_fns)
412 .long feroceon_dma_flush_range 424 .long feroceon_dma_flush_range
413 425
414ENTRY(feroceon_range_cache_fns) 426ENTRY(feroceon_range_cache_fns)
427 .long feroceon_flush_icache_all
415 .long feroceon_flush_kern_cache_all 428 .long feroceon_flush_kern_cache_all
416 .long feroceon_flush_user_cache_all 429 .long feroceon_flush_user_cache_all
417 .long feroceon_flush_user_cache_range 430 .long feroceon_flush_user_cache_range
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index cad07e403044..ec26355cb7c2 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -141,6 +141,17 @@ ENTRY(cpu_xsc3_do_idle)
141/* ================================= CACHE ================================ */ 141/* ================================= CACHE ================================ */
142 142
143/* 143/*
144 * flush_icache_all()
145 *
146 * Unconditionally clean and invalidate the entire icache.
147 */
148ENTRY(xsc3_flush_icache_all)
149 mov r0, #0
150 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
151 mov pc, lr
152ENDPROC(xsc3_flush_icache_all)
153
154/*
144 * flush_user_cache_all() 155 * flush_user_cache_all()
145 * 156 *
146 * Invalidate all cache entries in a particular address 157 * Invalidate all cache entries in a particular address
@@ -325,6 +336,7 @@ ENTRY(xsc3_dma_unmap_area)
325ENDPROC(xsc3_dma_unmap_area) 336ENDPROC(xsc3_dma_unmap_area)
326 337
327ENTRY(xsc3_cache_fns) 338ENTRY(xsc3_cache_fns)
339 .long xsc3_flush_icache_all
328 .long xsc3_flush_kern_cache_all 340 .long xsc3_flush_kern_cache_all
329 .long xsc3_flush_user_cache_all 341 .long xsc3_flush_user_cache_all
330 .long xsc3_flush_user_cache_range 342 .long xsc3_flush_user_cache_range
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index cb245edb2c2b..523408c0bb38 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -181,6 +181,17 @@ ENTRY(cpu_xscale_do_idle)
181/* ================================= CACHE ================================ */ 181/* ================================= CACHE ================================ */
182 182
183/* 183/*
184 * flush_icache_all()
185 *
186 * Unconditionally clean and invalidate the entire icache.
187 */
188ENTRY(xscale_flush_icache_all)
189 mov r0, #0
190 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
191 mov pc, lr
192ENDPROC(xscale_flush_icache_all)
193
194/*
184 * flush_user_cache_all() 195 * flush_user_cache_all()
185 * 196 *
186 * Invalidate all cache entries in a particular address 197 * Invalidate all cache entries in a particular address
@@ -397,6 +408,7 @@ ENTRY(xscale_dma_unmap_area)
397ENDPROC(xscale_dma_unmap_area) 408ENDPROC(xscale_dma_unmap_area)
398 409
399ENTRY(xscale_cache_fns) 410ENTRY(xscale_cache_fns)
411 .long xscale_flush_icache_all
400 .long xscale_flush_kern_cache_all 412 .long xscale_flush_kern_cache_all
401 .long xscale_flush_user_cache_all 413 .long xscale_flush_user_cache_all
402 .long xscale_flush_user_cache_range 414 .long xscale_flush_user_cache_range
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 06875b4dd70f..372670952789 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_MXC_USE_EPIT) += epit.o
18obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o 18obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
19obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o 19obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
20obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o 20obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
21obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
21ifdef CONFIG_SND_IMX_SOC 22ifdef CONFIG_SND_IMX_SOC
22obj-y += ssi-fiq.o 23obj-y += ssi-fiq.o
23obj-y += ssi-fiq-ksym.o 24obj-y += ssi-fiq-ksym.o
diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c
new file mode 100644
index 000000000000..039538e68793
--- /dev/null
+++ b/arch/arm/plat-mxc/cpufreq.c
@@ -0,0 +1,206 @@
1/*
2 * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
5/*
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14/*
15 * A driver for the Freescale Semiconductor i.MXC CPUfreq module.
16 * The CPUFREQ driver is for controling CPU frequency. It allows you to change
17 * the CPU clock speed on the fly.
18 */
19
20#include <linux/cpufreq.h>
21#include <linux/clk.h>
22#include <linux/err.h>
23#include <linux/slab.h>
24#include <mach/hardware.h>
25#include <mach/clock.h>
26
27#define CLK32_FREQ 32768
28#define NANOSECOND (1000 * 1000 * 1000)
29
30struct cpu_op *(*get_cpu_op)(int *op);
31
32static int cpu_freq_khz_min;
33static int cpu_freq_khz_max;
34
35static struct clk *cpu_clk;
36static struct cpufreq_frequency_table *imx_freq_table;
37
38static int cpu_op_nr;
39static struct cpu_op *cpu_op_tbl;
40
41static int set_cpu_freq(int freq)
42{
43 int ret = 0;
44 int org_cpu_rate;
45
46 org_cpu_rate = clk_get_rate(cpu_clk);
47 if (org_cpu_rate == freq)
48 return ret;
49
50 ret = clk_set_rate(cpu_clk, freq);
51 if (ret != 0) {
52 printk(KERN_DEBUG "cannot set CPU clock rate\n");
53 return ret;
54 }
55
56 return ret;
57}
58
59static int mxc_verify_speed(struct cpufreq_policy *policy)
60{
61 if (policy->cpu != 0)
62 return -EINVAL;
63
64 return cpufreq_frequency_table_verify(policy, imx_freq_table);
65}
66
67static unsigned int mxc_get_speed(unsigned int cpu)
68{
69 if (cpu)
70 return 0;
71
72 return clk_get_rate(cpu_clk) / 1000;
73}
74
75static int mxc_set_target(struct cpufreq_policy *policy,
76 unsigned int target_freq, unsigned int relation)
77{
78 struct cpufreq_freqs freqs;
79 int freq_Hz;
80 int ret = 0;
81 unsigned int index;
82
83 cpufreq_frequency_table_target(policy, imx_freq_table,
84 target_freq, relation, &index);
85 freq_Hz = imx_freq_table[index].frequency * 1000;
86
87 freqs.old = clk_get_rate(cpu_clk) / 1000;
88 freqs.new = freq_Hz / 1000;
89 freqs.cpu = 0;
90 freqs.flags = 0;
91 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
92
93 ret = set_cpu_freq(freq_Hz);
94
95 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
96
97 return ret;
98}
99
100static int __init mxc_cpufreq_init(struct cpufreq_policy *policy)
101{
102 int ret;
103 int i;
104
105 printk(KERN_INFO "i.MXC CPU frequency driver\n");
106
107 if (policy->cpu != 0)
108 return -EINVAL;
109
110 if (!get_cpu_op)
111 return -EINVAL;
112
113 cpu_clk = clk_get(NULL, "cpu_clk");
114 if (IS_ERR(cpu_clk)) {
115 printk(KERN_ERR "%s: failed to get cpu clock\n", __func__);
116 return PTR_ERR(cpu_clk);
117 }
118
119 cpu_op_tbl = get_cpu_op(&cpu_op_nr);
120
121 cpu_freq_khz_min = cpu_op_tbl[0].cpu_rate / 1000;
122 cpu_freq_khz_max = cpu_op_tbl[0].cpu_rate / 1000;
123
124 imx_freq_table = kmalloc(
125 sizeof(struct cpufreq_frequency_table) * (cpu_op_nr + 1),
126 GFP_KERNEL);
127 if (!imx_freq_table) {
128 ret = -ENOMEM;
129 goto err1;
130 }
131
132 for (i = 0; i < cpu_op_nr; i++) {
133 imx_freq_table[i].index = i;
134 imx_freq_table[i].frequency = cpu_op_tbl[i].cpu_rate / 1000;
135
136 if ((cpu_op_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min)
137 cpu_freq_khz_min = cpu_op_tbl[i].cpu_rate / 1000;
138
139 if ((cpu_op_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max)
140 cpu_freq_khz_max = cpu_op_tbl[i].cpu_rate / 1000;
141 }
142
143 imx_freq_table[i].index = i;
144 imx_freq_table[i].frequency = CPUFREQ_TABLE_END;
145
146 policy->cur = clk_get_rate(cpu_clk) / 1000;
147 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
148 policy->min = policy->cpuinfo.min_freq = cpu_freq_khz_min;
149 policy->max = policy->cpuinfo.max_freq = cpu_freq_khz_max;
150
151 /* Manual states, that PLL stabilizes in two CLK32 periods */
152 policy->cpuinfo.transition_latency = 2 * NANOSECOND / CLK32_FREQ;
153
154 ret = cpufreq_frequency_table_cpuinfo(policy, imx_freq_table);
155
156 if (ret < 0) {
157 printk(KERN_ERR "%s: failed to register i.MXC CPUfreq \
158 with error code %d\n", __func__, ret);
159 goto err;
160 }
161
162 cpufreq_frequency_table_get_attr(imx_freq_table, policy->cpu);
163 return 0;
164err:
165 kfree(imx_freq_table);
166err1:
167 clk_put(cpu_clk);
168 return ret;
169}
170
171static int mxc_cpufreq_exit(struct cpufreq_policy *policy)
172{
173 cpufreq_frequency_table_put_attr(policy->cpu);
174
175 set_cpu_freq(cpu_freq_khz_max * 1000);
176 clk_put(cpu_clk);
177 kfree(imx_freq_table);
178 return 0;
179}
180
181static struct cpufreq_driver mxc_driver = {
182 .flags = CPUFREQ_STICKY,
183 .verify = mxc_verify_speed,
184 .target = mxc_set_target,
185 .get = mxc_get_speed,
186 .init = mxc_cpufreq_init,
187 .exit = mxc_cpufreq_exit,
188 .name = "imx",
189};
190
191static int __devinit mxc_cpufreq_driver_init(void)
192{
193 return cpufreq_register_driver(&mxc_driver);
194}
195
196static void mxc_cpufreq_driver_exit(void)
197{
198 cpufreq_unregister_driver(&mxc_driver);
199}
200
201module_init(mxc_cpufreq_driver_init);
202module_exit(mxc_cpufreq_driver_exit);
203
204MODULE_AUTHOR("Freescale Semiconductor Inc. Yong Shen <yong.shen@linaro.org>");
205MODULE_DESCRIPTION("CPUfreq driver for i.MX");
206MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
index 404799487f17..9aa6f3ea9012 100644
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -6,9 +6,13 @@ config IMX_HAVE_PLATFORM_FEC
6 default y if ARCH_MX25 || SOC_IMX27 || ARCH_MX35 || ARCH_MX51 6 default y if ARCH_MX25 || SOC_IMX27 || ARCH_MX35 || ARCH_MX51
7 7
8config IMX_HAVE_PLATFORM_FLEXCAN 8config IMX_HAVE_PLATFORM_FLEXCAN
9 select HAVE_CAN_FLEXCAN 9 select HAVE_CAN_FLEXCAN if CAN
10 bool 10 bool
11 11
12config IMX_HAVE_PLATFORM_GPIO_KEYS
13 bool
14 default y if ARCH_MX51
15
12config IMX_HAVE_PLATFORM_IMX_I2C 16config IMX_HAVE_PLATFORM_IMX_I2C
13 bool 17 bool
14 18
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
index 0a3c1f089413..45aefeb283ba 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -1,6 +1,7 @@
1obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o 1obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o
2obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o 2obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
3obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o 3obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
4obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o
4obj-y += platform-imx-dma.o 5obj-y += platform-imx-dma.o
5obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o 6obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o
6obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o 7obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o
diff --git a/arch/arm/plat-mxc/devices/platform-gpio_keys.c b/arch/arm/plat-mxc/devices/platform-gpio_keys.c
new file mode 100644
index 000000000000..1c53a532ea0e
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-gpio_keys.c
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17 */
18#include <asm/sizes.h>
19#include <mach/hardware.h>
20#include <mach/devices-common.h>
21
22struct platform_device *__init imx_add_gpio_keys(
23 const struct gpio_keys_platform_data *pdata)
24{
25 return imx_add_platform_device("gpio-keys", -1, NULL,
26 0, pdata, sizeof(*pdata));
27}
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 9d38da077edb..9c3e36232b5b 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/interrupt.h>
23#include <linux/io.h> 24#include <linux/io.h>
24#include <linux/irq.h> 25#include <linux/irq.h>
25#include <linux/gpio.h> 26#include <linux/gpio.h>
@@ -201,11 +202,42 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
201 } 202 }
202} 203}
203 204
205/*
206 * Set interrupt number "irq" in the GPIO as a wake-up source.
207 * While system is running, all registered GPIO interrupts need to have
208 * wake-up enabled. When system is suspended, only selected GPIO interrupts
209 * need to have wake-up enabled.
210 * @param irq interrupt source number
211 * @param enable enable as wake-up if equal to non-zero
212 * @return This function returns 0 on success.
213 */
214static int gpio_set_wake_irq(u32 irq, u32 enable)
215{
216 u32 gpio = irq_to_gpio(irq);
217 u32 gpio_idx = gpio & 0x1F;
218 struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
219
220 if (enable) {
221 if (port->irq_high && (gpio_idx >= 16))
222 enable_irq_wake(port->irq_high);
223 else
224 enable_irq_wake(port->irq);
225 } else {
226 if (port->irq_high && (gpio_idx >= 16))
227 disable_irq_wake(port->irq_high);
228 else
229 disable_irq_wake(port->irq);
230 }
231
232 return 0;
233}
234
204static struct irq_chip gpio_irq_chip = { 235static struct irq_chip gpio_irq_chip = {
205 .ack = gpio_ack_irq, 236 .ack = gpio_ack_irq,
206 .mask = gpio_mask_irq, 237 .mask = gpio_mask_irq,
207 .unmask = gpio_unmask_irq, 238 .unmask = gpio_unmask_irq,
208 .set_type = gpio_set_irq_type, 239 .set_type = gpio_set_irq_type,
240 .set_wake = gpio_set_wake_irq,
209}; 241};
210 242
211static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, 243static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index 86d7575a564d..8c6896fd1e5f 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -29,6 +29,10 @@ struct platform_device *__init imx_add_flexcan(int id,
29 resource_size_t irq, 29 resource_size_t irq,
30 const struct flexcan_platform_data *pdata); 30 const struct flexcan_platform_data *pdata);
31 31
32#include <linux/gpio_keys.h>
33struct platform_device *__init imx_add_gpio_keys(
34 const struct gpio_keys_platform_data *pdata);
35
32#include <mach/i2c.h> 36#include <mach/i2c.h>
33struct imx_imx_i2c_data { 37struct imx_imx_i2c_data {
34 int id; 38 int id;
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
index e46b1c2836d4..d7a41e9a2605 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
@@ -45,6 +45,8 @@ typedef enum iomux_config {
45 PAD_CTL_PKE | PAD_CTL_HYS) 45 PAD_CTL_PKE | PAD_CTL_HYS)
46#define MX51_GPIO_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | \ 46#define MX51_GPIO_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | \
47 PAD_CTL_SRE_FAST) 47 PAD_CTL_SRE_FAST)
48#define MX51_GPIO_PAD_CTRL_2 (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
49 PAD_CTL_PUS_100K_UP)
48#define MX51_ECSPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \ 50#define MX51_ECSPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
49 PAD_CTL_SRE_FAST) 51 PAD_CTL_SRE_FAST)
50#define MX51_SDHCI_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP | \ 52#define MX51_SDHCI_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP | \
diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h
index 03e2afabc9fc..61cfe827498b 100644
--- a/arch/arm/plat-mxc/include/mach/mx31.h
+++ b/arch/arm/plat-mxc/include/mach/mx31.h
@@ -240,7 +240,6 @@ static inline void mx31_setup_weimcs(size_t cs,
240#define MPEG4_ENC_BASE_ADDR MX31_MPEG4_ENC_BASE_ADDR 240#define MPEG4_ENC_BASE_ADDR MX31_MPEG4_ENC_BASE_ADDR
241#define MXC_INT_MPEG4_ENCODER MX31_INT_MPEG4_ENCODER 241#define MXC_INT_MPEG4_ENCODER MX31_INT_MPEG4_ENCODER
242#define MXC_INT_FIRI MX31_INT_FIRI 242#define MXC_INT_FIRI MX31_INT_FIRI
243#define MXC_INT_MMC_SDHC1 MX31_INT_MMC_SDHC1
244#define MXC_INT_MBX MX31_INT_MBX 243#define MXC_INT_MBX MX31_INT_MBX
245#define MXC_INT_CSPI3 MX31_INT_CSPI3 244#define MXC_INT_CSPI3 MX31_INT_CSPI3
246#define MXC_INT_SIM2 MX31_INT_SIM2 245#define MXC_INT_SIM2 MX31_INT_SIM2
diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h
index ff905cb32458..6267cff6035d 100644
--- a/arch/arm/plat-mxc/include/mach/mx35.h
+++ b/arch/arm/plat-mxc/include/mach/mx35.h
@@ -197,8 +197,6 @@
197/* these should go away */ 197/* these should go away */
198#define MXC_FEC_BASE_ADDR MX35_FEC_BASE_ADDR 198#define MXC_FEC_BASE_ADDR MX35_FEC_BASE_ADDR
199#define MXC_INT_OWIRE MX35_INT_OWIRE 199#define MXC_INT_OWIRE MX35_INT_OWIRE
200#define MXC_INT_MMC_SDHC2 MX35_INT_MMC_SDHC2
201#define MXC_INT_MMC_SDHC3 MX35_INT_MMC_SDHC3
202#define MXC_INT_GPU2D MX35_INT_GPU2D 200#define MXC_INT_GPU2D MX35_INT_GPU2D
203#define MXC_INT_ASRC MX35_INT_ASRC 201#define MXC_INT_ASRC MX35_INT_ASRC
204#define MXC_INT_USBHS MX35_INT_USBHS 202#define MXC_INT_USBHS MX35_INT_USBHS
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index a790bf212972..a42c7207082d 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. 2 * Copyright 2004-2007, 2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) 3 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -20,6 +20,8 @@
20#ifndef __ASM_ARCH_MXC_H__ 20#ifndef __ASM_ARCH_MXC_H__
21#define __ASM_ARCH_MXC_H__ 21#define __ASM_ARCH_MXC_H__
22 22
23#include <linux/types.h>
24
23#ifndef __ASM_ARCH_MXC_HARDWARE_H__ 25#ifndef __ASM_ARCH_MXC_HARDWARE_H__
24#error "Do not include directly." 26#error "Do not include directly."
25#endif 27#endif
@@ -133,6 +135,15 @@ extern unsigned int __mxc_cpu_type;
133# define cpu_is_mxc91231() (0) 135# define cpu_is_mxc91231() (0)
134#endif 136#endif
135 137
138#ifndef __ASSEMBLY__
139
140struct cpu_op {
141 u32 cpu_rate;
142};
143
144extern struct cpu_op *(*get_cpu_op)(int *op);
145#endif
146
136#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2) 147#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
137/* These are deprecated, use mx[23][157]_setup_weimcs instead. */ 148/* These are deprecated, use mx[23][157]_setup_weimcs instead. */
138#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10)) 149#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10))
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
index 7b44d0c592b5..bcc43f346272 100644
--- a/arch/arm/plat-s3c24xx/common-smdk.c
+++ b/arch/arm/plat-s3c24xx/common-smdk.c
@@ -147,7 +147,7 @@ static struct mtd_partition smdk_default_nand_part[] = {
147 [7] = { 147 [7] = {
148 .name = "S3C2410 flash partition 7", 148 .name = "S3C2410 flash partition 7",
149 .offset = SZ_1M * 48, 149 .offset = SZ_1M * 48,
150 .size = SZ_16M, 150 .size = MTDPART_SIZ_FULL,
151 } 151 }
152}; 152};
153 153
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
index ae9d3c2403f0..24c6f5a30596 100644
--- a/arch/arm/plat-s3c24xx/gpiolib.c
+++ b/arch/arm/plat-s3c24xx/gpiolib.c
@@ -74,11 +74,6 @@ static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset)
74 return -EINVAL; 74 return -EINVAL;
75} 75}
76 76
77static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset)
78{
79 return IRQ_EINT8 + offset;
80}
81
82static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = { 77static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
83 .set_config = s3c_gpio_setcfg_s3c24xx_a, 78 .set_config = s3c_gpio_setcfg_s3c24xx_a,
84 .get_config = s3c_gpio_getcfg_s3c24xx_a, 79 .get_config = s3c_gpio_getcfg_s3c24xx_a,
@@ -159,12 +154,13 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
159 [6] = { 154 [6] = {
160 .base = S3C2410_GPGCON, 155 .base = S3C2410_GPGCON,
161 .pm = __gpio_pm(&s3c_gpio_pm_2bit), 156 .pm = __gpio_pm(&s3c_gpio_pm_2bit),
157 .irq_base = IRQ_EINT8,
162 .chip = { 158 .chip = {
163 .base = S3C2410_GPG(0), 159 .base = S3C2410_GPG(0),
164 .owner = THIS_MODULE, 160 .owner = THIS_MODULE,
165 .label = "GPIOG", 161 .label = "GPIOG",
166 .ngpio = 16, 162 .ngpio = 16,
167 .to_irq = s3c24xx_gpiolib_bankg_toirq, 163 .to_irq = samsung_gpiolib_to_irq,
168 }, 164 },
169 }, { 165 }, {
170 .base = S3C2410_GPHCON, 166 .base = S3C2410_GPHCON,
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 25960966af7c..65dbfa8e0a86 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -32,6 +32,11 @@ config S5P_EXT_INT
32 Use the external interrupts (other than GPIO interrupts.) 32 Use the external interrupts (other than GPIO interrupts.)
33 Note: Do not choose this for S5P6440 and S5P6450. 33 Note: Do not choose this for S5P6440 and S5P6450.
34 34
35config S5P_GPIO_INT
36 bool
37 help
38 Common code for the GPIO interrupts (other than external interrupts.)
39
35config S5P_DEV_FIMC0 40config S5P_DEV_FIMC0
36 bool 41 bool
37 help 42 help
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index f3e917e27da8..de65238a7aef 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -18,6 +18,9 @@ obj-y += cpu.o
18obj-y += clock.o 18obj-y += clock.o
19obj-y += irq.o 19obj-y += irq.o
20obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o 20obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
21obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
22obj-$(CONFIG_PM) += pm.o
23obj-$(CONFIG_PM) += irq-pm.o
21 24
22# devices 25# devices
23 26
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c
index 8aaf4e6b60c3..8d081d968c58 100644
--- a/arch/arm/plat-s5p/clock.c
+++ b/arch/arm/plat-s5p/clock.c
@@ -21,6 +21,8 @@
21#include <linux/io.h> 21#include <linux/io.h>
22#include <asm/div64.h> 22#include <asm/div64.h>
23 23
24#include <mach/regs-clock.h>
25
24#include <plat/clock.h> 26#include <plat/clock.h>
25#include <plat/clock-clksrc.h> 27#include <plat/clock-clksrc.h>
26#include <plat/s5p-clock.h> 28#include <plat/s5p-clock.h>
@@ -88,14 +90,6 @@ struct clk clk_fout_vpll = {
88 .ctrlbit = (1 << 31), 90 .ctrlbit = (1 << 31),
89}; 91};
90 92
91/* ARM clock */
92struct clk clk_arm = {
93 .name = "armclk",
94 .id = -1,
95 .rate = 0,
96 .ctrlbit = 0,
97};
98
99/* Possible clock sources for APLL Mux */ 93/* Possible clock sources for APLL Mux */
100static struct clk *clk_src_apll_list[] = { 94static struct clk *clk_src_apll_list[] = {
101 [0] = &clk_fin_apll, 95 [0] = &clk_fin_apll,
@@ -156,6 +150,24 @@ int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
156 return 0; 150 return 0;
157} 151}
158 152
153int s5p_epll_enable(struct clk *clk, int enable)
154{
155 unsigned int ctrlbit = clk->ctrlbit;
156 unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
157
158 if (enable)
159 __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
160 else
161 __raw_writel(epll_con, S5P_EPLL_CON);
162
163 return 0;
164}
165
166unsigned long s5p_epll_get_rate(struct clk *clk)
167{
168 return clk->rate;
169}
170
159static struct clk *s5p_clks[] __initdata = { 171static struct clk *s5p_clks[] __initdata = {
160 &clk_ext_xtal_mux, 172 &clk_ext_xtal_mux,
161 &clk_48m, 173 &clk_48m,
@@ -165,7 +177,6 @@ static struct clk *s5p_clks[] __initdata = {
165 &clk_fout_epll, 177 &clk_fout_epll,
166 &clk_fout_dpll, 178 &clk_fout_dpll,
167 &clk_fout_vpll, 179 &clk_fout_vpll,
168 &clk_arm,
169 &clk_vpll, 180 &clk_vpll,
170 &clk_xusbxti, 181 &clk_xusbxti,
171}; 182};
diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h
index 3fb3a3a17465..ba9121c60a2a 100644
--- a/arch/arm/plat-s5p/include/plat/irqs.h
+++ b/arch/arm/plat-s5p/include/plat/irqs.h
@@ -94,4 +94,22 @@
94 ((irq) - S5P_EINT_BASE1) : \ 94 ((irq) - S5P_EINT_BASE1) : \
95 ((irq) + 16 - S5P_EINT_BASE2)) 95 ((irq) + 16 - S5P_EINT_BASE2))
96 96
97#define IRQ_EINT_BIT(x) EINT_OFFSET(x)
98
99/* Typically only a few gpio chips require gpio interrupt support.
100 To avoid memory waste irq descriptors are allocated only for
101 S5P_GPIOINT_GROUP_COUNT chips, each with total number of
102 S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged
103 to any gpio chip with the s5p_register_gpio_interrupt() function */
104#define S5P_GPIOINT_GROUP_COUNT 4
105#define S5P_GPIOINT_GROUP_SIZE 8
106#define S5P_GPIOINT_COUNT (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE)
107
108/* IRQ types common for all s5p platforms */
109#define S5P_IRQ_TYPE_LEVEL_LOW (0x00)
110#define S5P_IRQ_TYPE_LEVEL_HIGH (0x01)
111#define S5P_IRQ_TYPE_EDGE_FALLING (0x02)
112#define S5P_IRQ_TYPE_EDGE_RISING (0x03)
113#define S5P_IRQ_TYPE_EDGE_BOTH (0x04)
114
97#endif /* __ASM_PLAT_S5P_IRQS_H */ 115#endif /* __ASM_PLAT_S5P_IRQS_H */
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h
index c4ff88bf6477..fef353d44513 100644
--- a/arch/arm/plat-s5p/include/plat/map-s5p.h
+++ b/arch/arm/plat-s5p/include/plat/map-s5p.h
@@ -13,24 +13,38 @@
13#ifndef __ASM_PLAT_MAP_S5P_H 13#ifndef __ASM_PLAT_MAP_S5P_H
14#define __ASM_PLAT_MAP_S5P_H __FILE__ 14#define __ASM_PLAT_MAP_S5P_H __FILE__
15 15
16#define S5P_VA_CHIPID S3C_ADDR(0x00700000) 16#define S5P_VA_CHIPID S3C_ADDR(0x02000000)
17#define S5P_VA_GPIO S3C_ADDR(0x00500000) 17#define S5P_VA_CMU S3C_ADDR(0x02100000)
18#define S5P_VA_SYSTIMER S3C_ADDR(0x01200000) 18#define S5P_VA_GPIO S3C_ADDR(0x02200000)
19#define S5P_VA_SROMC S3C_ADDR(0x01100000) 19#define S5P_VA_GPIO1 S5P_VA_GPIO
20#define S5P_VA_SYSRAM S3C_ADDR(0x01180000) 20#define S5P_VA_GPIO2 S3C_ADDR(0x02240000)
21 21#define S5P_VA_GPIO3 S3C_ADDR(0x02280000)
22#define S5P_VA_COMBINER_BASE S3C_ADDR(0x00600000) 22
23#define S5P_VA_SYSRAM S3C_ADDR(0x02400000)
24#define S5P_VA_DMC0 S3C_ADDR(0x02440000)
25#define S5P_VA_DMC1 S3C_ADDR(0x02480000)
26#define S5P_VA_SROMC S3C_ADDR(0x024C0000)
27
28#define S5P_VA_SYSTIMER S3C_ADDR(0x02500000)
29#define S5P_VA_L2CC S3C_ADDR(0x02600000)
30
31#define S5P_VA_COMBINER_BASE S3C_ADDR(0x02700000)
23#define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10) 32#define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10)
24 33
25#define S5P_VA_COREPERI_BASE S3C_ADDR(0x00800000) 34#define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000)
26#define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x)) 35#define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x))
27#define S5P_VA_SCU S5P_VA_COREPERI(0x0) 36#define S5P_VA_SCU S5P_VA_COREPERI(0x0)
28#define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100) 37#define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100)
29#define S5P_VA_TWD S5P_VA_COREPERI(0x600) 38#define S5P_VA_TWD S5P_VA_COREPERI(0x600)
30#define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000) 39#define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000)
31 40
32#define S5P_VA_L2CC S3C_ADDR(0x00900000) 41#define S3C_VA_USB_HSPHY S3C_ADDR(0x02900000)
33#define S5P_VA_CMU S3C_ADDR(0x00920000) 42
43#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
44#define VA_VIC0 VA_VIC(0)
45#define VA_VIC1 VA_VIC(1)
46#define VA_VIC2 VA_VIC(2)
47#define VA_VIC3 VA_VIC(3)
34 48
35#define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) 49#define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
36#define S5P_VA_UART0 S5P_VA_UART(0) 50#define S5P_VA_UART0 S5P_VA_UART(0)
@@ -42,10 +56,4 @@
42#define S3C_UART_OFFSET (0x400) 56#define S3C_UART_OFFSET (0x400)
43#endif 57#endif
44 58
45#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
46#define VA_VIC0 VA_VIC(0)
47#define VA_VIC1 VA_VIC(1)
48#define VA_VIC2 VA_VIC(2)
49#define VA_VIC3 VA_VIC(3)
50
51#endif /* __ASM_PLAT_MAP_S5P_H */ 59#endif /* __ASM_PLAT_MAP_S5P_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h
index 17036c898409..2b6dcff8ab2b 100644
--- a/arch/arm/plat-s5p/include/plat/s5p-clock.h
+++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h
@@ -43,4 +43,8 @@ extern struct clksrc_sources clk_src_dpll;
43 43
44extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable); 44extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
45 45
46/* Common EPLL operations for S5P platform */
47extern int s5p_epll_enable(struct clk *clk, int enable);
48extern unsigned long s5p_epll_get_rate(struct clk *clk);
49
46#endif /* __ASM_PLAT_S5P_CLOCK_H */ 50#endif /* __ASM_PLAT_S5P_CLOCK_H */
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
index f36cd3327025..752f1a645f9d 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -67,23 +67,23 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
67 67
68 switch (type) { 68 switch (type) {
69 case IRQ_TYPE_EDGE_RISING: 69 case IRQ_TYPE_EDGE_RISING:
70 newvalue = S5P_EXTINT_RISEEDGE; 70 newvalue = S5P_IRQ_TYPE_EDGE_RISING;
71 break; 71 break;
72 72
73 case IRQ_TYPE_EDGE_FALLING: 73 case IRQ_TYPE_EDGE_FALLING:
74 newvalue = S5P_EXTINT_FALLEDGE; 74 newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
75 break; 75 break;
76 76
77 case IRQ_TYPE_EDGE_BOTH: 77 case IRQ_TYPE_EDGE_BOTH:
78 newvalue = S5P_EXTINT_BOTHEDGE; 78 newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
79 break; 79 break;
80 80
81 case IRQ_TYPE_LEVEL_LOW: 81 case IRQ_TYPE_LEVEL_LOW:
82 newvalue = S5P_EXTINT_LOWLEV; 82 newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
83 break; 83 break;
84 84
85 case IRQ_TYPE_LEVEL_HIGH: 85 case IRQ_TYPE_LEVEL_HIGH:
86 newvalue = S5P_EXTINT_HILEV; 86 newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
87 break; 87 break;
88 88
89 default: 89 default:
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
new file mode 100644
index 000000000000..0e5dc8cbf5e3
--- /dev/null
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -0,0 +1,237 @@
1/* linux/arch/arm/plat-s5p/irq-gpioint.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * Author: Kyungmin Park <kyungmin.park@samsung.com>
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 * Author: Marek Szyprowski <m.szyprowski@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/interrupt.h>
17#include <linux/irq.h>
18#include <linux/io.h>
19#include <linux/gpio.h>
20
21#include <mach/map.h>
22#include <plat/gpio-core.h>
23#include <plat/gpio-cfg.h>
24
25#define S5P_GPIOREG(x) (S5P_VA_GPIO + (x))
26
27#define GPIOINT_CON_OFFSET 0x700
28#define GPIOINT_MASK_OFFSET 0x900
29#define GPIOINT_PEND_OFFSET 0xA00
30
31static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR];
32
33static int s5p_gpioint_get_group(unsigned int irq)
34{
35 struct gpio_chip *chip = get_irq_data(irq);
36 struct s3c_gpio_chip *s3c_chip = container_of(chip,
37 struct s3c_gpio_chip, chip);
38 int group;
39
40 for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++)
41 if (s3c_chip == irq_chips[group])
42 break;
43
44 return group;
45}
46
47static int s5p_gpioint_get_offset(unsigned int irq)
48{
49 struct gpio_chip *chip = get_irq_data(irq);
50 struct s3c_gpio_chip *s3c_chip = container_of(chip,
51 struct s3c_gpio_chip, chip);
52
53 return irq - s3c_chip->irq_base;
54}
55
56static void s5p_gpioint_ack(unsigned int irq)
57{
58 int group, offset, pend_offset;
59 unsigned int value;
60
61 group = s5p_gpioint_get_group(irq);
62 offset = s5p_gpioint_get_offset(irq);
63 pend_offset = group << 2;
64
65 value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
66 value |= 1 << offset;
67 __raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
68}
69
70static void s5p_gpioint_mask(unsigned int irq)
71{
72 int group, offset, mask_offset;
73 unsigned int value;
74
75 group = s5p_gpioint_get_group(irq);
76 offset = s5p_gpioint_get_offset(irq);
77 mask_offset = group << 2;
78
79 value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
80 value |= 1 << offset;
81 __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
82}
83
84static void s5p_gpioint_unmask(unsigned int irq)
85{
86 int group, offset, mask_offset;
87 unsigned int value;
88
89 group = s5p_gpioint_get_group(irq);
90 offset = s5p_gpioint_get_offset(irq);
91 mask_offset = group << 2;
92
93 value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
94 value &= ~(1 << offset);
95 __raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
96}
97
98static void s5p_gpioint_mask_ack(unsigned int irq)
99{
100 s5p_gpioint_mask(irq);
101 s5p_gpioint_ack(irq);
102}
103
104static int s5p_gpioint_set_type(unsigned int irq, unsigned int type)
105{
106 int group, offset, con_offset;
107 unsigned int value;
108
109 group = s5p_gpioint_get_group(irq);
110 offset = s5p_gpioint_get_offset(irq);
111 con_offset = group << 2;
112
113 switch (type) {
114 case IRQ_TYPE_EDGE_RISING:
115 type = S5P_IRQ_TYPE_EDGE_RISING;
116 break;
117 case IRQ_TYPE_EDGE_FALLING:
118 type = S5P_IRQ_TYPE_EDGE_FALLING;
119 break;
120 case IRQ_TYPE_EDGE_BOTH:
121 type = S5P_IRQ_TYPE_EDGE_BOTH;
122 break;
123 case IRQ_TYPE_LEVEL_HIGH:
124 type = S5P_IRQ_TYPE_LEVEL_HIGH;
125 break;
126 case IRQ_TYPE_LEVEL_LOW:
127 type = S5P_IRQ_TYPE_LEVEL_LOW;
128 break;
129 case IRQ_TYPE_NONE:
130 default:
131 printk(KERN_WARNING "No irq type\n");
132 return -EINVAL;
133 }
134
135 value = __raw_readl(S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
136 value &= ~(0x7 << (offset * 0x4));
137 value |= (type << (offset * 0x4));
138 __raw_writel(value, S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
139
140 return 0;
141}
142
143struct irq_chip s5p_gpioint = {
144 .name = "s5p_gpioint",
145 .ack = s5p_gpioint_ack,
146 .mask = s5p_gpioint_mask,
147 .mask_ack = s5p_gpioint_mask_ack,
148 .unmask = s5p_gpioint_unmask,
149 .set_type = s5p_gpioint_set_type,
150};
151
152static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
153{
154 int group, offset, pend_offset, mask_offset;
155 int real_irq;
156 unsigned int pend, mask;
157
158 for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++) {
159 pend_offset = group << 2;
160 pend = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) +
161 pend_offset);
162 if (!pend)
163 continue;
164
165 mask_offset = group << 2;
166 mask = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) +
167 mask_offset);
168 pend &= ~mask;
169
170 for (offset = 0; offset < 8; offset++) {
171 if (pend & (1 << offset)) {
172 struct s3c_gpio_chip *chip = irq_chips[group];
173 if (chip) {
174 real_irq = chip->irq_base + offset;
175 generic_handle_irq(real_irq);
176 }
177 }
178 }
179 }
180}
181
182static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
183{
184 static int used_gpioint_groups = 0;
185 static bool handler_registered = 0;
186 int irq, group = chip->group;
187 int i;
188
189 if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
190 return -ENOMEM;
191
192 chip->irq_base = S5P_GPIOINT_BASE +
193 used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
194 used_gpioint_groups++;
195
196 if (!handler_registered) {
197 set_irq_chained_handler(IRQ_GPIOINT, s5p_gpioint_handler);
198 handler_registered = 1;
199 }
200
201 irq_chips[group] = chip;
202 for (i = 0; i < chip->chip.ngpio; i++) {
203 irq = chip->irq_base + i;
204 set_irq_chip(irq, &s5p_gpioint);
205 set_irq_data(irq, &chip->chip);
206 set_irq_handler(irq, handle_level_irq);
207 set_irq_flags(irq, IRQF_VALID);
208 }
209 return 0;
210}
211
212int __init s5p_register_gpio_interrupt(int pin)
213{
214 struct s3c_gpio_chip *my_chip = s3c_gpiolib_getchip(pin);
215 int offset, group;
216 int ret;
217
218 if (!my_chip)
219 return -EINVAL;
220
221 offset = pin - my_chip->chip.base;
222 group = my_chip->group;
223
224 /* check if the group has been already registered */
225 if (my_chip->irq_base)
226 return my_chip->irq_base + offset;
227
228 /* register gpio group */
229 ret = s5p_gpioint_add(my_chip);
230 if (ret == 0) {
231 my_chip->chip.to_irq = samsung_gpiolib_to_irq;
232 printk(KERN_INFO "Registered interrupt support for gpio group %d.\n",
233 group);
234 return my_chip->irq_base + offset;
235 }
236 return ret;
237}
diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c
new file mode 100644
index 000000000000..dc33b9ecda45
--- /dev/null
+++ b/arch/arm/plat-s5p/irq-pm.c
@@ -0,0 +1,93 @@
1/* linux/arch/arm/plat-s5p/irq-pm.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Based on arch/arm/plat-s3c24xx/irq-pm.c,
7 * Copyright (c) 2003,2004 Simtec Electronics
8 * Ben Dooks <ben@simtec.co.uk>
9 * http://armlinux.simtec.co.uk/
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/interrupt.h>
19#include <linux/sysdev.h>
20
21#include <plat/cpu.h>
22#include <plat/irqs.h>
23#include <plat/pm.h>
24#include <mach/map.h>
25
26#include <mach/regs-gpio.h>
27#include <mach/regs-irq.h>
28
29/* state for IRQs over sleep */
30
31/* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM,
32 * as wakeup sources
33 *
34 * set bit to 1 in allow bitfield to enable the wakeup settings on it
35*/
36
37unsigned long s3c_irqwake_intallow = 0x00000006L;
38unsigned long s3c_irqwake_eintallow = 0xffffffffL;
39
40int s3c_irq_wake(unsigned int irqno, unsigned int state)
41{
42 unsigned long irqbit;
43
44 switch (irqno) {
45 case IRQ_RTC_TIC:
46 case IRQ_RTC_ALARM:
47 irqbit = 1 << (irqno + 1 - IRQ_RTC_ALARM);
48 if (!state)
49 s3c_irqwake_intmask |= irqbit;
50 else
51 s3c_irqwake_intmask &= ~irqbit;
52 break;
53 default:
54 return -ENOENT;
55 }
56 return 0;
57}
58
59static struct sleep_save eint_save[] = {
60 SAVE_ITEM(S5P_EINT_CON(0)),
61 SAVE_ITEM(S5P_EINT_CON(1)),
62 SAVE_ITEM(S5P_EINT_CON(2)),
63 SAVE_ITEM(S5P_EINT_CON(3)),
64
65 SAVE_ITEM(S5P_EINT_FLTCON(0)),
66 SAVE_ITEM(S5P_EINT_FLTCON(1)),
67 SAVE_ITEM(S5P_EINT_FLTCON(2)),
68 SAVE_ITEM(S5P_EINT_FLTCON(3)),
69 SAVE_ITEM(S5P_EINT_FLTCON(4)),
70 SAVE_ITEM(S5P_EINT_FLTCON(5)),
71 SAVE_ITEM(S5P_EINT_FLTCON(6)),
72 SAVE_ITEM(S5P_EINT_FLTCON(7)),
73
74 SAVE_ITEM(S5P_EINT_MASK(0)),
75 SAVE_ITEM(S5P_EINT_MASK(1)),
76 SAVE_ITEM(S5P_EINT_MASK(2)),
77 SAVE_ITEM(S5P_EINT_MASK(3)),
78};
79
80int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
81{
82 s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save));
83
84 return 0;
85}
86
87int s3c24xx_irq_resume(struct sys_device *dev)
88{
89 s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save));
90
91 return 0;
92}
93
diff --git a/arch/arm/plat-s5p/pm.c b/arch/arm/plat-s5p/pm.c
new file mode 100644
index 000000000000..d592b6304b48
--- /dev/null
+++ b/arch/arm/plat-s5p/pm.c
@@ -0,0 +1,52 @@
1/* linux/arch/arm/plat-s5p/pm.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5P Power Manager (Suspend-To-RAM) support
7 *
8 * Based on arch/arm/plat-s3c24xx/pm.c
9 * Copyright (c) 2004,2006 Simtec Electronics
10 * Ben Dooks <ben@simtec.co.uk>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15*/
16
17#include <linux/suspend.h>
18#include <plat/pm.h>
19
20#define PFX "s5p pm: "
21
22/* s3c_pm_check_resume_pin
23 *
24 * check to see if the pin is configured correctly for sleep mode, and
25 * make any necessary adjustments if it is not
26*/
27
28static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
29{
30 /* nothing here yet */
31}
32
33/* s3c_pm_configure_extint
34 *
35 * configure all external interrupt pins
36*/
37
38void s3c_pm_configure_extint(void)
39{
40 /* nothing here yet */
41}
42
43void s3c_pm_restore_core(void)
44{
45 /* nothing here yet */
46}
47
48void s3c_pm_save_core(void)
49{
50 /* nothing here yet */
51}
52
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 7c0bde781167..dcd6eff4ee53 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -180,6 +180,31 @@ config S3C_DEV_I2C2
180 help 180 help
181 Compile in platform device definitions for I2C channel 2 181 Compile in platform device definitions for I2C channel 2
182 182
183config S3C_DEV_I2C3
184 bool
185 help
186 Compile in platform device definition for I2C controller 3
187
188config S3C_DEV_I2C4
189 bool
190 help
191 Compile in platform device definition for I2C controller 4
192
193config S3C_DEV_I2C5
194 bool
195 help
196 Compile in platform device definition for I2C controller 5
197
198config S3C_DEV_I2C6
199 bool
200 help
201 Compile in platform device definition for I2C controller 6
202
203config S3C_DEV_I2C7
204 bool
205 help
206 Compile in platform device definition for I2C controller 7
207
183config S3C_DEV_FB 208config S3C_DEV_FB
184 bool 209 bool
185 help 210 help
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 4d8ff923207a..afcce474af8e 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -40,6 +40,11 @@ obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o
40obj-y += dev-i2c0.o 40obj-y += dev-i2c0.o
41obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o 41obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
42obj-$(CONFIG_S3C_DEV_I2C2) += dev-i2c2.o 42obj-$(CONFIG_S3C_DEV_I2C2) += dev-i2c2.o
43obj-$(CONFIG_S3C_DEV_I2C3) += dev-i2c3.o
44obj-$(CONFIG_S3C_DEV_I2C4) += dev-i2c4.o
45obj-$(CONFIG_S3C_DEV_I2C5) += dev-i2c5.o
46obj-$(CONFIG_S3C_DEV_I2C6) += dev-i2c6.o
47obj-$(CONFIG_S3C_DEV_I2C7) += dev-i2c7.o
43obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o 48obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
44obj-y += dev-uart.o 49obj-y += dev-uart.o
45obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o 50obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
index 9d2be0941410..db7a65c7f127 100644
--- a/arch/arm/plat-samsung/dev-hsmmc.c
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
@@ -41,6 +41,7 @@ struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
41 .max_width = 4, 41 .max_width = 4,
42 .host_caps = (MMC_CAP_4_BIT_DATA | 42 .host_caps = (MMC_CAP_4_BIT_DATA |
43 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), 43 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
44 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
44}; 45};
45 46
46struct platform_device s3c_device_hsmmc0 = { 47struct platform_device s3c_device_hsmmc0 = {
@@ -59,17 +60,20 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
59{ 60{
60 struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata; 61 struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
61 62
62 set->max_width = pd->max_width;
63 set->cd_type = pd->cd_type; 63 set->cd_type = pd->cd_type;
64 set->ext_cd_init = pd->ext_cd_init; 64 set->ext_cd_init = pd->ext_cd_init;
65 set->ext_cd_cleanup = pd->ext_cd_cleanup; 65 set->ext_cd_cleanup = pd->ext_cd_cleanup;
66 set->ext_cd_gpio = pd->ext_cd_gpio; 66 set->ext_cd_gpio = pd->ext_cd_gpio;
67 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; 67 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
68 68
69 if (pd->max_width)
70 set->max_width = pd->max_width;
69 if (pd->cfg_gpio) 71 if (pd->cfg_gpio)
70 set->cfg_gpio = pd->cfg_gpio; 72 set->cfg_gpio = pd->cfg_gpio;
71 if (pd->cfg_card) 73 if (pd->cfg_card)
72 set->cfg_card = pd->cfg_card; 74 set->cfg_card = pd->cfg_card;
73 if (pd->host_caps) 75 if (pd->host_caps)
74 set->host_caps = pd->host_caps; 76 set->host_caps |= pd->host_caps;
77 if (pd->clk_type)
78 set->clk_type = pd->clk_type;
75} 79}
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
index a6c8295840af..2497321f08d7 100644
--- a/arch/arm/plat-samsung/dev-hsmmc1.c
+++ b/arch/arm/plat-samsung/dev-hsmmc1.c
@@ -41,6 +41,7 @@ struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
41 .max_width = 4, 41 .max_width = 4,
42 .host_caps = (MMC_CAP_4_BIT_DATA | 42 .host_caps = (MMC_CAP_4_BIT_DATA |
43 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), 43 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
44 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
44}; 45};
45 46
46struct platform_device s3c_device_hsmmc1 = { 47struct platform_device s3c_device_hsmmc1 = {
@@ -59,17 +60,20 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
59{ 60{
60 struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata; 61 struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
61 62
62 set->max_width = pd->max_width;
63 set->cd_type = pd->cd_type; 63 set->cd_type = pd->cd_type;
64 set->ext_cd_init = pd->ext_cd_init; 64 set->ext_cd_init = pd->ext_cd_init;
65 set->ext_cd_cleanup = pd->ext_cd_cleanup; 65 set->ext_cd_cleanup = pd->ext_cd_cleanup;
66 set->ext_cd_gpio = pd->ext_cd_gpio; 66 set->ext_cd_gpio = pd->ext_cd_gpio;
67 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; 67 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
68 68
69 if (pd->max_width)
70 set->max_width = pd->max_width;
69 if (pd->cfg_gpio) 71 if (pd->cfg_gpio)
70 set->cfg_gpio = pd->cfg_gpio; 72 set->cfg_gpio = pd->cfg_gpio;
71 if (pd->cfg_card) 73 if (pd->cfg_card)
72 set->cfg_card = pd->cfg_card; 74 set->cfg_card = pd->cfg_card;
73 if (pd->host_caps) 75 if (pd->host_caps)
74 set->host_caps = pd->host_caps; 76 set->host_caps |= pd->host_caps;
77 if (pd->clk_type)
78 set->clk_type = pd->clk_type;
75} 79}
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
index cb0d7143381a..f60aedba417c 100644
--- a/arch/arm/plat-samsung/dev-hsmmc2.c
+++ b/arch/arm/plat-samsung/dev-hsmmc2.c
@@ -42,6 +42,7 @@ struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
42 .max_width = 4, 42 .max_width = 4,
43 .host_caps = (MMC_CAP_4_BIT_DATA | 43 .host_caps = (MMC_CAP_4_BIT_DATA |
44 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), 44 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
45 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
45}; 46};
46 47
47struct platform_device s3c_device_hsmmc2 = { 48struct platform_device s3c_device_hsmmc2 = {
@@ -60,17 +61,20 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
60{ 61{
61 struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata; 62 struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
62 63
63 set->max_width = pd->max_width;
64 set->cd_type = pd->cd_type; 64 set->cd_type = pd->cd_type;
65 set->ext_cd_init = pd->ext_cd_init; 65 set->ext_cd_init = pd->ext_cd_init;
66 set->ext_cd_cleanup = pd->ext_cd_cleanup; 66 set->ext_cd_cleanup = pd->ext_cd_cleanup;
67 set->ext_cd_gpio = pd->ext_cd_gpio; 67 set->ext_cd_gpio = pd->ext_cd_gpio;
68 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; 68 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
69 69
70 if (pd->max_width)
71 set->max_width = pd->max_width;
70 if (pd->cfg_gpio) 72 if (pd->cfg_gpio)
71 set->cfg_gpio = pd->cfg_gpio; 73 set->cfg_gpio = pd->cfg_gpio;
72 if (pd->cfg_card) 74 if (pd->cfg_card)
73 set->cfg_card = pd->cfg_card; 75 set->cfg_card = pd->cfg_card;
74 if (pd->host_caps) 76 if (pd->host_caps)
75 set->host_caps = pd->host_caps; 77 set->host_caps |= pd->host_caps;
78 if (pd->clk_type)
79 set->clk_type = pd->clk_type;
76} 80}
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
index 85aaf0f2842f..ede776f20e62 100644
--- a/arch/arm/plat-samsung/dev-hsmmc3.c
+++ b/arch/arm/plat-samsung/dev-hsmmc3.c
@@ -33,8 +33,8 @@ static struct resource s3c_hsmmc3_resource[] = {
33 .flags = IORESOURCE_MEM, 33 .flags = IORESOURCE_MEM,
34 }, 34 },
35 [1] = { 35 [1] = {
36 .start = IRQ_MMC3, 36 .start = IRQ_HSMMC3,
37 .end = IRQ_MMC3, 37 .end = IRQ_HSMMC3,
38 .flags = IORESOURCE_IRQ, 38 .flags = IORESOURCE_IRQ,
39 } 39 }
40}; 40};
@@ -45,6 +45,7 @@ struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
45 .max_width = 4, 45 .max_width = 4,
46 .host_caps = (MMC_CAP_4_BIT_DATA | 46 .host_caps = (MMC_CAP_4_BIT_DATA |
47 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), 47 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
48 .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
48}; 49};
49 50
50struct platform_device s3c_device_hsmmc3 = { 51struct platform_device s3c_device_hsmmc3 = {
@@ -63,15 +64,20 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
63{ 64{
64 struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata; 65 struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata;
65 66
66 set->max_width = pd->max_width;
67 set->cd_type = pd->cd_type; 67 set->cd_type = pd->cd_type;
68 set->ext_cd_init = pd->ext_cd_init; 68 set->ext_cd_init = pd->ext_cd_init;
69 set->ext_cd_cleanup = pd->ext_cd_cleanup; 69 set->ext_cd_cleanup = pd->ext_cd_cleanup;
70 set->ext_cd_gpio = pd->ext_cd_gpio; 70 set->ext_cd_gpio = pd->ext_cd_gpio;
71 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; 71 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
72 72
73 if (pd->max_width)
74 set->max_width = pd->max_width;
73 if (pd->cfg_gpio) 75 if (pd->cfg_gpio)
74 set->cfg_gpio = pd->cfg_gpio; 76 set->cfg_gpio = pd->cfg_gpio;
75 if (pd->cfg_card) 77 if (pd->cfg_card)
76 set->cfg_card = pd->cfg_card; 78 set->cfg_card = pd->cfg_card;
79 if (pd->host_caps)
80 set->host_caps |= pd->host_caps;
81 if (pd->clk_type)
82 set->clk_type = pd->clk_type;
77} 83}
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c
index 07036dee09e7..ff4ba69b6830 100644
--- a/arch/arm/plat-samsung/dev-i2c2.c
+++ b/arch/arm/plat-samsung/dev-i2c2.c
@@ -32,8 +32,8 @@ static struct resource s3c_i2c_resource[] = {
32 .flags = IORESOURCE_MEM, 32 .flags = IORESOURCE_MEM,
33 }, 33 },
34 [1] = { 34 [1] = {
35 .start = IRQ_CAN0, 35 .start = IRQ_IIC2,
36 .end = IRQ_CAN0, 36 .end = IRQ_IIC2,
37 .flags = IORESOURCE_IRQ, 37 .flags = IORESOURCE_IRQ,
38 }, 38 },
39}; 39};
diff --git a/arch/arm/plat-samsung/dev-i2c3.c b/arch/arm/plat-samsung/dev-i2c3.c
new file mode 100644
index 000000000000..8586a10014b7
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c3.c
@@ -0,0 +1,68 @@
1/* linux/arch/arm/plat-samsung/dev-i2c3.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 3
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC3,
29 .end = S3C_PA_IIC3 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC3,
34 .end = IRQ_IIC3,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c3 = {
40 .name = "s3c2440-i2c",
41 .id = 3,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46static struct s3c2410_platform_i2c default_i2c_data3 __initdata = {
47 .flags = 0,
48 .bus_num = 3,
49 .slave_addr = 0x10,
50 .frequency = 100*1000,
51 .sda_delay = 100,
52};
53
54void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
55{
56 struct s3c2410_platform_i2c *npd;
57
58 if (!pd)
59 pd = &default_i2c_data3;
60
61 npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
62 if (!npd)
63 printk(KERN_ERR "%s: no memory for platform data\n", __func__);
64 else if (!npd->cfg_gpio)
65 npd->cfg_gpio = s3c_i2c3_cfg_gpio;
66
67 s3c_device_i2c3.dev.platform_data = npd;
68}
diff --git a/arch/arm/plat-samsung/dev-i2c4.c b/arch/arm/plat-samsung/dev-i2c4.c
new file mode 100644
index 000000000000..df2159e2daa6
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c4.c
@@ -0,0 +1,68 @@
1/* linux/arch/arm/plat-samsung/dev-i2c4.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 3
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC4,
29 .end = S3C_PA_IIC4 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC4,
34 .end = IRQ_IIC4,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c4 = {
40 .name = "s3c2440-i2c",
41 .id = 4,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46static struct s3c2410_platform_i2c default_i2c_data4 __initdata = {
47 .flags = 0,
48 .bus_num = 4,
49 .slave_addr = 0x10,
50 .frequency = 100*1000,
51 .sda_delay = 100,
52};
53
54void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
55{
56 struct s3c2410_platform_i2c *npd;
57
58 if (!pd)
59 pd = &default_i2c_data4;
60
61 npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
62 if (!npd)
63 printk(KERN_ERR "%s: no memory for platform data\n", __func__);
64 else if (!npd->cfg_gpio)
65 npd->cfg_gpio = s3c_i2c4_cfg_gpio;
66
67 s3c_device_i2c4.dev.platform_data = npd;
68}
diff --git a/arch/arm/plat-samsung/dev-i2c5.c b/arch/arm/plat-samsung/dev-i2c5.c
new file mode 100644
index 000000000000..0499c2c3877b
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c5.c
@@ -0,0 +1,68 @@
1/* linux/arch/arm/plat-samsung/dev-i2c3.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 3
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC5,
29 .end = S3C_PA_IIC5 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC5,
34 .end = IRQ_IIC5,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c5 = {
40 .name = "s3c2440-i2c",
41 .id = 5,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46static struct s3c2410_platform_i2c default_i2c_data5 __initdata = {
47 .flags = 0,
48 .bus_num = 5,
49 .slave_addr = 0x10,
50 .frequency = 100*1000,
51 .sda_delay = 100,
52};
53
54void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
55{
56 struct s3c2410_platform_i2c *npd;
57
58 if (!pd)
59 pd = &default_i2c_data5;
60
61 npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
62 if (!npd)
63 printk(KERN_ERR "%s: no memory for platform data\n", __func__);
64 else if (!npd->cfg_gpio)
65 npd->cfg_gpio = s3c_i2c5_cfg_gpio;
66
67 s3c_device_i2c5.dev.platform_data = npd;
68}
diff --git a/arch/arm/plat-samsung/dev-i2c6.c b/arch/arm/plat-samsung/dev-i2c6.c
new file mode 100644
index 000000000000..4083108908a8
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c6.c
@@ -0,0 +1,68 @@
1/* linux/arch/arm/plat-samsung/dev-i2c6.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 6
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC6,
29 .end = S3C_PA_IIC6 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC6,
34 .end = IRQ_IIC6,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c6 = {
40 .name = "s3c2440-i2c",
41 .id = 6,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46static struct s3c2410_platform_i2c default_i2c_data6 __initdata = {
47 .flags = 0,
48 .bus_num = 6,
49 .slave_addr = 0x10,
50 .frequency = 100*1000,
51 .sda_delay = 100,
52};
53
54void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
55{
56 struct s3c2410_platform_i2c *npd;
57
58 if (!pd)
59 pd = &default_i2c_data6;
60
61 npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
62 if (!npd)
63 printk(KERN_ERR "%s: no memory for platform data\n", __func__);
64 else if (!npd->cfg_gpio)
65 npd->cfg_gpio = s3c_i2c6_cfg_gpio;
66
67 s3c_device_i2c6.dev.platform_data = npd;
68}
diff --git a/arch/arm/plat-samsung/dev-i2c7.c b/arch/arm/plat-samsung/dev-i2c7.c
new file mode 100644
index 000000000000..1182451d7dce
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c7.c
@@ -0,0 +1,68 @@
1/* linux/arch/arm/plat-samsung/dev-i2c7.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P series device definition for i2c device 7
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/gfp.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/platform_device.h>
17
18#include <mach/irqs.h>
19#include <mach/map.h>
20
21#include <plat/regs-iic.h>
22#include <plat/iic.h>
23#include <plat/devs.h>
24#include <plat/cpu.h>
25
26static struct resource s3c_i2c_resource[] = {
27 [0] = {
28 .start = S3C_PA_IIC7,
29 .end = S3C_PA_IIC7 + SZ_4K - 1,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = IRQ_IIC7,
34 .end = IRQ_IIC7,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39struct platform_device s3c_device_i2c7 = {
40 .name = "s3c2440-i2c",
41 .id = 7,
42 .num_resources = ARRAY_SIZE(s3c_i2c_resource),
43 .resource = s3c_i2c_resource,
44};
45
46static struct s3c2410_platform_i2c default_i2c_data7 __initdata = {
47 .flags = 0,
48 .bus_num = 7,
49 .slave_addr = 0x10,
50 .frequency = 100*1000,
51 .sda_delay = 100,
52};
53
54void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
55{
56 struct s3c2410_platform_i2c *npd;
57
58 if (!pd)
59 pd = &default_i2c_data7;
60
61 npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
62 if (!npd)
63 printk(KERN_ERR "%s: no memory for platform data\n", __func__);
64 else if (!npd->cfg_gpio)
65 npd->cfg_gpio = s3c_i2c7_cfg_gpio;
66
67 s3c_device_i2c7.dev.platform_data = npd;
68}
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index e3d41eaed1ff..b732b773b9af 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -41,6 +41,37 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
41} 41}
42EXPORT_SYMBOL(s3c_gpio_cfgpin); 42EXPORT_SYMBOL(s3c_gpio_cfgpin);
43 43
44int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
45 unsigned int cfg)
46{
47 int ret;
48
49 for (; nr > 0; nr--, start++) {
50 ret = s3c_gpio_cfgpin(start, cfg);
51 if (ret != 0)
52 return ret;
53 }
54
55 return 0;
56}
57EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
58
59int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
60 unsigned int cfg, s3c_gpio_pull_t pull)
61{
62 int ret;
63
64 for (; nr > 0; nr--, start++) {
65 s3c_gpio_setpull(start, pull);
66 ret = s3c_gpio_cfgpin(start, cfg);
67 if (ret != 0)
68 return ret;
69 }
70
71 return 0;
72}
73EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
74
44unsigned s3c_gpio_getcfg(unsigned int pin) 75unsigned s3c_gpio_getcfg(unsigned int pin)
45{ 76{
46 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); 77 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
@@ -80,6 +111,25 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
80} 111}
81EXPORT_SYMBOL(s3c_gpio_setpull); 112EXPORT_SYMBOL(s3c_gpio_setpull);
82 113
114s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
115{
116 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
117 unsigned long flags;
118 int offset;
119 u32 pup = 0;
120
121 if (chip) {
122 offset = pin - chip->chip.base;
123
124 s3c_gpio_lock(chip, flags);
125 pup = s3c_gpio_do_getpull(chip, offset);
126 s3c_gpio_unlock(chip, flags);
127 }
128
129 return (__force s3c_gpio_pull_t)pup;
130}
131EXPORT_SYMBOL(s3c_gpio_getpull);
132
83#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX 133#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
84int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, 134int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
85 unsigned int off, unsigned int cfg) 135 unsigned int off, unsigned int cfg)
diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c
index b83a83351cea..7743c4b8b2fb 100644
--- a/arch/arm/plat-samsung/gpio.c
+++ b/arch/arm/plat-samsung/gpio.c
@@ -157,3 +157,11 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
157 if (ret >= 0) 157 if (ret >= 0)
158 s3c_gpiolib_track(chip); 158 s3c_gpiolib_track(chip);
159} 159}
160
161int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
162{
163 struct s3c_gpio_chip *s3c_chip = container_of(chip,
164 struct s3c_gpio_chip, chip);
165
166 return s3c_chip->irq_base + offset;
167}
diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h
index e32f9edfd4b7..7712ff6336f4 100644
--- a/arch/arm/plat-samsung/include/plat/audio.h
+++ b/arch/arm/plat-samsung/include/plat/audio.h
@@ -16,6 +16,15 @@
16#define S3C64XX_AC97_GPE 1 16#define S3C64XX_AC97_GPE 1
17extern void s3c64xx_ac97_setup_gpio(int); 17extern void s3c64xx_ac97_setup_gpio(int);
18 18
19/*
20 * The machine init code calls s5p*_spdif_setup_gpio with
21 * one of these defines in order to select appropriate bank
22 * of GPIO for S/PDIF pins
23 */
24#define S5PC100_SPDIF_GPD 0
25#define S5PC100_SPDIF_GPG3 1
26extern void s5pc100_spdif_setup_gpio(int);
27
19/** 28/**
20 * struct s3c_audio_pdata - common platform data for audio device drivers 29 * struct s3c_audio_pdata - common platform data for audio device drivers
21 * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode 30 * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index c8b94279bad1..2d82a6cb1444 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -48,6 +48,11 @@ extern struct platform_device s3c_device_wdt;
48extern struct platform_device s3c_device_i2c0; 48extern struct platform_device s3c_device_i2c0;
49extern struct platform_device s3c_device_i2c1; 49extern struct platform_device s3c_device_i2c1;
50extern struct platform_device s3c_device_i2c2; 50extern struct platform_device s3c_device_i2c2;
51extern struct platform_device s3c_device_i2c3;
52extern struct platform_device s3c_device_i2c4;
53extern struct platform_device s3c_device_i2c5;
54extern struct platform_device s3c_device_i2c6;
55extern struct platform_device s3c_device_i2c7;
51extern struct platform_device s3c_device_rtc; 56extern struct platform_device s3c_device_rtc;
52extern struct platform_device s3c_device_adc; 57extern struct platform_device s3c_device_adc;
53extern struct platform_device s3c_device_sdi; 58extern struct platform_device s3c_device_sdi;
@@ -89,6 +94,7 @@ extern struct platform_device s5pv210_device_pcm2;
89extern struct platform_device s5pv210_device_iis0; 94extern struct platform_device s5pv210_device_iis0;
90extern struct platform_device s5pv210_device_iis1; 95extern struct platform_device s5pv210_device_iis1;
91extern struct platform_device s5pv210_device_iis2; 96extern struct platform_device s5pv210_device_iis2;
97extern struct platform_device s5pv210_device_spdif;
92 98
93extern struct platform_device s5p6442_device_pcm0; 99extern struct platform_device s5p6442_device_pcm0;
94extern struct platform_device s5p6442_device_pcm1; 100extern struct platform_device s5p6442_device_pcm1;
@@ -108,6 +114,7 @@ extern struct platform_device s5pc100_device_pcm1;
108extern struct platform_device s5pc100_device_iis0; 114extern struct platform_device s5pc100_device_iis0;
109extern struct platform_device s5pc100_device_iis1; 115extern struct platform_device s5pc100_device_iis1;
110extern struct platform_device s5pc100_device_iis2; 116extern struct platform_device s5pc100_device_iis2;
117extern struct platform_device s5pc100_device_spdif;
111 118
112extern struct platform_device samsung_device_keypad; 119extern struct platform_device samsung_device_keypad;
113 120
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index 3e21c75feefa..8fd65d8b5863 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -42,6 +42,12 @@ static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
42 return (chip->config->set_pull)(chip, off, pull); 42 return (chip->config->set_pull)(chip, off, pull);
43} 43}
44 44
45static inline s3c_gpio_pull_t s3c_gpio_do_getpull(struct s3c_gpio_chip *chip,
46 unsigned int off)
47{
48 return chip->config->get_pull(chip, off);
49}
50
45/** 51/**
46 * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration. 52 * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
47 * @chip: The gpio chip that is being configured. 53 * @chip: The gpio chip that is being configured.
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 1c6b92947c5d..e4b5cf126fa9 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -108,6 +108,19 @@ extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
108 */ 108 */
109extern unsigned s3c_gpio_getcfg(unsigned int pin); 109extern unsigned s3c_gpio_getcfg(unsigned int pin);
110 110
111/**
112 * s3c_gpio_cfgpin_range() - Change the GPIO function for configuring pin range
113 * @start: The pin number to start at
114 * @nr: The number of pins to configure from @start.
115 * @cfg: The configuration for the pin's function
116 *
117 * Call s3c_gpio_cfgpin() for the @nr pins starting at @start.
118 *
119 * @sa s3c_gpio_cfgpin.
120 */
121extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
122 unsigned int cfg);
123
111/* Define values for the pull-{up,down} available for each gpio pin. 124/* Define values for the pull-{up,down} available for each gpio pin.
112 * 125 *
113 * These values control the state of the weak pull-{up,down} resistors 126 * These values control the state of the weak pull-{up,down} resistors
@@ -140,6 +153,31 @@ extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
140*/ 153*/
141extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); 154extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
142 155
156/* configure `all` aspects of an gpio */
157
158/**
159 * s3c_gpio_cfgall_range() - configure range of gpio functtion and pull.
160 * @start: The gpio number to start at.
161 * @nr: The number of gpio to configure from @start.
162 * @cfg: The configuration to use
163 * @pull: The pull setting to use.
164 *
165 * Run s3c_gpio_cfgpin() and s3c_gpio_setpull() over the gpio range starting
166 * @gpio and running for @size.
167 *
168 * @sa s3c_gpio_cfgpin
169 * @sa s3c_gpio_setpull
170 * @sa s3c_gpio_cfgpin_range
171 */
172extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
173 unsigned int cfg, s3c_gpio_pull_t pull);
174
175static inline int s3c_gpio_cfgrange_nopull(unsigned int pin, unsigned int size,
176 unsigned int cfg)
177{
178 return s3c_gpio_cfgall_range(pin, size, cfg, S3C_GPIO_PULL_NONE);
179}
180
143/* Define values for the drvstr available for each gpio pin. 181/* Define values for the drvstr available for each gpio pin.
144 * 182 *
145 * These values control the value of the output signal driver strength, 183 * These values control the value of the output signal driver strength,
@@ -169,4 +207,22 @@ extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin);
169*/ 207*/
170extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr); 208extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);
171 209
210/**
211 * s5p_register_gpio_interrupt() - register interrupt support for a gpio group
212 * @pin: The pin number from the group to be registered
213 *
214 * This function registers gpio interrupt support for the group that the
215 * specified pin belongs to.
216 *
217 * The total number of gpio pins is quite large ob s5p series. Registering
218 * irq support for all of them would be a resource waste. Because of that the
219 * interrupt support for standard gpio pins is registered dynamically.
220 *
221 * It will return the irq number of the interrupt that has been registered
222 * or -ENOMEM if no more gpio interrupts can be registered. It is allowed
223 * to call this function more than once for the same gpio group (the group
224 * will be registered only once).
225 */
226extern int s5p_register_gpio_interrupt(int pin);
227
172#endif /* __PLAT_GPIO_CFG_H */ 228#endif /* __PLAT_GPIO_CFG_H */
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index e358c7da8480..13a22b8861ef 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -43,6 +43,8 @@ struct s3c_gpio_cfg;
43 * struct s3c_gpio_chip - wrapper for specific implementation of gpio 43 * struct s3c_gpio_chip - wrapper for specific implementation of gpio
44 * @chip: The chip structure to be exported via gpiolib. 44 * @chip: The chip structure to be exported via gpiolib.
45 * @base: The base pointer to the gpio configuration registers. 45 * @base: The base pointer to the gpio configuration registers.
46 * @group: The group register number for gpio interrupt support.
47 * @irq_base: The base irq number.
46 * @config: special function and pull-resistor control information. 48 * @config: special function and pull-resistor control information.
47 * @lock: Lock for exclusive access to this gpio bank. 49 * @lock: Lock for exclusive access to this gpio bank.
48 * @pm_save: Save information for suspend/resume support. 50 * @pm_save: Save information for suspend/resume support.
@@ -63,6 +65,8 @@ struct s3c_gpio_chip {
63 struct s3c_gpio_cfg *config; 65 struct s3c_gpio_cfg *config;
64 struct s3c_gpio_pm *pm; 66 struct s3c_gpio_pm *pm;
65 void __iomem *base; 67 void __iomem *base;
68 int irq_base;
69 int group;
66 spinlock_t lock; 70 spinlock_t lock;
67#ifdef CONFIG_PM 71#ifdef CONFIG_PM
68 u32 pm_save[4]; 72 u32 pm_save[4];
@@ -118,6 +122,17 @@ extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
118extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip); 122extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
119extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip); 123extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
120 124
125
126/**
127 * samsung_gpiolib_to_irq - convert gpio pin to irq number
128 * @chip: The gpio chip that the pin belongs to.
129 * @offset: The offset of the pin in the chip.
130 *
131 * This helper returns the irq number calculated from the chip->irq_base and
132 * the provided offset.
133 */
134extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset);
135
121/* exported for core SoC support to change */ 136/* exported for core SoC support to change */
122extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default; 137extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
123 138
diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h
index 133308bf595d..1543da8f85c1 100644
--- a/arch/arm/plat-samsung/include/plat/iic.h
+++ b/arch/arm/plat-samsung/include/plat/iic.h
@@ -55,10 +55,20 @@ struct s3c2410_platform_i2c {
55extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c); 55extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c);
56extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c); 56extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c);
57extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c); 57extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c);
58extern void s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *i2c);
59extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c);
60extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c);
61extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c);
62extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c);
58 63
59/* defined by architecture to configure gpio */ 64/* defined by architecture to configure gpio */
60extern void s3c_i2c0_cfg_gpio(struct platform_device *dev); 65extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
61extern void s3c_i2c1_cfg_gpio(struct platform_device *dev); 66extern void s3c_i2c1_cfg_gpio(struct platform_device *dev);
62extern void s3c_i2c2_cfg_gpio(struct platform_device *dev); 67extern void s3c_i2c2_cfg_gpio(struct platform_device *dev);
68extern void s3c_i2c3_cfg_gpio(struct platform_device *dev);
69extern void s3c_i2c4_cfg_gpio(struct platform_device *dev);
70extern void s3c_i2c5_cfg_gpio(struct platform_device *dev);
71extern void s3c_i2c6_cfg_gpio(struct platform_device *dev);
72extern void s3c_i2c7_cfg_gpio(struct platform_device *dev);
63 73
64#endif /* __ASM_ARCH_IIC_H */ 74#endif /* __ASM_ARCH_IIC_H */
diff --git a/arch/arm/plat-samsung/include/plat/map-base.h b/arch/arm/plat-samsung/include/plat/map-base.h
index 250be311c85b..3ffac4d2e4f0 100644
--- a/arch/arm/plat-samsung/include/plat/map-base.h
+++ b/arch/arm/plat-samsung/include/plat/map-base.h
@@ -14,7 +14,7 @@
14#ifndef __ASM_PLAT_MAP_H 14#ifndef __ASM_PLAT_MAP_H
15#define __ASM_PLAT_MAP_H __FILE__ 15#define __ASM_PLAT_MAP_H __FILE__
16 16
17/* Fit all our registers in at 0xF4000000 upwards, trying to use as 17/* Fit all our registers in at 0xF6000000 upwards, trying to use as
18 * little of the VA space as possible so vmalloc and friends have a 18 * little of the VA space as possible so vmalloc and friends have a
19 * better chance of getting memory. 19 * better chance of getting memory.
20 * 20 *
@@ -22,7 +22,7 @@
22 * an single MOVS instruction (ie, only 8 bits of set data) 22 * an single MOVS instruction (ie, only 8 bits of set data)
23 */ 23 */
24 24
25#define S3C_ADDR_BASE (0xF4000000) 25#define S3C_ADDR_BASE 0xF6000000
26 26
27#ifndef __ASSEMBLY__ 27#ifndef __ASSEMBLY__
28#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x)) 28#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
diff --git a/arch/arm/plat-samsung/include/plat/nand-core.h b/arch/arm/plat-samsung/include/plat/nand-core.h
new file mode 100644
index 000000000000..6de20789a95e
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/nand-core.h
@@ -0,0 +1,28 @@
1/* arch/arm/plat-samsung/include/plat/nand-core.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S3C - Nand Controller core functions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_NAND_CORE_H
14#define __ASM_ARCH_NAND_CORE_H __FILE__
15
16/* These functions are only for use with the core support code, such as
17 * the cpu specific initialisation code
18 */
19
20/* re-define device name depending on support. */
21static inline void s3c_nand_setname(char *name)
22{
23#ifdef CONFIG_S3C_DEV_NAND
24 s3c_device_nand.name = name;
25#endif
26}
27
28#endif /* __ASM_ARCH_NAND_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 30844c263d03..85853f8c4c5d 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -28,11 +28,17 @@ enum cd_types {
28 S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */ 28 S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */
29}; 29};
30 30
31enum clk_types {
32 S3C_SDHCI_CLK_DIV_INTERNAL, /* use mmc internal clock divider */
33 S3C_SDHCI_CLK_DIV_EXTERNAL, /* use external clock divider */
34};
35
31/** 36/**
32 * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI 37 * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
33 * @max_width: The maximum number of data bits supported. 38 * @max_width: The maximum number of data bits supported.
34 * @host_caps: Standard MMC host capabilities bit field. 39 * @host_caps: Standard MMC host capabilities bit field.
35 * @cd_type: Type of Card Detection method (see cd_types enum above) 40 * @cd_type: Type of Card Detection method (see cd_types enum above)
41 * @clk_type: Type of clock divider method (see clk_types enum above)
36 * @ext_cd_init: Initialize external card detect subsystem. Called on 42 * @ext_cd_init: Initialize external card detect subsystem. Called on
37 * sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL. 43 * sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL.
38 * notify_func argument is a callback to the sdhci-s3c driver 44 * notify_func argument is a callback to the sdhci-s3c driver
@@ -59,6 +65,7 @@ struct s3c_sdhci_platdata {
59 unsigned int max_width; 65 unsigned int max_width;
60 unsigned int host_caps; 66 unsigned int host_caps;
61 enum cd_types cd_type; 67 enum cd_types cd_type;
68 enum clk_types clk_type;
62 69
63 char **clocks; /* set of clock sources */ 70 char **clocks; /* set of clock sources */
64 71
@@ -110,6 +117,10 @@ extern void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
110extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w); 117extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
111extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w); 118extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
112extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w); 119extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
120extern void s5pv310_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
121extern void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
122extern void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
123extern void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
113 124
114/* S3C64XX SDHCI setup */ 125/* S3C64XX SDHCI setup */
115 126
@@ -288,4 +299,57 @@ static inline void s5pv210_default_sdhci3(void) { }
288 299
289#endif /* CONFIG_S5PV210_SETUP_SDHCI */ 300#endif /* CONFIG_S5PV210_SETUP_SDHCI */
290 301
302/* S5PV310 SDHCI setup */
303#ifdef CONFIG_S5PV310_SETUP_SDHCI
304extern char *s5pv310_hsmmc_clksrcs[4];
305
306extern void s5pv310_setup_sdhci_cfg_card(struct platform_device *dev,
307 void __iomem *r,
308 struct mmc_ios *ios,
309 struct mmc_card *card);
310
311static inline void s5pv310_default_sdhci0(void)
312{
313#ifdef CONFIG_S3C_DEV_HSMMC
314 s3c_hsmmc0_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
315 s3c_hsmmc0_def_platdata.cfg_gpio = s5pv310_setup_sdhci0_cfg_gpio;
316 s3c_hsmmc0_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
317#endif
318}
319
320static inline void s5pv310_default_sdhci1(void)
321{
322#ifdef CONFIG_S3C_DEV_HSMMC1
323 s3c_hsmmc1_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
324 s3c_hsmmc1_def_platdata.cfg_gpio = s5pv310_setup_sdhci1_cfg_gpio;
325 s3c_hsmmc1_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
326#endif
327}
328
329static inline void s5pv310_default_sdhci2(void)
330{
331#ifdef CONFIG_S3C_DEV_HSMMC2
332 s3c_hsmmc2_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
333 s3c_hsmmc2_def_platdata.cfg_gpio = s5pv310_setup_sdhci2_cfg_gpio;
334 s3c_hsmmc2_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
335#endif
336}
337
338static inline void s5pv310_default_sdhci3(void)
339{
340#ifdef CONFIG_S3C_DEV_HSMMC3
341 s3c_hsmmc3_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
342 s3c_hsmmc3_def_platdata.cfg_gpio = s5pv310_setup_sdhci3_cfg_gpio;
343 s3c_hsmmc3_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
344#endif
345}
346
347#else
348static inline void s5pv310_default_sdhci0(void) { }
349static inline void s5pv310_default_sdhci1(void) { }
350static inline void s5pv310_default_sdhci2(void) { }
351static inline void s5pv310_default_sdhci3(void) { }
352
353#endif /* CONFIG_S5PV310_SETUP_SDHCI */
354
291#endif /* __PLAT_S3C_SDHCI_H */ 355#endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
index 7df03f87fbfa..96528200eb79 100644
--- a/arch/arm/plat-samsung/pm-gpio.c
+++ b/arch/arm/plat-samsung/pm-gpio.c
@@ -192,7 +192,7 @@ struct s3c_gpio_pm s3c_gpio_pm_2bit = {
192 .resume = s3c_gpio_pm_2bit_resume, 192 .resume = s3c_gpio_pm_2bit_resume,
193}; 193};
194 194
195#ifdef CONFIG_ARCH_S3C64XX 195#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P)
196static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip) 196static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
197{ 197{
198 chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON); 198 chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
@@ -302,7 +302,7 @@ struct s3c_gpio_pm s3c_gpio_pm_4bit = {
302 .save = s3c_gpio_pm_4bit_save, 302 .save = s3c_gpio_pm_4bit_save,
303 .resume = s3c_gpio_pm_4bit_resume, 303 .resume = s3c_gpio_pm_4bit_resume,
304}; 304};
305#endif /* CONFIG_ARCH_S3C64XX */ 305#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */
306 306
307/** 307/**
308 * s3c_pm_save_gpio() - save gpio chip data for suspend 308 * s3c_pm_save_gpio() - save gpio chip data for suspend
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c
index a91305a60aed..b4ff8d74ac40 100644
--- a/arch/arm/plat-samsung/s3c-pl330.c
+++ b/arch/arm/plat-samsung/s3c-pl330.c
@@ -15,6 +15,8 @@
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/clk.h>
19#include <linux/err.h>
18 20
19#include <asm/hardware/pl330.h> 21#include <asm/hardware/pl330.h>
20 22
@@ -27,6 +29,7 @@
27 * @node: To attach to the global list of DMACs. 29 * @node: To attach to the global list of DMACs.
28 * @pi: PL330 configuration info for the DMAC. 30 * @pi: PL330 configuration info for the DMAC.
29 * @kmcache: Pool to quickly allocate xfers for all channels in the dmac. 31 * @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
32 * @clk: Pointer of DMAC operation clock.
30 */ 33 */
31struct s3c_pl330_dmac { 34struct s3c_pl330_dmac {
32 unsigned busy_chan; 35 unsigned busy_chan;
@@ -34,6 +37,7 @@ struct s3c_pl330_dmac {
34 struct list_head node; 37 struct list_head node;
35 struct pl330_info *pi; 38 struct pl330_info *pi;
36 struct kmem_cache *kmcache; 39 struct kmem_cache *kmcache;
40 struct clk *clk;
37}; 41};
38 42
39/** 43/**
@@ -1072,16 +1076,25 @@ static int pl330_probe(struct platform_device *pdev)
1072 if (ret) 1076 if (ret)
1073 goto probe_err4; 1077 goto probe_err4;
1074 1078
1075 ret = pl330_add(pl330_info);
1076 if (ret)
1077 goto probe_err5;
1078
1079 /* Allocate a new DMAC */ 1079 /* Allocate a new DMAC */
1080 s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL); 1080 s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
1081 if (!s3c_pl330_dmac) { 1081 if (!s3c_pl330_dmac) {
1082 ret = -ENOMEM; 1082 ret = -ENOMEM;
1083 goto probe_err5;
1084 }
1085
1086 /* Get operation clock and enable it */
1087 s3c_pl330_dmac->clk = clk_get(&pdev->dev, "pdma");
1088 if (IS_ERR(s3c_pl330_dmac->clk)) {
1089 dev_err(&pdev->dev, "Cannot get operation clock.\n");
1090 ret = -EINVAL;
1083 goto probe_err6; 1091 goto probe_err6;
1084 } 1092 }
1093 clk_enable(s3c_pl330_dmac->clk);
1094
1095 ret = pl330_add(pl330_info);
1096 if (ret)
1097 goto probe_err7;
1085 1098
1086 /* Hook the info */ 1099 /* Hook the info */
1087 s3c_pl330_dmac->pi = pl330_info; 1100 s3c_pl330_dmac->pi = pl330_info;
@@ -1094,7 +1107,7 @@ static int pl330_probe(struct platform_device *pdev)
1094 1107
1095 if (!s3c_pl330_dmac->kmcache) { 1108 if (!s3c_pl330_dmac->kmcache) {
1096 ret = -ENOMEM; 1109 ret = -ENOMEM;
1097 goto probe_err7; 1110 goto probe_err8;
1098 } 1111 }
1099 1112
1100 /* Get the list of peripherals */ 1113 /* Get the list of peripherals */
@@ -1120,10 +1133,13 @@ static int pl330_probe(struct platform_device *pdev)
1120 1133
1121 return 0; 1134 return 0;
1122 1135
1136probe_err8:
1137 pl330_del(pl330_info);
1123probe_err7: 1138probe_err7:
1124 kfree(s3c_pl330_dmac); 1139 clk_disable(s3c_pl330_dmac->clk);
1140 clk_put(s3c_pl330_dmac->clk);
1125probe_err6: 1141probe_err6:
1126 pl330_del(pl330_info); 1142 kfree(s3c_pl330_dmac);
1127probe_err5: 1143probe_err5:
1128 free_irq(irq, pl330_info); 1144 free_irq(irq, pl330_info);
1129probe_err4: 1145probe_err4:
@@ -1188,6 +1204,10 @@ static int pl330_remove(struct platform_device *pdev)
1188 } 1204 }
1189 } 1205 }
1190 1206
1207 /* Disable operation clock */
1208 clk_disable(dmac->clk);
1209 clk_put(dmac->clk);
1210
1191 /* Remove the DMAC */ 1211 /* Remove the DMAC */
1192 list_del(&dmac->node); 1212 list_del(&dmac->node);
1193 kfree(dmac); 1213 kfree(dmac);
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 881a3a5f5647..07ea908c510d 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -176,6 +176,21 @@ static void ap320_wvga_power_off(void *board_data)
176 __raw_writew(0, FPGA_LCDREG); 176 __raw_writew(0, FPGA_LCDREG);
177} 177}
178 178
179const static struct fb_videomode ap325rxa_lcdc_modes[] = {
180 {
181 .name = "LB070WV1",
182 .xres = 800,
183 .yres = 480,
184 .left_margin = 32,
185 .right_margin = 160,
186 .hsync_len = 8,
187 .upper_margin = 63,
188 .lower_margin = 80,
189 .vsync_len = 1,
190 .sync = 0, /* hsync and vsync are active low */
191 },
192};
193
179static struct sh_mobile_lcdc_info lcdc_info = { 194static struct sh_mobile_lcdc_info lcdc_info = {
180 .clock_source = LCDC_CLK_EXTERNAL, 195 .clock_source = LCDC_CLK_EXTERNAL,
181 .ch[0] = { 196 .ch[0] = {
@@ -183,18 +198,8 @@ static struct sh_mobile_lcdc_info lcdc_info = {
183 .bpp = 16, 198 .bpp = 16,
184 .interface_type = RGB18, 199 .interface_type = RGB18,
185 .clock_divider = 1, 200 .clock_divider = 1,
186 .lcd_cfg = { 201 .lcd_cfg = ap325rxa_lcdc_modes,
187 .name = "LB070WV1", 202 .num_cfg = ARRAY_SIZE(ap325rxa_lcdc_modes),
188 .xres = 800,
189 .yres = 480,
190 .left_margin = 32,
191 .right_margin = 160,
192 .hsync_len = 8,
193 .upper_margin = 63,
194 .lower_margin = 80,
195 .vsync_len = 1,
196 .sync = 0, /* hsync and vsync are active low */
197 },
198 .lcd_size_cfg = { /* 7.0 inch */ 203 .lcd_size_cfg = { /* 7.0 inch */
199 .width = 152, 204 .width = 152,
200 .height = 91, 205 .height = 91,
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index ddc7e4e4d2a0..2eaeb9e59585 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -231,14 +231,41 @@ static struct platform_device usb1_common_device = {
231}; 231};
232 232
233/* LCDC */ 233/* LCDC */
234const static struct fb_videomode ecovec_lcd_modes[] = {
235 {
236 .name = "Panel",
237 .xres = 800,
238 .yres = 480,
239 .left_margin = 220,
240 .right_margin = 110,
241 .hsync_len = 70,
242 .upper_margin = 20,
243 .lower_margin = 5,
244 .vsync_len = 5,
245 .sync = 0, /* hsync and vsync are active low */
246 },
247};
248
249const static struct fb_videomode ecovec_dvi_modes[] = {
250 {
251 .name = "DVI",
252 .xres = 1280,
253 .yres = 720,
254 .left_margin = 220,
255 .right_margin = 110,
256 .hsync_len = 40,
257 .upper_margin = 20,
258 .lower_margin = 5,
259 .vsync_len = 5,
260 .sync = 0, /* hsync and vsync are active low */
261 },
262};
263
234static struct sh_mobile_lcdc_info lcdc_info = { 264static struct sh_mobile_lcdc_info lcdc_info = {
235 .ch[0] = { 265 .ch[0] = {
236 .interface_type = RGB18, 266 .interface_type = RGB18,
237 .chan = LCDC_CHAN_MAINLCD, 267 .chan = LCDC_CHAN_MAINLCD,
238 .bpp = 16, 268 .bpp = 16,
239 .lcd_cfg = {
240 .sync = 0, /* hsync and vsync are active low */
241 },
242 .lcd_size_cfg = { /* 7.0 inch */ 269 .lcd_size_cfg = { /* 7.0 inch */
243 .width = 152, 270 .width = 152,
244 .height = 91, 271 .height = 91,
@@ -1075,33 +1102,18 @@ static int __init arch_setup(void)
1075 if (gpio_get_value(GPIO_PTE6)) { 1102 if (gpio_get_value(GPIO_PTE6)) {
1076 /* DVI */ 1103 /* DVI */
1077 lcdc_info.clock_source = LCDC_CLK_EXTERNAL; 1104 lcdc_info.clock_source = LCDC_CLK_EXTERNAL;
1078 lcdc_info.ch[0].clock_divider = 1, 1105 lcdc_info.ch[0].clock_divider = 1;
1079 lcdc_info.ch[0].lcd_cfg.name = "DVI"; 1106 lcdc_info.ch[0].lcd_cfg = ecovec_dvi_modes;
1080 lcdc_info.ch[0].lcd_cfg.xres = 1280; 1107 lcdc_info.ch[0].num_cfg = ARRAY_SIZE(ecovec_dvi_modes);
1081 lcdc_info.ch[0].lcd_cfg.yres = 720;
1082 lcdc_info.ch[0].lcd_cfg.left_margin = 220;
1083 lcdc_info.ch[0].lcd_cfg.right_margin = 110;
1084 lcdc_info.ch[0].lcd_cfg.hsync_len = 40;
1085 lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
1086 lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
1087 lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
1088 1108
1089 gpio_set_value(GPIO_PTA2, 1); 1109 gpio_set_value(GPIO_PTA2, 1);
1090 gpio_set_value(GPIO_PTU1, 1); 1110 gpio_set_value(GPIO_PTU1, 1);
1091 } else { 1111 } else {
1092 /* Panel */ 1112 /* Panel */
1093
1094 lcdc_info.clock_source = LCDC_CLK_PERIPHERAL; 1113 lcdc_info.clock_source = LCDC_CLK_PERIPHERAL;
1095 lcdc_info.ch[0].clock_divider = 2, 1114 lcdc_info.ch[0].clock_divider = 2;
1096 lcdc_info.ch[0].lcd_cfg.name = "Panel"; 1115 lcdc_info.ch[0].lcd_cfg = ecovec_lcd_modes;
1097 lcdc_info.ch[0].lcd_cfg.xres = 800; 1116 lcdc_info.ch[0].num_cfg = ARRAY_SIZE(ecovec_lcd_modes);
1098 lcdc_info.ch[0].lcd_cfg.yres = 480;
1099 lcdc_info.ch[0].lcd_cfg.left_margin = 220;
1100 lcdc_info.ch[0].lcd_cfg.right_margin = 110;
1101 lcdc_info.ch[0].lcd_cfg.hsync_len = 70;
1102 lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
1103 lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
1104 lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
1105 1117
1106 gpio_set_value(GPIO_PTR1, 1); 1118 gpio_set_value(GPIO_PTR1, 1);
1107 1119
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 1742849db648..9b60eaabf8f3 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -126,6 +126,21 @@ static struct platform_device kfr2r09_sh_keysc_device = {
126 }, 126 },
127}; 127};
128 128
129const static struct fb_videomode kfr2r09_lcdc_modes[] = {
130 {
131 .name = "TX07D34VM0AAA",
132 .xres = 240,
133 .yres = 400,
134 .left_margin = 0,
135 .right_margin = 16,
136 .hsync_len = 8,
137 .upper_margin = 0,
138 .lower_margin = 1,
139 .vsync_len = 1,
140 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
141 },
142};
143
129static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = { 144static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
130 .clock_source = LCDC_CLK_BUS, 145 .clock_source = LCDC_CLK_BUS,
131 .ch[0] = { 146 .ch[0] = {
@@ -134,18 +149,8 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
134 .interface_type = SYS18, 149 .interface_type = SYS18,
135 .clock_divider = 6, 150 .clock_divider = 6,
136 .flags = LCDC_FLAGS_DWPOL, 151 .flags = LCDC_FLAGS_DWPOL,
137 .lcd_cfg = { 152 .lcd_cfg = kfr2r09_lcdc_modes,
138 .name = "TX07D34VM0AAA", 153 .num_cfg = ARRAY_SIZE(kfr2r09_lcdc_modes),
139 .xres = 240,
140 .yres = 400,
141 .left_margin = 0,
142 .right_margin = 16,
143 .hsync_len = 8,
144 .upper_margin = 0,
145 .lower_margin = 1,
146 .vsync_len = 1,
147 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
148 },
149 .lcd_size_cfg = { 154 .lcd_size_cfg = {
150 .width = 35, 155 .width = 35,
151 .height = 58, 156 .height = 58,
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 03af84842559..c8acfec98695 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -213,51 +213,55 @@ static struct platform_device migor_nand_flash_device = {
213 } 213 }
214}; 214};
215 215
216const static struct fb_videomode migor_lcd_modes[] = {
217 {
218#if defined(CONFIG_SH_MIGOR_RTA_WVGA)
219 .name = "LB070WV1",
220 .xres = 800,
221 .yres = 480,
222 .left_margin = 64,
223 .right_margin = 16,
224 .hsync_len = 120,
225 .sync = 0,
226#elif defined(CONFIG_SH_MIGOR_QVGA)
227 .name = "PH240320T",
228 .xres = 320,
229 .yres = 240,
230 .left_margin = 0,
231 .right_margin = 16,
232 .hsync_len = 8,
233 .sync = FB_SYNC_HOR_HIGH_ACT,
234#endif
235 .upper_margin = 1,
236 .lower_margin = 17,
237 .vsync_len = 2,
238 },
239};
240
216static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = { 241static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
217#ifdef CONFIG_SH_MIGOR_RTA_WVGA 242#if defined(CONFIG_SH_MIGOR_RTA_WVGA)
218 .clock_source = LCDC_CLK_BUS, 243 .clock_source = LCDC_CLK_BUS,
219 .ch[0] = { 244 .ch[0] = {
220 .chan = LCDC_CHAN_MAINLCD, 245 .chan = LCDC_CHAN_MAINLCD,
221 .bpp = 16, 246 .bpp = 16,
222 .interface_type = RGB16, 247 .interface_type = RGB16,
223 .clock_divider = 2, 248 .clock_divider = 2,
224 .lcd_cfg = { 249 .lcd_cfg = migor_lcd_modes,
225 .name = "LB070WV1", 250 .num_cfg = ARRAY_SIZE(migor_lcd_modes),
226 .xres = 800,
227 .yres = 480,
228 .left_margin = 64,
229 .right_margin = 16,
230 .hsync_len = 120,
231 .upper_margin = 1,
232 .lower_margin = 17,
233 .vsync_len = 2,
234 .sync = 0,
235 },
236 .lcd_size_cfg = { /* 7.0 inch */ 251 .lcd_size_cfg = { /* 7.0 inch */
237 .width = 152, 252 .width = 152,
238 .height = 91, 253 .height = 91,
239 }, 254 },
240 } 255 }
241#endif 256#elif defined(CONFIG_SH_MIGOR_QVGA)
242#ifdef CONFIG_SH_MIGOR_QVGA
243 .clock_source = LCDC_CLK_PERIPHERAL, 257 .clock_source = LCDC_CLK_PERIPHERAL,
244 .ch[0] = { 258 .ch[0] = {
245 .chan = LCDC_CHAN_MAINLCD, 259 .chan = LCDC_CHAN_MAINLCD,
246 .bpp = 16, 260 .bpp = 16,
247 .interface_type = SYS16A, 261 .interface_type = SYS16A,
248 .clock_divider = 10, 262 .clock_divider = 10,
249 .lcd_cfg = { 263 .lcd_cfg = migor_lcd_modes,
250 .name = "PH240320T", 264 .num_cfg = ARRAY_SIZE(migor_lcd_modes),
251 .xres = 320,
252 .yres = 240,
253 .left_margin = 0,
254 .right_margin = 16,
255 .hsync_len = 8,
256 .upper_margin = 1,
257 .lower_margin = 17,
258 .vsync_len = 2,
259 .sync = FB_SYNC_HOR_HIGH_ACT,
260 },
261 .lcd_size_cfg = { /* 2.4 inch */ 265 .lcd_size_cfg = { /* 2.4 inch */
262 .width = 49, 266 .width = 49,
263 .height = 37, 267 .height = 37,
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 8cc1d7295d85..c31d228fdfc6 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -144,16 +144,42 @@ static struct platform_device nor_flash_device = {
144}; 144};
145 145
146/* LCDC */ 146/* LCDC */
147const static struct fb_videomode lcdc_720p_modes[] = {
148 {
149 .name = "LB070WV1",
150 .sync = 0, /* hsync and vsync are active low */
151 .xres = 1280,
152 .yres = 720,
153 .left_margin = 220,
154 .right_margin = 110,
155 .hsync_len = 40,
156 .upper_margin = 20,
157 .lower_margin = 5,
158 .vsync_len = 5,
159 },
160};
161
162const static struct fb_videomode lcdc_vga_modes[] = {
163 {
164 .name = "LB070WV1",
165 .sync = 0, /* hsync and vsync are active low */
166 .xres = 640,
167 .yres = 480,
168 .left_margin = 105,
169 .right_margin = 50,
170 .hsync_len = 96,
171 .upper_margin = 33,
172 .lower_margin = 10,
173 .vsync_len = 2,
174 },
175};
176
147static struct sh_mobile_lcdc_info lcdc_info = { 177static struct sh_mobile_lcdc_info lcdc_info = {
148 .clock_source = LCDC_CLK_EXTERNAL, 178 .clock_source = LCDC_CLK_EXTERNAL,
149 .ch[0] = { 179 .ch[0] = {
150 .chan = LCDC_CHAN_MAINLCD, 180 .chan = LCDC_CHAN_MAINLCD,
151 .bpp = 16, 181 .bpp = 16,
152 .clock_divider = 1, 182 .clock_divider = 1,
153 .lcd_cfg = {
154 .name = "LB070WV1",
155 .sync = 0, /* hsync and vsync are active low */
156 },
157 .lcd_size_cfg = { /* 7.0 inch */ 183 .lcd_size_cfg = { /* 7.0 inch */
158 .width = 152, 184 .width = 152,
159 .height = 91, 185 .height = 91,
@@ -908,24 +934,12 @@ static int __init devices_setup(void)
908 934
909 if (sw & SW41_B) { 935 if (sw & SW41_B) {
910 /* 720p */ 936 /* 720p */
911 lcdc_info.ch[0].lcd_cfg.xres = 1280; 937 lcdc_info.ch[0].lcd_cfg = lcdc_720p_modes;
912 lcdc_info.ch[0].lcd_cfg.yres = 720; 938 lcdc_info.ch[0].num_cfg = ARRAY_SIZE(lcdc_720p_modes);
913 lcdc_info.ch[0].lcd_cfg.left_margin = 220;
914 lcdc_info.ch[0].lcd_cfg.right_margin = 110;
915 lcdc_info.ch[0].lcd_cfg.hsync_len = 40;
916 lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
917 lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
918 lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
919 } else { 939 } else {
920 /* VGA */ 940 /* VGA */
921 lcdc_info.ch[0].lcd_cfg.xres = 640; 941 lcdc_info.ch[0].lcd_cfg = lcdc_vga_modes;
922 lcdc_info.ch[0].lcd_cfg.yres = 480; 942 lcdc_info.ch[0].num_cfg = ARRAY_SIZE(lcdc_vga_modes);
923 lcdc_info.ch[0].lcd_cfg.left_margin = 105;
924 lcdc_info.ch[0].lcd_cfg.right_margin = 50;
925 lcdc_info.ch[0].lcd_cfg.hsync_len = 96;
926 lcdc_info.ch[0].lcd_cfg.upper_margin = 33;
927 lcdc_info.ch[0].lcd_cfg.lower_margin = 10;
928 lcdc_info.ch[0].lcd_cfg.vsync_len = 2;
929 } 943 }
930 944
931 if (sw & SW41_A) { 945 if (sw & SW41_A) {
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 5699ce0c1780..3f3d431033ca 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -123,83 +123,87 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
123 u32 linelength; 123 u32 linelength;
124 bool yuv; 124 bool yuv;
125 125
126 /* Select data format */ 126 /*
127 * Select data format. MIPI DSI is not hot-pluggable, so, we just use
128 * the default videomode. If this ever becomes a problem, We'll have to
129 * move this to mipi_display_on() above and use info->var.xres
130 */
127 switch (pdata->data_format) { 131 switch (pdata->data_format) {
128 case MIPI_RGB888: 132 case MIPI_RGB888:
129 pctype = 0; 133 pctype = 0;
130 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; 134 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
131 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; 135 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
132 linelength = ch->lcd_cfg.xres * 3; 136 linelength = ch->lcd_cfg[0].xres * 3;
133 yuv = false; 137 yuv = false;
134 break; 138 break;
135 case MIPI_RGB565: 139 case MIPI_RGB565:
136 pctype = 1; 140 pctype = 1;
137 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; 141 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
138 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; 142 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
139 linelength = ch->lcd_cfg.xres * 2; 143 linelength = ch->lcd_cfg[0].xres * 2;
140 yuv = false; 144 yuv = false;
141 break; 145 break;
142 case MIPI_RGB666_LP: 146 case MIPI_RGB666_LP:
143 pctype = 2; 147 pctype = 2;
144 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; 148 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
145 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; 149 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
146 linelength = ch->lcd_cfg.xres * 3; 150 linelength = ch->lcd_cfg[0].xres * 3;
147 yuv = false; 151 yuv = false;
148 break; 152 break;
149 case MIPI_RGB666: 153 case MIPI_RGB666:
150 pctype = 3; 154 pctype = 3;
151 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; 155 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
152 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; 156 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
153 linelength = (ch->lcd_cfg.xres * 18 + 7) / 8; 157 linelength = (ch->lcd_cfg[0].xres * 18 + 7) / 8;
154 yuv = false; 158 yuv = false;
155 break; 159 break;
156 case MIPI_BGR888: 160 case MIPI_BGR888:
157 pctype = 8; 161 pctype = 8;
158 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; 162 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
159 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; 163 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
160 linelength = ch->lcd_cfg.xres * 3; 164 linelength = ch->lcd_cfg[0].xres * 3;
161 yuv = false; 165 yuv = false;
162 break; 166 break;
163 case MIPI_BGR565: 167 case MIPI_BGR565:
164 pctype = 9; 168 pctype = 9;
165 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; 169 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
166 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; 170 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
167 linelength = ch->lcd_cfg.xres * 2; 171 linelength = ch->lcd_cfg[0].xres * 2;
168 yuv = false; 172 yuv = false;
169 break; 173 break;
170 case MIPI_BGR666_LP: 174 case MIPI_BGR666_LP:
171 pctype = 0xa; 175 pctype = 0xa;
172 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; 176 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
173 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; 177 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
174 linelength = ch->lcd_cfg.xres * 3; 178 linelength = ch->lcd_cfg[0].xres * 3;
175 yuv = false; 179 yuv = false;
176 break; 180 break;
177 case MIPI_BGR666: 181 case MIPI_BGR666:
178 pctype = 0xb; 182 pctype = 0xb;
179 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; 183 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
180 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; 184 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
181 linelength = (ch->lcd_cfg.xres * 18 + 7) / 8; 185 linelength = (ch->lcd_cfg[0].xres * 18 + 7) / 8;
182 yuv = false; 186 yuv = false;
183 break; 187 break;
184 case MIPI_YUYV: 188 case MIPI_YUYV:
185 pctype = 4; 189 pctype = 4;
186 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; 190 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
187 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; 191 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
188 linelength = ch->lcd_cfg.xres * 2; 192 linelength = ch->lcd_cfg[0].xres * 2;
189 yuv = true; 193 yuv = true;
190 break; 194 break;
191 case MIPI_UYVY: 195 case MIPI_UYVY:
192 pctype = 5; 196 pctype = 5;
193 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; 197 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
194 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; 198 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
195 linelength = ch->lcd_cfg.xres * 2; 199 linelength = ch->lcd_cfg[0].xres * 2;
196 yuv = true; 200 yuv = true;
197 break; 201 break;
198 case MIPI_YUV420_L: 202 case MIPI_YUV420_L:
199 pctype = 6; 203 pctype = 6;
200 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; 204 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
201 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; 205 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
202 linelength = (ch->lcd_cfg.xres * 12 + 7) / 8; 206 linelength = (ch->lcd_cfg[0].xres * 12 + 7) / 8;
203 yuv = true; 207 yuv = true;
204 break; 208 break;
205 case MIPI_YUV420: 209 case MIPI_YUV420:
@@ -207,7 +211,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
207 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; 211 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
208 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; 212 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
209 /* Length of U/V line */ 213 /* Length of U/V line */
210 linelength = (ch->lcd_cfg.xres + 1) / 2; 214 linelength = (ch->lcd_cfg[0].xres + 1) / 2;
211 yuv = true; 215 yuv = true;
212 break; 216 break;
213 default: 217 default:
@@ -281,7 +285,7 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
281 iowrite32(0x00e00000, base + 0x8024); /* VMCTR2 */ 285 iowrite32(0x00e00000, base + 0x8024); /* VMCTR2 */
282 /* 286 /*
283 * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see 287 * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see
284 * sh_mobile_lcdc_info.ch[0].lcd_cfg.xres), HSALEN = 1 - default 288 * sh_mobile_lcdc_info.ch[0].lcd_cfg[0].xres), HSALEN = 1 - default
285 * (unused, since VMCTR2[HSABM] = 0) 289 * (unused, since VMCTR2[HSABM] = 0)
286 */ 290 */
287 iowrite32(1 | (linelength << 16), base + 0x8028); /* VMLEN1 */ 291 iowrite32(1 | (linelength << 16), base + 0x8028); /* VMLEN1 */
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index ef989d94511c..55b3077ff6ff 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -28,6 +28,8 @@
28#include <video/sh_mobile_hdmi.h> 28#include <video/sh_mobile_hdmi.h>
29#include <video/sh_mobile_lcdc.h> 29#include <video/sh_mobile_lcdc.h>
30 30
31#include "sh_mobile_lcdcfb.h"
32
31#define HDMI_SYSTEM_CTRL 0x00 /* System control */ 33#define HDMI_SYSTEM_CTRL 0x00 /* System control */
32#define HDMI_L_R_DATA_SWAP_CTRL_RPKT 0x01 /* L/R data swap control, 34#define HDMI_L_R_DATA_SWAP_CTRL_RPKT 0x01 /* L/R data swap control,
33 bits 19..16 of 20-bit N for Audio Clock Regeneration packet */ 35 bits 19..16 of 20-bit N for Audio Clock Regeneration packet */
@@ -206,12 +208,15 @@ enum hotplug_state {
206 208
207struct sh_hdmi { 209struct sh_hdmi {
208 void __iomem *base; 210 void __iomem *base;
209 enum hotplug_state hp_state; 211 enum hotplug_state hp_state; /* hot-plug status */
212 bool preprogrammed_mode; /* use a pre-programmed VIC or the external mode */
210 struct clk *hdmi_clk; 213 struct clk *hdmi_clk;
211 struct device *dev; 214 struct device *dev;
212 struct fb_info *info; 215 struct fb_info *info;
216 struct mutex mutex; /* Protect the info pointer */
213 struct delayed_work edid_work; 217 struct delayed_work edid_work;
214 struct fb_var_screeninfo var; 218 struct fb_var_screeninfo var;
219 struct fb_monspecs monspec;
215}; 220};
216 221
217static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg) 222static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
@@ -277,7 +282,7 @@ static struct snd_soc_codec_driver soc_codec_dev_sh_hdmi = {
277 */ 282 */
278 283
279/* External video parameter settings */ 284/* External video parameter settings */
280static void hdmi_external_video_param(struct sh_hdmi *hdmi) 285static void sh_hdmi_external_video_param(struct sh_hdmi *hdmi)
281{ 286{
282 struct fb_var_screeninfo *var = &hdmi->var; 287 struct fb_var_screeninfo *var = &hdmi->var;
283 u16 htotal, hblank, hdelay, vtotal, vblank, vdelay, voffset; 288 u16 htotal, hblank, hdelay, vtotal, vblank, vdelay, voffset;
@@ -309,9 +314,9 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi)
309 if (var->sync & FB_SYNC_VERT_HIGH_ACT) 314 if (var->sync & FB_SYNC_VERT_HIGH_ACT)
310 sync |= 8; 315 sync |= 8;
311 316
312 pr_debug("H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n", 317 dev_dbg(hdmi->dev, "H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n",
313 htotal, hblank, hdelay, var->hsync_len, 318 htotal, hblank, hdelay, var->hsync_len,
314 vtotal, vblank, vdelay, var->vsync_len, sync); 319 vtotal, vblank, vdelay, var->vsync_len, sync);
315 320
316 hdmi_write(hdmi, sync | (voffset << 4), HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS); 321 hdmi_write(hdmi, sync | (voffset << 4), HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS);
317 322
@@ -336,7 +341,10 @@ static void hdmi_external_video_param(struct sh_hdmi *hdmi)
336 341
337 hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION); 342 hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION);
338 343
339 /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for manual mode */ 344 /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for external mode */
345 if (!hdmi->preprogrammed_mode)
346 hdmi_write(hdmi, sync | 1 | (voffset << 4),
347 HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS);
340} 348}
341 349
342/** 350/**
@@ -454,21 +462,61 @@ static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
454} 462}
455 463
456/** 464/**
457 * sh_hdmi_phy_config() 465 * sh_hdmi_phy_config() - configure the HDMI PHY for the used video mode
458 */ 466 */
459static void sh_hdmi_phy_config(struct sh_hdmi *hdmi) 467static void sh_hdmi_phy_config(struct sh_hdmi *hdmi)
460{ 468{
461 /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */ 469 if (hdmi->var.yres > 480) {
462 hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1); 470 /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */
463 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2); 471 /*
464 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3); 472 * [1:0] Speed_A
465 /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */ 473 * [3:2] Speed_B
466 hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5); 474 * [4] PLLA_Bypass
467 hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6); 475 * [6] DRV_TEST_EN
468 hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7); 476 * [7] DRV_TEST_IN
469 hdmi_write(hdmi, 0x0E, HDMI_SLIPHDMIT_PARAM_SETTINGS_8); 477 */
470 hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9); 478 hdmi_write(hdmi, 0x0f, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
471 hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10); 479 /* PLLB_CONFIG[17], PLLA_CONFIG[17] - not in PHY datasheet */
480 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
481 /*
482 * [2:0] BGR_I_OFFSET
483 * [6:4] BGR_V_OFFSET
484 */
485 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3);
486 /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */
487 hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5);
488 /*
489 * PLLA_CONFIG[15:8]: regulator voltage[0], CP current,
490 * LPF capacitance, LPF resistance[1]
491 */
492 hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6);
493 /* PLLB_CONFIG[7:0]: LPF resistance[0], VCO offset, VCO gain */
494 hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7);
495 /*
496 * PLLB_CONFIG[15:8]: regulator voltage[0], CP current,
497 * LPF capacitance, LPF resistance[1]
498 */
499 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
500 /* DRV_CONFIG, PE_CONFIG */
501 hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
502 /*
503 * [2:0] AMON_SEL (4 == LPF voltage)
504 * [4] PLLA_CONFIG[16]
505 * [5] PLLB_CONFIG[16]
506 */
507 hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
508 } else {
509 /* for 480p8bit 27MHz */
510 hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
511 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
512 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3);
513 hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5);
514 hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6);
515 hdmi_write(hdmi, 0x48, HDMI_SLIPHDMIT_PARAM_SETTINGS_7);
516 hdmi_write(hdmi, 0x0F, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
517 hdmi_write(hdmi, 0x20, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
518 hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
519 }
472} 520}
473 521
474/** 522/**
@@ -476,6 +524,8 @@ static void sh_hdmi_phy_config(struct sh_hdmi *hdmi)
476 */ 524 */
477static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi) 525static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
478{ 526{
527 u8 vic;
528
479 /* AVI InfoFrame */ 529 /* AVI InfoFrame */
480 hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_INDEX); 530 hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_INDEX);
481 531
@@ -500,9 +550,9 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
500 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB1); 550 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB1);
501 551
502 /* 552 /*
503 * C = No Data 553 * [7:6] C = Colorimetry: no data
504 * M = 16:9 Picture Aspect Ratio 554 * [5:4] M = 2: 16:9, 1: 4:3 Picture Aspect Ratio
505 * R = Same as picture aspect ratio 555 * [3:0] R = 8: Active Frame Aspect Ratio: same as picture aspect ratio
506 */ 556 */
507 hdmi_write(hdmi, 0x28, HDMI_CTRL_PKT_BUF_ACCESS_PB2); 557 hdmi_write(hdmi, 0x28, HDMI_CTRL_PKT_BUF_ACCESS_PB2);
508 558
@@ -516,9 +566,15 @@ static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
516 566
517 /* 567 /*
518 * VIC = 1280 x 720p: ignored if external config is used 568 * VIC = 1280 x 720p: ignored if external config is used
519 * Send 2 for 720 x 480p, 16 for 1080p 569 * Send 2 for 720 x 480p, 16 for 1080p, ignored in external mode
520 */ 570 */
521 hdmi_write(hdmi, 4, HDMI_CTRL_PKT_BUF_ACCESS_PB4); 571 if (hdmi->var.yres == 1080 && hdmi->var.xres == 1920)
572 vic = 16;
573 else if (hdmi->var.yres == 480 && hdmi->var.xres == 720)
574 vic = 2;
575 else
576 vic = 4;
577 hdmi_write(hdmi, vic, HDMI_CTRL_PKT_BUF_ACCESS_PB4);
522 578
523 /* PR = No Repetition */ 579 /* PR = No Repetition */
524 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB5); 580 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB5);
@@ -592,100 +648,6 @@ static void sh_hdmi_audio_infoframe_setup(struct sh_hdmi *hdmi)
592} 648}
593 649
594/** 650/**
595 * sh_hdmi_gamut_metadata_setup() - Gamut Metadata Packet of CONTROL PACKET
596 */
597static void sh_hdmi_gamut_metadata_setup(struct sh_hdmi *hdmi)
598{
599 int i;
600
601 /* Gamut Metadata Packet */
602 hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_INDEX);
603
604 /* Packet Type = 0x0A */
605 hdmi_write(hdmi, 0x0A, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
606 /* Gamut Packet is not used, so default value */
607 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
608 /* Gamut Packet is not used, so default value */
609 hdmi_write(hdmi, 0x10, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
610
611 /* GBD bytes 0 through 27 */
612 for (i = 0; i <= 27; i++)
613 /* HDMI_CTRL_PKT_BUF_ACCESS_PB0_63H - PB27_7EH */
614 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
615}
616
617/**
618 * sh_hdmi_acp_setup() - Audio Content Protection Packet (ACP)
619 */
620static void sh_hdmi_acp_setup(struct sh_hdmi *hdmi)
621{
622 int i;
623
624 /* Audio Content Protection Packet (ACP) */
625 hdmi_write(hdmi, 0x01, HDMI_CTRL_PKT_BUF_INDEX);
626
627 /* Packet Type = 0x04 */
628 hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
629 /* ACP_Type */
630 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
631 /* Reserved (0) */
632 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
633
634 /* GBD bytes 0 through 27 */
635 for (i = 0; i <= 27; i++)
636 /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
637 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
638}
639
640/**
641 * sh_hdmi_isrc1_setup() - ISRC1 Packet
642 */
643static void sh_hdmi_isrc1_setup(struct sh_hdmi *hdmi)
644{
645 int i;
646
647 /* ISRC1 Packet */
648 hdmi_write(hdmi, 0x02, HDMI_CTRL_PKT_BUF_INDEX);
649
650 /* Packet Type = 0x05 */
651 hdmi_write(hdmi, 0x05, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
652 /* ISRC_Cont, ISRC_Valid, Reserved (0), ISRC_Status */
653 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
654 /* Reserved (0) */
655 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
656
657 /* PB0 UPC_EAN_ISRC_0-15 */
658 /* Bytes PB16-PB27 shall be set to a value of 0. */
659 for (i = 0; i <= 27; i++)
660 /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
661 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
662}
663
664/**
665 * sh_hdmi_isrc2_setup() - ISRC2 Packet
666 */
667static void sh_hdmi_isrc2_setup(struct sh_hdmi *hdmi)
668{
669 int i;
670
671 /* ISRC2 Packet */
672 hdmi_write(hdmi, 0x03, HDMI_CTRL_PKT_BUF_INDEX);
673
674 /* HB0 Packet Type = 0x06 */
675 hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
676 /* Reserved (0) */
677 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
678 /* Reserved (0) */
679 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
680
681 /* PB0 UPC_EAN_ISRC_16-31 */
682 /* Bytes PB16-PB27 shall be set to a value of 0. */
683 for (i = 0; i <= 27; i++)
684 /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
685 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
686}
687
688/**
689 * sh_hdmi_configure() - Initialise HDMI for output 651 * sh_hdmi_configure() - Initialise HDMI for output
690 */ 652 */
691static void sh_hdmi_configure(struct sh_hdmi *hdmi) 653static void sh_hdmi_configure(struct sh_hdmi *hdmi)
@@ -705,18 +667,6 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
705 /* Audio InfoFrame */ 667 /* Audio InfoFrame */
706 sh_hdmi_audio_infoframe_setup(hdmi); 668 sh_hdmi_audio_infoframe_setup(hdmi);
707 669
708 /* Gamut Metadata packet */
709 sh_hdmi_gamut_metadata_setup(hdmi);
710
711 /* Audio Content Protection (ACP) Packet */
712 sh_hdmi_acp_setup(hdmi);
713
714 /* ISRC1 Packet */
715 sh_hdmi_isrc1_setup(hdmi);
716
717 /* ISRC2 Packet */
718 sh_hdmi_isrc2_setup(hdmi);
719
720 /* 670 /*
721 * Control packet auto send with VSYNC control: auto send 671 * Control packet auto send with VSYNC control: auto send
722 * General control, Gamut metadata, ISRC, and ACP packets 672 * General control, Gamut metadata, ISRC, and ACP packets
@@ -734,17 +684,42 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
734 hdmi_write(hdmi, 0x40, HDMI_SYSTEM_CTRL); 684 hdmi_write(hdmi, 0x40, HDMI_SYSTEM_CTRL);
735} 685}
736 686
737static void sh_hdmi_read_edid(struct sh_hdmi *hdmi) 687static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi,
688 const struct fb_videomode *mode)
738{ 689{
739 struct fb_var_screeninfo *var = &hdmi->var; 690 long target = PICOS2KHZ(mode->pixclock) * 1000,
740 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; 691 rate = clk_round_rate(hdmi->hdmi_clk, target);
741 struct fb_videomode *lcd_cfg = &pdata->lcd_chan->lcd_cfg; 692 unsigned long rate_error = rate > 0 ? abs(rate - target) : ULONG_MAX;
742 unsigned long height = var->height, width = var->width; 693
743 int i; 694 dev_dbg(hdmi->dev, "%u-%u-%u-%u x %u-%u-%u-%u\n",
695 mode->left_margin, mode->xres,
696 mode->right_margin, mode->hsync_len,
697 mode->upper_margin, mode->yres,
698 mode->lower_margin, mode->vsync_len);
699
700 dev_dbg(hdmi->dev, "\t@%lu(+/-%lu)Hz, e=%lu / 1000, r=%uHz\n", target,
701 rate_error, rate_error ? 10000 / (10 * target / rate_error) : 0,
702 mode->refresh);
703
704 return rate_error;
705}
706
707static int sh_hdmi_read_edid(struct sh_hdmi *hdmi)
708{
709 struct fb_var_screeninfo tmpvar;
710 struct fb_var_screeninfo *var = &tmpvar;
711 const struct fb_videomode *mode, *found = NULL;
712 struct fb_info *info = hdmi->info;
713 struct fb_modelist *modelist = NULL;
714 unsigned int f_width = 0, f_height = 0, f_refresh = 0;
715 unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */
716 bool exact_match = false;
744 u8 edid[128]; 717 u8 edid[128];
718 char *forced;
719 int i;
745 720
746 /* Read EDID */ 721 /* Read EDID */
747 pr_debug("Read back EDID code:"); 722 dev_dbg(hdmi->dev, "Read back EDID code:");
748 for (i = 0; i < 128; i++) { 723 for (i = 0; i < 128; i++) {
749 edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW); 724 edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW);
750#ifdef DEBUG 725#ifdef DEBUG
@@ -759,29 +734,97 @@ static void sh_hdmi_read_edid(struct sh_hdmi *hdmi)
759#ifdef DEBUG 734#ifdef DEBUG
760 printk(KERN_CONT "\n"); 735 printk(KERN_CONT "\n");
761#endif 736#endif
762 fb_parse_edid(edid, var); 737
763 pr_debug("%u-%u-%u-%u x %u-%u-%u-%u @ %lu kHz monitor detected\n", 738 fb_edid_to_monspecs(edid, &hdmi->monspec);
764 var->left_margin, var->xres, var->right_margin, var->hsync_len, 739
765 var->upper_margin, var->yres, var->lower_margin, var->vsync_len, 740 fb_get_options("sh_mobile_lcdc", &forced);
766 PICOS2KHZ(var->pixclock)); 741 if (forced && *forced) {
767 742 /* Only primitive parsing so far */
768 /* FIXME: Use user-provided configuration instead of EDID */ 743 i = sscanf(forced, "%ux%u@%u",
769 var->width = width; 744 &f_width, &f_height, &f_refresh);
770 var->xres = lcd_cfg->xres; 745 if (i < 2) {
771 var->xres_virtual = lcd_cfg->xres; 746 f_width = 0;
772 var->left_margin = lcd_cfg->left_margin; 747 f_height = 0;
773 var->right_margin = lcd_cfg->right_margin; 748 }
774 var->hsync_len = lcd_cfg->hsync_len; 749 dev_dbg(hdmi->dev, "Forced mode %ux%u@%uHz\n",
775 var->height = height; 750 f_width, f_height, f_refresh);
776 var->yres = lcd_cfg->yres; 751 }
777 var->yres_virtual = lcd_cfg->yres * 2; 752
778 var->upper_margin = lcd_cfg->upper_margin; 753 /* Walk monitor modes to find the best or the exact match */
779 var->lower_margin = lcd_cfg->lower_margin; 754 for (i = 0, mode = hdmi->monspec.modedb;
780 var->vsync_len = lcd_cfg->vsync_len; 755 f_width && f_height && i < hdmi->monspec.modedb_len && !exact_match;
781 var->sync = lcd_cfg->sync; 756 i++, mode++) {
782 var->pixclock = lcd_cfg->pixclock; 757 unsigned long rate_error = sh_hdmi_rate_error(hdmi, mode);
783 758
784 hdmi_external_video_param(hdmi); 759 /* No interest in unmatching modes */
760 if (f_width != mode->xres || f_height != mode->yres)
761 continue;
762 if (f_refresh == mode->refresh || (!f_refresh && !rate_error))
763 /*
764 * Exact match if either the refresh rate matches or it
765 * hasn't been specified and we've found a mode, for
766 * which we can configure the clock precisely
767 */
768 exact_match = true;
769 else if (found && found_rate_error <= rate_error)
770 /*
771 * We otherwise search for the closest matching clock
772 * rate - either if no refresh rate has been specified
773 * or we cannot find an exactly matching one
774 */
775 continue;
776
777 /* Check if supported: sufficient fb memory, supported clock-rate */
778 fb_videomode_to_var(var, mode);
779
780 if (info && info->fbops->fb_check_var &&
781 info->fbops->fb_check_var(var, info)) {
782 exact_match = false;
783 continue;
784 }
785
786 found = mode;
787 found_rate_error = rate_error;
788 }
789
790 /*
791 * TODO 1: if no ->info is present, postpone running the config until
792 * after ->info first gets registered.
793 * TODO 2: consider registering the HDMI platform device from the LCDC
794 * driver, and passing ->info with HDMI platform data.
795 */
796 if (info && !found) {
797 modelist = hdmi->info->modelist.next &&
798 !list_empty(&hdmi->info->modelist) ?
799 list_entry(hdmi->info->modelist.next,
800 struct fb_modelist, list) :
801 NULL;
802
803 if (modelist) {
804 found = &modelist->mode;
805 found_rate_error = sh_hdmi_rate_error(hdmi, found);
806 }
807 }
808
809 /* No cookie today */
810 if (!found)
811 return -ENXIO;
812
813 dev_info(hdmi->dev, "Using %s mode %ux%u@%uHz (%luHz), clock error %luHz\n",
814 modelist ? "default" : "EDID", found->xres, found->yres,
815 found->refresh, PICOS2KHZ(found->pixclock) * 1000, found_rate_error);
816
817 if ((found->xres == 720 && found->yres == 480) ||
818 (found->xres == 1280 && found->yres == 720) ||
819 (found->xres == 1920 && found->yres == 1080))
820 hdmi->preprogrammed_mode = true;
821 else
822 hdmi->preprogrammed_mode = false;
823
824 fb_videomode_to_var(&hdmi->var, found);
825 sh_hdmi_external_video_param(hdmi);
826
827 return 0;
785} 828}
786 829
787static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id) 830static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
@@ -809,8 +852,8 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
809 hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_2); 852 hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_2);
810 853
811 if (printk_ratelimit()) 854 if (printk_ratelimit())
812 pr_debug("IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n", 855 dev_dbg(hdmi->dev, "IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n",
813 irq, status1, mask1, status2, mask2); 856 irq, status1, mask1, status2, mask2);
814 857
815 if (!((status1 & mask1) | (status2 & mask2))) { 858 if (!((status1 & mask1) | (status2 & mask2))) {
816 return IRQ_NONE; 859 return IRQ_NONE;
@@ -821,7 +864,7 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
821 udelay(500); 864 udelay(500);
822 865
823 msens = hdmi_read(hdmi, HDMI_HOT_PLUG_MSENS_STATUS); 866 msens = hdmi_read(hdmi, HDMI_HOT_PLUG_MSENS_STATUS);
824 pr_debug("MSENS 0x%x\n", msens); 867 dev_dbg(hdmi->dev, "MSENS 0x%x\n", msens);
825 /* Check, if hot plug & MSENS pin status are both high */ 868 /* Check, if hot plug & MSENS pin status are both high */
826 if ((msens & 0xC0) == 0xC0) { 869 if ((msens & 0xC0) == 0xC0) {
827 /* Display plug in */ 870 /* Display plug in */
@@ -857,83 +900,176 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
857 return IRQ_HANDLED; 900 return IRQ_HANDLED;
858} 901}
859 902
860static void hdmi_display_on(void *arg, struct fb_info *info) 903/* locking: called with info->lock held, or before register_framebuffer() */
904static void sh_hdmi_display_on(void *arg, struct fb_info *info)
861{ 905{
906 /*
907 * info is guaranteed to be valid, when we are called, because our
908 * FB_EVENT_FB_UNBIND notify is also called with info->lock held
909 */
862 struct sh_hdmi *hdmi = arg; 910 struct sh_hdmi *hdmi = arg;
863 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; 911 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
912 struct sh_mobile_lcdc_chan *ch = info->par;
864 913
865 if (info->var.xres != 1280 || info->var.yres != 720) { 914 dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__,
866 dev_warn(info->device, "Unsupported framebuffer geometry %ux%u\n", 915 pdata->lcd_dev, info->state);
867 info->var.xres, info->var.yres); 916
868 return; 917 /* No need to lock */
869 } 918 hdmi->info = info;
870 919
871 pr_debug("%s(%p): state %x\n", __func__, pdata->lcd_dev, info->state);
872 /* 920 /*
873 * FIXME: not a good place to store fb_info. And we cannot nullify it 921 * hp_state can be set to
874 * even on monitor disconnect. What should the lifecycle be? 922 * HDMI_HOTPLUG_DISCONNECTED: on monitor unplug
923 * HDMI_HOTPLUG_CONNECTED: on monitor plug-in
924 * HDMI_HOTPLUG_EDID_DONE: on EDID read completion
875 */ 925 */
876 hdmi->info = info;
877 switch (hdmi->hp_state) { 926 switch (hdmi->hp_state) {
878 case HDMI_HOTPLUG_EDID_DONE: 927 case HDMI_HOTPLUG_EDID_DONE:
879 /* PS mode d->e. All functions are active */ 928 /* PS mode d->e. All functions are active */
880 hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL); 929 hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL);
881 pr_debug("HDMI running\n"); 930 dev_dbg(hdmi->dev, "HDMI running\n");
882 break; 931 break;
883 case HDMI_HOTPLUG_DISCONNECTED: 932 case HDMI_HOTPLUG_DISCONNECTED:
884 info->state = FBINFO_STATE_SUSPENDED; 933 info->state = FBINFO_STATE_SUSPENDED;
885 default: 934 default:
886 hdmi->var = info->var; 935 hdmi->var = ch->display_var;
887 } 936 }
888} 937}
889 938
890static void hdmi_display_off(void *arg) 939/* locking: called with info->lock held */
940static void sh_hdmi_display_off(void *arg)
891{ 941{
892 struct sh_hdmi *hdmi = arg; 942 struct sh_hdmi *hdmi = arg;
893 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; 943 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
894 944
895 pr_debug("%s(%p)\n", __func__, pdata->lcd_dev); 945 dev_dbg(hdmi->dev, "%s(%p)\n", __func__, pdata->lcd_dev);
896 /* PS mode e->a */ 946 /* PS mode e->a */
897 hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL); 947 hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL);
898} 948}
899 949
950static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
951{
952 struct fb_info *info = hdmi->info;
953 struct sh_mobile_lcdc_chan *ch = info->par;
954 struct fb_var_screeninfo *new_var = &hdmi->var, *old_var = &ch->display_var;
955 struct fb_videomode mode1, mode2;
956
957 fb_var_to_videomode(&mode1, old_var);
958 fb_var_to_videomode(&mode2, new_var);
959
960 dev_dbg(info->dev, "Old %ux%u, new %ux%u\n",
961 mode1.xres, mode1.yres, mode2.xres, mode2.yres);
962
963 if (fb_mode_is_equal(&mode1, &mode2))
964 return false;
965
966 dev_dbg(info->dev, "Switching %u -> %u lines\n",
967 mode1.yres, mode2.yres);
968 *old_var = *new_var;
969
970 return true;
971}
972
973/**
974 * sh_hdmi_clk_configure() - set HDMI clock frequency and enable the clock
975 * @hdmi: driver context
976 * @pixclock: pixel clock period in picoseconds
977 * return: configured positive rate if successful
978 * 0 if couldn't set the rate, but managed to enable the clock
979 * negative error, if couldn't enable the clock
980 */
981static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long pixclock)
982{
983 long rate;
984 int ret;
985
986 rate = PICOS2KHZ(pixclock) * 1000;
987 rate = clk_round_rate(hdmi->hdmi_clk, rate);
988 if (rate > 0) {
989 ret = clk_set_rate(hdmi->hdmi_clk, rate);
990 if (ret < 0) {
991 dev_warn(hdmi->dev, "Cannot set rate %ld: %d\n", rate, ret);
992 rate = 0;
993 } else {
994 dev_dbg(hdmi->dev, "HDMI set frequency %lu\n", rate);
995 }
996 } else {
997 rate = 0;
998 dev_warn(hdmi->dev, "Cannot get suitable rate: %ld\n", rate);
999 }
1000
1001 ret = clk_enable(hdmi->hdmi_clk);
1002 if (ret < 0) {
1003 dev_err(hdmi->dev, "Cannot enable clock: %d\n", ret);
1004 return ret;
1005 }
1006
1007 return rate;
1008}
1009
900/* Hotplug interrupt occurred, read EDID */ 1010/* Hotplug interrupt occurred, read EDID */
901static void edid_work_fn(struct work_struct *work) 1011static void sh_hdmi_edid_work_fn(struct work_struct *work)
902{ 1012{
903 struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work); 1013 struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work);
904 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; 1014 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
1015 struct sh_mobile_lcdc_chan *ch;
1016 int ret;
905 1017
906 pr_debug("%s(%p): begin, hotplug status %d\n", __func__, 1018 dev_dbg(hdmi->dev, "%s(%p): begin, hotplug status %d\n", __func__,
907 pdata->lcd_dev, hdmi->hp_state); 1019 pdata->lcd_dev, hdmi->hp_state);
908 1020
909 if (!pdata->lcd_dev) 1021 if (!pdata->lcd_dev)
910 return; 1022 return;
911 1023
1024 mutex_lock(&hdmi->mutex);
1025
912 if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) { 1026 if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) {
913 pm_runtime_get_sync(hdmi->dev);
914 /* A device has been plugged in */ 1027 /* A device has been plugged in */
915 sh_hdmi_read_edid(hdmi); 1028 pm_runtime_get_sync(hdmi->dev);
1029
1030 ret = sh_hdmi_read_edid(hdmi);
1031 if (ret < 0)
1032 goto out;
1033
1034 /* Reconfigure the clock */
1035 clk_disable(hdmi->hdmi_clk);
1036 ret = sh_hdmi_clk_configure(hdmi, hdmi->var.pixclock);
1037 if (ret < 0)
1038 goto out;
1039
916 msleep(10); 1040 msleep(10);
917 sh_hdmi_configure(hdmi); 1041 sh_hdmi_configure(hdmi);
918 /* Switched to another (d) power-save mode */ 1042 /* Switched to another (d) power-save mode */
919 msleep(10); 1043 msleep(10);
920 1044
921 if (!hdmi->info) 1045 if (!hdmi->info)
922 return; 1046 goto out;
1047
1048 ch = hdmi->info->par;
923 1049
924 acquire_console_sem(); 1050 acquire_console_sem();
925 1051
926 /* HDMI plug in */ 1052 /* HDMI plug in */
927 hdmi->info->var = hdmi->var; 1053 if (!sh_hdmi_must_reconfigure(hdmi) &&
928 if (hdmi->info->state != FBINFO_STATE_RUNNING) 1054 hdmi->info->state == FBINFO_STATE_RUNNING) {
1055 /*
1056 * First activation with the default monitor - just turn
1057 * on, if we run a resume here, the logo disappears
1058 */
1059 if (lock_fb_info(hdmi->info)) {
1060 sh_hdmi_display_on(hdmi, hdmi->info);
1061 unlock_fb_info(hdmi->info);
1062 }
1063 } else {
1064 /* New monitor or have to wake up */
929 fb_set_suspend(hdmi->info, 0); 1065 fb_set_suspend(hdmi->info, 0);
930 else 1066 }
931 hdmi_display_on(hdmi, hdmi->info);
932 1067
933 release_console_sem(); 1068 release_console_sem();
934 } else { 1069 } else {
1070 ret = 0;
935 if (!hdmi->info) 1071 if (!hdmi->info)
936 return; 1072 goto out;
937 1073
938 acquire_console_sem(); 1074 acquire_console_sem();
939 1075
@@ -942,15 +1078,67 @@ static void edid_work_fn(struct work_struct *work)
942 1078
943 release_console_sem(); 1079 release_console_sem();
944 pm_runtime_put(hdmi->dev); 1080 pm_runtime_put(hdmi->dev);
1081 fb_destroy_modedb(hdmi->monspec.modedb);
945 } 1082 }
946 1083
947 pr_debug("%s(%p): end\n", __func__, pdata->lcd_dev); 1084out:
1085 if (ret < 0)
1086 hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED;
1087 mutex_unlock(&hdmi->mutex);
1088
1089 dev_dbg(hdmi->dev, "%s(%p): end\n", __func__, pdata->lcd_dev);
1090}
1091
1092static int sh_hdmi_notify(struct notifier_block *nb,
1093 unsigned long action, void *data);
1094
1095static struct notifier_block sh_hdmi_notifier = {
1096 .notifier_call = sh_hdmi_notify,
1097};
1098
1099static int sh_hdmi_notify(struct notifier_block *nb,
1100 unsigned long action, void *data)
1101{
1102 struct fb_event *event = data;
1103 struct fb_info *info = event->info;
1104 struct sh_mobile_lcdc_chan *ch = info->par;
1105 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
1106 struct sh_hdmi *hdmi = board_cfg->board_data;
1107
1108 if (nb != &sh_hdmi_notifier || !hdmi || hdmi->info != info)
1109 return NOTIFY_DONE;
1110
1111 switch(action) {
1112 case FB_EVENT_FB_REGISTERED:
1113 /* Unneeded, activation taken care by sh_hdmi_display_on() */
1114 break;
1115 case FB_EVENT_FB_UNREGISTERED:
1116 /*
1117 * We are called from unregister_framebuffer() with the
1118 * info->lock held. This is bad for us, because we can race with
1119 * the scheduled work, which has to call fb_set_suspend(), which
1120 * takes info->lock internally, so, sh_hdmi_edid_work_fn()
1121 * cannot take and hold info->lock for the whole function
1122 * duration. Using an additional lock creates a classical AB-BA
1123 * lock up. Therefore, we have to release the info->lock
1124 * temporarily, synchronise with the work queue and re-acquire
1125 * the info->lock.
1126 */
1127 unlock_fb_info(hdmi->info);
1128 mutex_lock(&hdmi->mutex);
1129 hdmi->info = NULL;
1130 mutex_unlock(&hdmi->mutex);
1131 lock_fb_info(hdmi->info);
1132 return NOTIFY_OK;
1133 }
1134 return NOTIFY_DONE;
948} 1135}
949 1136
950static int __init sh_hdmi_probe(struct platform_device *pdev) 1137static int __init sh_hdmi_probe(struct platform_device *pdev)
951{ 1138{
952 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data; 1139 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
953 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1140 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1141 struct sh_mobile_lcdc_board_cfg *board_cfg;
954 int irq = platform_get_irq(pdev, 0), ret; 1142 int irq = platform_get_irq(pdev, 0), ret;
955 struct sh_hdmi *hdmi; 1143 struct sh_hdmi *hdmi;
956 long rate; 1144 long rate;
@@ -964,10 +1152,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
964 return -ENOMEM; 1152 return -ENOMEM;
965 } 1153 }
966 1154
967 ret = snd_soc_register_codec(&pdev->dev, 1155 mutex_init(&hdmi->mutex);
968 &soc_codec_dev_sh_hdmi, &sh_hdmi_dai, 1);
969 if (ret < 0)
970 goto esndreg;
971 1156
972 hdmi->dev = &pdev->dev; 1157 hdmi->dev = &pdev->dev;
973 1158
@@ -978,30 +1163,14 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
978 goto egetclk; 1163 goto egetclk;
979 } 1164 }
980 1165
981 rate = PICOS2KHZ(pdata->lcd_chan->lcd_cfg.pixclock) * 1000; 1166 /* Some arbitrary relaxed pixclock just to get things started */
982 1167 rate = sh_hdmi_clk_configure(hdmi, 37037);
983 rate = clk_round_rate(hdmi->hdmi_clk, rate);
984 if (rate < 0) { 1168 if (rate < 0) {
985 ret = rate; 1169 ret = rate;
986 dev_err(&pdev->dev, "Cannot get suitable rate: %ld\n", rate);
987 goto erate; 1170 goto erate;
988 } 1171 }
989 1172
990 ret = clk_set_rate(hdmi->hdmi_clk, rate); 1173 dev_dbg(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate);
991 if (ret < 0) {
992 dev_err(&pdev->dev, "Cannot set rate %ld: %d\n", rate, ret);
993 goto erate;
994 }
995
996 pr_debug("HDMI set frequency %lu\n", rate);
997
998 ret = clk_enable(hdmi->hdmi_clk);
999 if (ret < 0) {
1000 dev_err(&pdev->dev, "Cannot enable clock: %d\n", ret);
1001 goto eclkenable;
1002 }
1003
1004 dev_info(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate);
1005 1174
1006 if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) { 1175 if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) {
1007 dev_err(&pdev->dev, "HDMI register region already claimed\n"); 1176 dev_err(&pdev->dev, "HDMI register region already claimed\n");
@@ -1018,18 +1187,18 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
1018 1187
1019 platform_set_drvdata(pdev, hdmi); 1188 platform_set_drvdata(pdev, hdmi);
1020 1189
1021#if 1
1022 /* Product and revision IDs are 0 in sh-mobile version */ 1190 /* Product and revision IDs are 0 in sh-mobile version */
1023 dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n", 1191 dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n",
1024 hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID)); 1192 hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID));
1025#endif
1026 1193
1027 /* Set up LCDC callbacks */ 1194 /* Set up LCDC callbacks */
1028 pdata->lcd_chan->board_cfg.board_data = hdmi; 1195 board_cfg = &pdata->lcd_chan->board_cfg;
1029 pdata->lcd_chan->board_cfg.display_on = hdmi_display_on; 1196 board_cfg->owner = THIS_MODULE;
1030 pdata->lcd_chan->board_cfg.display_off = hdmi_display_off; 1197 board_cfg->board_data = hdmi;
1198 board_cfg->display_on = sh_hdmi_display_on;
1199 board_cfg->display_off = sh_hdmi_display_off;
1031 1200
1032 INIT_DELAYED_WORK(&hdmi->edid_work, edid_work_fn); 1201 INIT_DELAYED_WORK(&hdmi->edid_work, sh_hdmi_edid_work_fn);
1033 1202
1034 pm_runtime_enable(&pdev->dev); 1203 pm_runtime_enable(&pdev->dev);
1035 pm_runtime_resume(&pdev->dev); 1204 pm_runtime_resume(&pdev->dev);
@@ -1041,8 +1210,17 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
1041 goto ereqirq; 1210 goto ereqirq;
1042 } 1211 }
1043 1212
1213 ret = snd_soc_register_codec(&pdev->dev,
1214 &soc_codec_dev_sh_hdmi, &sh_hdmi_dai, 1);
1215 if (ret < 0) {
1216 dev_err(&pdev->dev, "codec registration failed\n");
1217 goto ecodec;
1218 }
1219
1044 return 0; 1220 return 0;
1045 1221
1222ecodec:
1223 free_irq(irq, hdmi);
1046ereqirq: 1224ereqirq:
1047 pm_runtime_disable(&pdev->dev); 1225 pm_runtime_disable(&pdev->dev);
1048 iounmap(hdmi->base); 1226 iounmap(hdmi->base);
@@ -1050,12 +1228,10 @@ emap:
1050 release_mem_region(res->start, resource_size(res)); 1228 release_mem_region(res->start, resource_size(res));
1051ereqreg: 1229ereqreg:
1052 clk_disable(hdmi->hdmi_clk); 1230 clk_disable(hdmi->hdmi_clk);
1053eclkenable:
1054erate: 1231erate:
1055 clk_put(hdmi->hdmi_clk); 1232 clk_put(hdmi->hdmi_clk);
1056egetclk: 1233egetclk:
1057 snd_soc_unregister_codec(&pdev->dev); 1234 mutex_destroy(&hdmi->mutex);
1058esndreg:
1059 kfree(hdmi); 1235 kfree(hdmi);
1060 1236
1061 return ret; 1237 return ret;
@@ -1066,21 +1242,26 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
1066 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data; 1242 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
1067 struct sh_hdmi *hdmi = platform_get_drvdata(pdev); 1243 struct sh_hdmi *hdmi = platform_get_drvdata(pdev);
1068 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1244 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1245 struct sh_mobile_lcdc_board_cfg *board_cfg = &pdata->lcd_chan->board_cfg;
1069 int irq = platform_get_irq(pdev, 0); 1246 int irq = platform_get_irq(pdev, 0);
1070 1247
1071 snd_soc_unregister_codec(&pdev->dev); 1248 snd_soc_unregister_codec(&pdev->dev);
1072 1249
1073 pdata->lcd_chan->board_cfg.display_on = NULL; 1250 board_cfg->display_on = NULL;
1074 pdata->lcd_chan->board_cfg.display_off = NULL; 1251 board_cfg->display_off = NULL;
1075 pdata->lcd_chan->board_cfg.board_data = NULL; 1252 board_cfg->board_data = NULL;
1253 board_cfg->owner = NULL;
1076 1254
1255 /* No new work will be scheduled, wait for running ISR */
1077 free_irq(irq, hdmi); 1256 free_irq(irq, hdmi);
1078 pm_runtime_disable(&pdev->dev); 1257 /* Wait for already scheduled work */
1079 cancel_delayed_work_sync(&hdmi->edid_work); 1258 cancel_delayed_work_sync(&hdmi->edid_work);
1259 pm_runtime_disable(&pdev->dev);
1080 clk_disable(hdmi->hdmi_clk); 1260 clk_disable(hdmi->hdmi_clk);
1081 clk_put(hdmi->hdmi_clk); 1261 clk_put(hdmi->hdmi_clk);
1082 iounmap(hdmi->base); 1262 iounmap(hdmi->base);
1083 release_mem_region(res->start, resource_size(res)); 1263 release_mem_region(res->start, resource_size(res));
1264 mutex_destroy(&hdmi->mutex);
1084 kfree(hdmi); 1265 kfree(hdmi);
1085 1266
1086 return 0; 1267 return 0;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 7a1419279c8f..50963739a409 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -12,7 +12,6 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/fb.h>
16#include <linux/clk.h> 15#include <linux/clk.h>
17#include <linux/pm_runtime.h> 16#include <linux/pm_runtime.h>
18#include <linux/platform_device.h> 17#include <linux/platform_device.h>
@@ -21,10 +20,12 @@
21#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
22#include <linux/ioctl.h> 21#include <linux/ioctl.h>
23#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/console.h>
24#include <video/sh_mobile_lcdc.h> 24#include <video/sh_mobile_lcdc.h>
25#include <asm/atomic.h> 25#include <asm/atomic.h>
26 26
27#define PALETTE_NR 16 27#include "sh_mobile_lcdcfb.h"
28
28#define SIDE_B_OFFSET 0x1000 29#define SIDE_B_OFFSET 0x1000
29#define MIRROR_OFFSET 0x2000 30#define MIRROR_OFFSET 0x2000
30 31
@@ -53,11 +54,8 @@ static int lcdc_shared_regs[] = {
53}; 54};
54#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs) 55#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
55 56
56/* per-channel registers */ 57#define DEFAULT_XRES 1280
57enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, 58#define DEFAULT_YRES 1024
58 LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
59 LDHAJR,
60 NR_CH_REGS };
61 59
62static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { 60static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
63 [LDDCKPAT1R] = 0x400, 61 [LDDCKPAT1R] = 0x400,
@@ -112,23 +110,21 @@ static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
112#define LDRCNTR_MRC 0x00000001 110#define LDRCNTR_MRC 0x00000001
113#define LDSR_MRS 0x00000100 111#define LDSR_MRS 0x00000100
114 112
115struct sh_mobile_lcdc_priv; 113static const struct fb_videomode default_720p = {
116struct sh_mobile_lcdc_chan { 114 .name = "HDMI 720p",
117 struct sh_mobile_lcdc_priv *lcdc; 115 .xres = 1280,
118 unsigned long *reg_offs; 116 .yres = 720,
119 unsigned long ldmt1r_value; 117
120 unsigned long enabled; /* ME and SE in LDCNT2R */ 118 .left_margin = 200,
121 struct sh_mobile_lcdc_chan_cfg cfg; 119 .right_margin = 88,
122 u32 pseudo_palette[PALETTE_NR]; 120 .hsync_len = 48,
123 unsigned long saved_ch_regs[NR_CH_REGS]; 121
124 struct fb_info *info; 122 .upper_margin = 20,
125 dma_addr_t dma_handle; 123 .lower_margin = 5,
126 struct fb_deferred_io defio; 124 .vsync_len = 5,
127 struct scatterlist *sglist; 125
128 unsigned long frame_end; 126 .pixclock = 13468,
129 unsigned long pan_offset; 127 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
130 wait_queue_head_t frame_end_wait;
131 struct completion vsync_completion;
132}; 128};
133 129
134struct sh_mobile_lcdc_priv { 130struct sh_mobile_lcdc_priv {
@@ -409,8 +405,8 @@ static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
409 405
410static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) 406static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
411{ 407{
412 struct fb_var_screeninfo *var = &ch->info->var; 408 struct fb_var_screeninfo *var = &ch->info->var, *display_var = &ch->display_var;
413 unsigned long h_total, hsync_pos; 409 unsigned long h_total, hsync_pos, display_h_total;
414 u32 tmp; 410 u32 tmp;
415 411
416 tmp = ch->ldmt1r_value; 412 tmp = ch->ldmt1r_value;
@@ -428,31 +424,33 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
428 lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r); 424 lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r);
429 425
430 /* horizontal configuration */ 426 /* horizontal configuration */
431 h_total = var->xres + var->hsync_len + 427 h_total = display_var->xres + display_var->hsync_len +
432 var->left_margin + var->right_margin; 428 display_var->left_margin + display_var->right_margin;
433 tmp = h_total / 8; /* HTCN */ 429 tmp = h_total / 8; /* HTCN */
434 tmp |= (var->xres / 8) << 16; /* HDCN */ 430 tmp |= (min(display_var->xres, var->xres) / 8) << 16; /* HDCN */
435 lcdc_write_chan(ch, LDHCNR, tmp); 431 lcdc_write_chan(ch, LDHCNR, tmp);
436 432
437 hsync_pos = var->xres + var->right_margin; 433 hsync_pos = display_var->xres + display_var->right_margin;
438 tmp = hsync_pos / 8; /* HSYNP */ 434 tmp = hsync_pos / 8; /* HSYNP */
439 tmp |= (var->hsync_len / 8) << 16; /* HSYNW */ 435 tmp |= (display_var->hsync_len / 8) << 16; /* HSYNW */
440 lcdc_write_chan(ch, LDHSYNR, tmp); 436 lcdc_write_chan(ch, LDHSYNR, tmp);
441 437
442 /* vertical configuration */ 438 /* vertical configuration */
443 tmp = var->yres + var->vsync_len + 439 tmp = display_var->yres + display_var->vsync_len +
444 var->upper_margin + var->lower_margin; /* VTLN */ 440 display_var->upper_margin + display_var->lower_margin; /* VTLN */
445 tmp |= var->yres << 16; /* VDLN */ 441 tmp |= min(display_var->yres, var->yres) << 16; /* VDLN */
446 lcdc_write_chan(ch, LDVLNR, tmp); 442 lcdc_write_chan(ch, LDVLNR, tmp);
447 443
448 tmp = var->yres + var->lower_margin; /* VSYNP */ 444 tmp = display_var->yres + display_var->lower_margin; /* VSYNP */
449 tmp |= var->vsync_len << 16; /* VSYNW */ 445 tmp |= display_var->vsync_len << 16; /* VSYNW */
450 lcdc_write_chan(ch, LDVSYNR, tmp); 446 lcdc_write_chan(ch, LDVSYNR, tmp);
451 447
452 /* Adjust horizontal synchronisation for HDMI */ 448 /* Adjust horizontal synchronisation for HDMI */
453 tmp = ((var->xres & 7) << 24) | 449 display_h_total = display_var->xres + display_var->hsync_len +
454 ((h_total & 7) << 16) | 450 display_var->left_margin + display_var->right_margin;
455 ((var->hsync_len & 7) << 8) | 451 tmp = ((display_var->xres & 7) << 24) |
452 ((display_h_total & 7) << 16) |
453 ((display_var->hsync_len & 7) << 8) |
456 hsync_pos; 454 hsync_pos;
457 lcdc_write_chan(ch, LDHAJR, tmp); 455 lcdc_write_chan(ch, LDHAJR, tmp);
458} 456}
@@ -460,7 +458,6 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
460static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) 458static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
461{ 459{
462 struct sh_mobile_lcdc_chan *ch; 460 struct sh_mobile_lcdc_chan *ch;
463 struct fb_videomode *lcd_cfg;
464 struct sh_mobile_lcdc_board_cfg *board_cfg; 461 struct sh_mobile_lcdc_board_cfg *board_cfg;
465 unsigned long tmp; 462 unsigned long tmp;
466 int k, m; 463 int k, m;
@@ -503,7 +500,8 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
503 m = 1 << 6; 500 m = 1 << 6;
504 tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0); 501 tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0);
505 502
506 lcdc_write_chan(ch, LDDCKPAT1R, 0x00000000); 503 /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider denominator */
504 lcdc_write_chan(ch, LDDCKPAT1R, 0);
507 lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1); 505 lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1);
508 } 506 }
509 507
@@ -518,7 +516,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
518 516
519 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 517 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
520 ch = &priv->ch[k]; 518 ch = &priv->ch[k];
521 lcd_cfg = &ch->cfg.lcd_cfg;
522 519
523 if (!ch->enabled) 520 if (!ch->enabled)
524 continue; 521 continue;
@@ -547,7 +544,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
547 544
548 /* set bpp format in PKF[4:0] */ 545 /* set bpp format in PKF[4:0] */
549 tmp = lcdc_read_chan(ch, LDDFR); 546 tmp = lcdc_read_chan(ch, LDDFR);
550 tmp &= ~(0x0001001f); 547 tmp &= ~0x0001001f;
551 tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0; 548 tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0;
552 lcdc_write_chan(ch, LDDFR, tmp); 549 lcdc_write_chan(ch, LDDFR, tmp);
553 550
@@ -591,8 +588,10 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
591 continue; 588 continue;
592 589
593 board_cfg = &ch->cfg.board_cfg; 590 board_cfg = &ch->cfg.board_cfg;
594 if (board_cfg->display_on) 591 if (try_module_get(board_cfg->owner) && board_cfg->display_on) {
595 board_cfg->display_on(board_cfg->board_data, ch->info); 592 board_cfg->display_on(board_cfg->board_data, ch->info);
593 module_put(board_cfg->owner);
594 }
596 } 595 }
597 596
598 return 0; 597 return 0;
@@ -614,7 +613,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
614 * flush frame, and wait for frame end interrupt 613 * flush frame, and wait for frame end interrupt
615 * clean up deferred io and enable clock 614 * clean up deferred io and enable clock
616 */ 615 */
617 if (ch->info->fbdefio) { 616 if (ch->info && ch->info->fbdefio) {
618 ch->frame_end = 0; 617 ch->frame_end = 0;
619 schedule_delayed_work(&ch->info->deferred_work, 0); 618 schedule_delayed_work(&ch->info->deferred_work, 0);
620 wait_event(ch->frame_end_wait, ch->frame_end); 619 wait_event(ch->frame_end_wait, ch->frame_end);
@@ -624,8 +623,10 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
624 } 623 }
625 624
626 board_cfg = &ch->cfg.board_cfg; 625 board_cfg = &ch->cfg.board_cfg;
627 if (board_cfg->display_off) 626 if (try_module_get(board_cfg->owner) && board_cfg->display_off) {
628 board_cfg->display_off(board_cfg->board_data); 627 board_cfg->display_off(board_cfg->board_data);
628 module_put(board_cfg->owner);
629 }
629 } 630 }
630 631
631 /* stop the lcdc */ 632 /* stop the lcdc */
@@ -704,7 +705,6 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
704 return PTR_ERR(priv->dot_clk); 705 return PTR_ERR(priv->dot_clk);
705 } 706 }
706 } 707 }
707 atomic_set(&priv->hw_usecnt, -1);
708 708
709 /* Runtime PM support involves two step for this driver: 709 /* Runtime PM support involves two step for this driver:
710 * 1) Enable Runtime PM 710 * 1) Enable Runtime PM
@@ -837,6 +837,102 @@ static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd,
837 return retval; 837 return retval;
838} 838}
839 839
840static void sh_mobile_fb_reconfig(struct fb_info *info)
841{
842 struct sh_mobile_lcdc_chan *ch = info->par;
843 struct fb_videomode mode1, mode2;
844 struct fb_event event;
845 int evnt = FB_EVENT_MODE_CHANGE_ALL;
846
847 if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par))
848 /* More framebuffer users are active */
849 return;
850
851 fb_var_to_videomode(&mode1, &ch->display_var);
852 fb_var_to_videomode(&mode2, &info->var);
853
854 if (fb_mode_is_equal(&mode1, &mode2))
855 return;
856
857 /* Display has been re-plugged, framebuffer is free now, reconfigure */
858 if (fb_set_var(info, &ch->display_var) < 0)
859 /* Couldn't reconfigure, hopefully, can continue as before */
860 return;
861
862 info->fix.line_length = mode2.xres * (ch->cfg.bpp / 8);
863
864 /*
865 * fb_set_var() calls the notifier change internally, only if
866 * FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a
867 * user event, we have to call the chain ourselves.
868 */
869 event.info = info;
870 event.data = &mode2;
871 fb_notifier_call_chain(evnt, &event);
872}
873
874/*
875 * Locking: both .fb_release() and .fb_open() are called with info->lock held if
876 * user == 1, or with console sem held, if user == 0.
877 */
878static int sh_mobile_release(struct fb_info *info, int user)
879{
880 struct sh_mobile_lcdc_chan *ch = info->par;
881
882 mutex_lock(&ch->open_lock);
883 dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count);
884
885 ch->use_count--;
886
887 /* Nothing to reconfigure, when called from fbcon */
888 if (user) {
889 acquire_console_sem();
890 sh_mobile_fb_reconfig(info);
891 release_console_sem();
892 }
893
894 mutex_unlock(&ch->open_lock);
895
896 return 0;
897}
898
899static int sh_mobile_open(struct fb_info *info, int user)
900{
901 struct sh_mobile_lcdc_chan *ch = info->par;
902
903 mutex_lock(&ch->open_lock);
904 ch->use_count++;
905
906 dev_dbg(info->dev, "%s(): %d users\n", __func__, ch->use_count);
907 mutex_unlock(&ch->open_lock);
908
909 return 0;
910}
911
912static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
913{
914 struct sh_mobile_lcdc_chan *ch = info->par;
915
916 if (var->xres < 160 || var->xres > 1920 ||
917 var->yres < 120 || var->yres > 1080 ||
918 var->left_margin < 32 || var->left_margin > 320 ||
919 var->right_margin < 12 || var->right_margin > 240 ||
920 var->upper_margin < 12 || var->upper_margin > 120 ||
921 var->lower_margin < 1 || var->lower_margin > 64 ||
922 var->hsync_len < 32 || var->hsync_len > 240 ||
923 var->vsync_len < 2 || var->vsync_len > 64 ||
924 var->pixclock < 6000 || var->pixclock > 40000 ||
925 var->xres * var->yres * (ch->cfg.bpp / 8) * 2 > info->fix.smem_len) {
926 dev_warn(info->dev, "Invalid info: %u %u %u %u %u %u %u %u %u!\n",
927 var->xres, var->yres,
928 var->left_margin, var->right_margin,
929 var->upper_margin, var->lower_margin,
930 var->hsync_len, var->vsync_len,
931 var->pixclock);
932 return -EINVAL;
933 }
934 return 0;
935}
840 936
841static struct fb_ops sh_mobile_lcdc_ops = { 937static struct fb_ops sh_mobile_lcdc_ops = {
842 .owner = THIS_MODULE, 938 .owner = THIS_MODULE,
@@ -848,6 +944,9 @@ static struct fb_ops sh_mobile_lcdc_ops = {
848 .fb_imageblit = sh_mobile_lcdc_imageblit, 944 .fb_imageblit = sh_mobile_lcdc_imageblit,
849 .fb_pan_display = sh_mobile_fb_pan_display, 945 .fb_pan_display = sh_mobile_fb_pan_display,
850 .fb_ioctl = sh_mobile_ioctl, 946 .fb_ioctl = sh_mobile_ioctl,
947 .fb_open = sh_mobile_open,
948 .fb_release = sh_mobile_release,
949 .fb_check_var = sh_mobile_check_var,
851}; 950};
852 951
853static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) 952static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
@@ -958,6 +1057,7 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
958 .runtime_resume = sh_mobile_lcdc_runtime_resume, 1057 .runtime_resume = sh_mobile_lcdc_runtime_resume,
959}; 1058};
960 1059
1060/* locking: called with info->lock held */
961static int sh_mobile_lcdc_notify(struct notifier_block *nb, 1061static int sh_mobile_lcdc_notify(struct notifier_block *nb,
962 unsigned long action, void *data) 1062 unsigned long action, void *data)
963{ 1063{
@@ -965,53 +1065,40 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
965 struct fb_info *info = event->info; 1065 struct fb_info *info = event->info;
966 struct sh_mobile_lcdc_chan *ch = info->par; 1066 struct sh_mobile_lcdc_chan *ch = info->par;
967 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg; 1067 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
968 struct fb_var_screeninfo *var; 1068 int ret;
969 1069
970 if (&ch->lcdc->notifier != nb) 1070 if (&ch->lcdc->notifier != nb)
971 return 0; 1071 return NOTIFY_DONE;
972 1072
973 dev_dbg(info->dev, "%s(): action = %lu, data = %p\n", 1073 dev_dbg(info->dev, "%s(): action = %lu, data = %p\n",
974 __func__, action, event->data); 1074 __func__, action, event->data);
975 1075
976 switch(action) { 1076 switch(action) {
977 case FB_EVENT_SUSPEND: 1077 case FB_EVENT_SUSPEND:
978 if (board_cfg->display_off) 1078 if (try_module_get(board_cfg->owner) && board_cfg->display_off) {
979 board_cfg->display_off(board_cfg->board_data); 1079 board_cfg->display_off(board_cfg->board_data);
1080 module_put(board_cfg->owner);
1081 }
980 pm_runtime_put(info->device); 1082 pm_runtime_put(info->device);
1083 sh_mobile_lcdc_stop(ch->lcdc);
981 break; 1084 break;
982 case FB_EVENT_RESUME: 1085 case FB_EVENT_RESUME:
983 var = &info->var; 1086 mutex_lock(&ch->open_lock);
1087 sh_mobile_fb_reconfig(info);
1088 mutex_unlock(&ch->open_lock);
984 1089
985 /* HDMI must be enabled before LCDC configuration */ 1090 /* HDMI must be enabled before LCDC configuration */
986 if (board_cfg->display_on) 1091 if (try_module_get(board_cfg->owner) && board_cfg->display_on) {
987 board_cfg->display_on(board_cfg->board_data, ch->info); 1092 board_cfg->display_on(board_cfg->board_data, info);
988 1093 module_put(board_cfg->owner);
989 /* Check if the new display is not in our modelist */
990 if (ch->info->modelist.next &&
991 !fb_match_mode(var, &ch->info->modelist)) {
992 struct fb_videomode mode;
993 int ret;
994
995 /* Can we handle this display? */
996 if (var->xres > ch->cfg.lcd_cfg.xres ||
997 var->yres > ch->cfg.lcd_cfg.yres)
998 return -ENOMEM;
999
1000 /* Add to the modelist */
1001 fb_var_to_videomode(&mode, var);
1002 ret = fb_add_videomode(&mode, &ch->info->modelist);
1003 if (ret < 0)
1004 return ret;
1005 } 1094 }
1006 1095
1007 pm_runtime_get_sync(info->device); 1096 ret = sh_mobile_lcdc_start(ch->lcdc);
1008 1097 if (!ret)
1009 sh_mobile_lcdc_geometry(ch); 1098 pm_runtime_get_sync(info->device);
1010
1011 break;
1012 } 1099 }
1013 1100
1014 return 0; 1101 return NOTIFY_OK;
1015} 1102}
1016 1103
1017static int sh_mobile_lcdc_remove(struct platform_device *pdev); 1104static int sh_mobile_lcdc_remove(struct platform_device *pdev);
@@ -1020,14 +1107,13 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1020{ 1107{
1021 struct fb_info *info; 1108 struct fb_info *info;
1022 struct sh_mobile_lcdc_priv *priv; 1109 struct sh_mobile_lcdc_priv *priv;
1023 struct sh_mobile_lcdc_info *pdata; 1110 struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data;
1024 struct sh_mobile_lcdc_chan_cfg *cfg;
1025 struct resource *res; 1111 struct resource *res;
1026 int error; 1112 int error;
1027 void *buf; 1113 void *buf;
1028 int i, j; 1114 int i, j;
1029 1115
1030 if (!pdev->dev.platform_data) { 1116 if (!pdata) {
1031 dev_err(&pdev->dev, "no platform data defined\n"); 1117 dev_err(&pdev->dev, "no platform data defined\n");
1032 return -EINVAL; 1118 return -EINVAL;
1033 } 1119 }
@@ -1055,31 +1141,33 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1055 } 1141 }
1056 1142
1057 priv->irq = i; 1143 priv->irq = i;
1058 pdata = pdev->dev.platform_data; 1144 atomic_set(&priv->hw_usecnt, -1);
1059 1145
1060 j = 0; 1146 j = 0;
1061 for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) { 1147 for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) {
1062 priv->ch[j].lcdc = priv; 1148 struct sh_mobile_lcdc_chan *ch = priv->ch + j;
1063 memcpy(&priv->ch[j].cfg, &pdata->ch[i], sizeof(pdata->ch[i])); 1149
1150 ch->lcdc = priv;
1151 memcpy(&ch->cfg, &pdata->ch[i], sizeof(pdata->ch[i]));
1064 1152
1065 error = sh_mobile_lcdc_check_interface(&priv->ch[j]); 1153 error = sh_mobile_lcdc_check_interface(ch);
1066 if (error) { 1154 if (error) {
1067 dev_err(&pdev->dev, "unsupported interface type\n"); 1155 dev_err(&pdev->dev, "unsupported interface type\n");
1068 goto err1; 1156 goto err1;
1069 } 1157 }
1070 init_waitqueue_head(&priv->ch[j].frame_end_wait); 1158 init_waitqueue_head(&ch->frame_end_wait);
1071 init_completion(&priv->ch[j].vsync_completion); 1159 init_completion(&ch->vsync_completion);
1072 priv->ch[j].pan_offset = 0; 1160 ch->pan_offset = 0;
1073 1161
1074 switch (pdata->ch[i].chan) { 1162 switch (pdata->ch[i].chan) {
1075 case LCDC_CHAN_MAINLCD: 1163 case LCDC_CHAN_MAINLCD:
1076 priv->ch[j].enabled = 1 << 1; 1164 ch->enabled = 1 << 1;
1077 priv->ch[j].reg_offs = lcdc_offs_mainlcd; 1165 ch->reg_offs = lcdc_offs_mainlcd;
1078 j++; 1166 j++;
1079 break; 1167 break;
1080 case LCDC_CHAN_SUBLCD: 1168 case LCDC_CHAN_SUBLCD:
1081 priv->ch[j].enabled = 1 << 2; 1169 ch->enabled = 1 << 2;
1082 priv->ch[j].reg_offs = lcdc_offs_sublcd; 1170 ch->reg_offs = lcdc_offs_sublcd;
1083 j++; 1171 j++;
1084 break; 1172 break;
1085 } 1173 }
@@ -1103,69 +1191,83 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1103 1191
1104 for (i = 0; i < j; i++) { 1192 for (i = 0; i < j; i++) {
1105 struct fb_var_screeninfo *var; 1193 struct fb_var_screeninfo *var;
1106 struct fb_videomode *lcd_cfg; 1194 const struct fb_videomode *lcd_cfg, *max_cfg = NULL;
1107 cfg = &priv->ch[i].cfg; 1195 struct sh_mobile_lcdc_chan *ch = priv->ch + i;
1196 struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg;
1197 const struct fb_videomode *mode = cfg->lcd_cfg;
1198 unsigned long max_size = 0;
1199 int k;
1108 1200
1109 priv->ch[i].info = framebuffer_alloc(0, &pdev->dev); 1201 ch->info = framebuffer_alloc(0, &pdev->dev);
1110 if (!priv->ch[i].info) { 1202 if (!ch->info) {
1111 dev_err(&pdev->dev, "unable to allocate fb_info\n"); 1203 dev_err(&pdev->dev, "unable to allocate fb_info\n");
1112 error = -ENOMEM; 1204 error = -ENOMEM;
1113 break; 1205 break;
1114 } 1206 }
1115 1207
1116 info = priv->ch[i].info; 1208 info = ch->info;
1117 var = &info->var; 1209 var = &info->var;
1118 lcd_cfg = &cfg->lcd_cfg;
1119 info->fbops = &sh_mobile_lcdc_ops; 1210 info->fbops = &sh_mobile_lcdc_ops;
1120 var->xres = var->xres_virtual = lcd_cfg->xres; 1211 info->par = ch;
1121 var->yres = lcd_cfg->yres; 1212
1213 mutex_init(&ch->open_lock);
1214
1215 for (k = 0, lcd_cfg = mode;
1216 k < cfg->num_cfg && lcd_cfg;
1217 k++, lcd_cfg++) {
1218 unsigned long size = lcd_cfg->yres * lcd_cfg->xres;
1219
1220 if (size > max_size) {
1221 max_cfg = lcd_cfg;
1222 max_size = size;
1223 }
1224 }
1225
1226 if (!mode)
1227 max_size = DEFAULT_XRES * DEFAULT_YRES;
1228 else if (max_cfg)
1229 dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n",
1230 max_cfg->xres, max_cfg->yres);
1231
1232 info->fix = sh_mobile_lcdc_fix;
1233 info->fix.smem_len = max_size * (cfg->bpp / 8) * 2;
1234
1235 if (!mode)
1236 mode = &default_720p;
1237
1238 fb_videomode_to_var(var, mode);
1122 /* Default Y virtual resolution is 2x panel size */ 1239 /* Default Y virtual resolution is 2x panel size */
1123 var->yres_virtual = var->yres * 2; 1240 var->yres_virtual = var->yres * 2;
1124 var->width = cfg->lcd_size_cfg.width;
1125 var->height = cfg->lcd_size_cfg.height;
1126 var->activate = FB_ACTIVATE_NOW; 1241 var->activate = FB_ACTIVATE_NOW;
1127 var->left_margin = lcd_cfg->left_margin;
1128 var->right_margin = lcd_cfg->right_margin;
1129 var->upper_margin = lcd_cfg->upper_margin;
1130 var->lower_margin = lcd_cfg->lower_margin;
1131 var->hsync_len = lcd_cfg->hsync_len;
1132 var->vsync_len = lcd_cfg->vsync_len;
1133 var->sync = lcd_cfg->sync;
1134 var->pixclock = lcd_cfg->pixclock;
1135 1242
1136 error = sh_mobile_lcdc_set_bpp(var, cfg->bpp); 1243 error = sh_mobile_lcdc_set_bpp(var, cfg->bpp);
1137 if (error) 1244 if (error)
1138 break; 1245 break;
1139 1246
1140 info->fix = sh_mobile_lcdc_fix;
1141 info->fix.line_length = lcd_cfg->xres * (cfg->bpp / 8);
1142 info->fix.smem_len = info->fix.line_length *
1143 var->yres_virtual;
1144
1145 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len, 1247 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
1146 &priv->ch[i].dma_handle, GFP_KERNEL); 1248 &ch->dma_handle, GFP_KERNEL);
1147 if (!buf) { 1249 if (!buf) {
1148 dev_err(&pdev->dev, "unable to allocate buffer\n"); 1250 dev_err(&pdev->dev, "unable to allocate buffer\n");
1149 error = -ENOMEM; 1251 error = -ENOMEM;
1150 break; 1252 break;
1151 } 1253 }
1152 1254
1153 info->pseudo_palette = &priv->ch[i].pseudo_palette; 1255 info->pseudo_palette = &ch->pseudo_palette;
1154 info->flags = FBINFO_FLAG_DEFAULT; 1256 info->flags = FBINFO_FLAG_DEFAULT;
1155 1257
1156 error = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0); 1258 error = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
1157 if (error < 0) { 1259 if (error < 0) {
1158 dev_err(&pdev->dev, "unable to allocate cmap\n"); 1260 dev_err(&pdev->dev, "unable to allocate cmap\n");
1159 dma_free_coherent(&pdev->dev, info->fix.smem_len, 1261 dma_free_coherent(&pdev->dev, info->fix.smem_len,
1160 buf, priv->ch[i].dma_handle); 1262 buf, ch->dma_handle);
1161 break; 1263 break;
1162 } 1264 }
1163 1265
1164 memset(buf, 0, info->fix.smem_len); 1266 info->fix.smem_start = ch->dma_handle;
1165 info->fix.smem_start = priv->ch[i].dma_handle; 1267 info->fix.line_length = var->xres * (cfg->bpp / 8);
1166 info->screen_base = buf; 1268 info->screen_base = buf;
1167 info->device = &pdev->dev; 1269 info->device = &pdev->dev;
1168 info->par = &priv->ch[i]; 1270 ch->display_var = *var;
1169 } 1271 }
1170 1272
1171 if (error) 1273 if (error)
@@ -1179,6 +1281,10 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1179 1281
1180 for (i = 0; i < j; i++) { 1282 for (i = 0; i < j; i++) {
1181 struct sh_mobile_lcdc_chan *ch = priv->ch + i; 1283 struct sh_mobile_lcdc_chan *ch = priv->ch + i;
1284 const struct fb_videomode *mode = ch->cfg.lcd_cfg;
1285
1286 if (!mode)
1287 mode = &default_720p;
1182 1288
1183 info = ch->info; 1289 info = ch->info;
1184 1290
@@ -1191,6 +1297,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1191 } 1297 }
1192 } 1298 }
1193 1299
1300 fb_videomode_to_modelist(mode, ch->cfg.num_cfg, &info->modelist);
1194 error = register_framebuffer(info); 1301 error = register_framebuffer(info);
1195 if (error < 0) 1302 if (error < 0)
1196 goto err1; 1303 goto err1;
@@ -1200,8 +1307,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1200 pdev->name, 1307 pdev->name,
1201 (ch->cfg.chan == LCDC_CHAN_MAINLCD) ? 1308 (ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
1202 "mainlcd" : "sublcd", 1309 "mainlcd" : "sublcd",
1203 (int) ch->cfg.lcd_cfg.xres, 1310 info->var.xres, info->var.yres,
1204 (int) ch->cfg.lcd_cfg.yres,
1205 ch->cfg.bpp); 1311 ch->cfg.bpp);
1206 1312
1207 /* deferred io mode: disable clock to save power */ 1313 /* deferred io mode: disable clock to save power */
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
new file mode 100644
index 000000000000..9ecee2fba1d7
--- /dev/null
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -0,0 +1,41 @@
1#ifndef SH_MOBILE_LCDCFB_H
2#define SH_MOBILE_LCDCFB_H
3
4#include <linux/completion.h>
5#include <linux/fb.h>
6#include <linux/mutex.h>
7#include <linux/wait.h>
8
9/* per-channel registers */
10enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
11 LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
12 LDHAJR,
13 NR_CH_REGS };
14
15#define PALETTE_NR 16
16
17struct sh_mobile_lcdc_priv;
18struct fb_info;
19
20struct sh_mobile_lcdc_chan {
21 struct sh_mobile_lcdc_priv *lcdc;
22 unsigned long *reg_offs;
23 unsigned long ldmt1r_value;
24 unsigned long enabled; /* ME and SE in LDCNT2R */
25 struct sh_mobile_lcdc_chan_cfg cfg;
26 u32 pseudo_palette[PALETTE_NR];
27 unsigned long saved_ch_regs[NR_CH_REGS];
28 struct fb_info *info;
29 dma_addr_t dma_handle;
30 struct fb_deferred_io defio;
31 struct scatterlist *sglist;
32 unsigned long frame_end;
33 unsigned long pan_offset;
34 wait_queue_head_t frame_end_wait;
35 struct completion vsync_completion;
36 struct fb_var_screeninfo display_var;
37 int use_count;
38 struct mutex open_lock; /* protects the use counter */
39};
40
41#endif
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index 55d700e8566e..daabae5817c6 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -49,7 +49,9 @@ struct sh_mobile_lcdc_sys_bus_ops {
49 unsigned long (*read_data)(void *handle); 49 unsigned long (*read_data)(void *handle);
50}; 50};
51 51
52struct module;
52struct sh_mobile_lcdc_board_cfg { 53struct sh_mobile_lcdc_board_cfg {
54 struct module *owner;
53 void *board_data; 55 void *board_data;
54 int (*setup_sys)(void *board_data, void *sys_ops_handle, 56 int (*setup_sys)(void *board_data, void *sys_ops_handle,
55 struct sh_mobile_lcdc_sys_bus_ops *sys_ops); 57 struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
@@ -70,7 +72,8 @@ struct sh_mobile_lcdc_chan_cfg {
70 int interface_type; /* selects RGBn or SYSn I/F, see above */ 72 int interface_type; /* selects RGBn or SYSn I/F, see above */
71 int clock_divider; 73 int clock_divider;
72 unsigned long flags; /* LCDC_FLAGS_... */ 74 unsigned long flags; /* LCDC_FLAGS_... */
73 struct fb_videomode lcd_cfg; 75 const struct fb_videomode *lcd_cfg;
76 int num_cfg;
74 struct sh_mobile_lcdc_lcd_size_cfg lcd_size_cfg; 77 struct sh_mobile_lcdc_lcd_size_cfg lcd_size_cfg;
75 struct sh_mobile_lcdc_board_cfg board_cfg; 78 struct sh_mobile_lcdc_board_cfg board_cfg;
76 struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */ 79 struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */