diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-30 11:26:25 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-30 11:26:25 -0400 |
| commit | 706d4b12f8d7edd28d7e879a77235472da393edb (patch) | |
| tree | c9bc1ce06b1154a49da1d0d907cac544a818eb0e | |
| parent | 3af54c9bd9e6f14f896aac1bb0e8405ae0bc7a44 (diff) | |
| parent | 9bafc74163d8bccca9810159aab39be926fb877c (diff) | |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (215 commits)
ARM: memblock: setup lowmem mappings using memblock
ARM: memblock: move meminfo into find_limits directly
ARM: memblock: convert free_highpages() to use memblock
ARM: move freeing of highmem pages out of mem_init()
ARM: memblock: convert memory detail printing to use memblock
ARM: memblock: use memblock to free memory into arm_bootmem_init()
ARM: memblock: use memblock when initializing memory allocators
ARM: ensure membank array is always sorted
ARM: 6466/1: implement flush_icache_all for the rest of the CPUs
ARM: 6464/2: fix spinlock recursion in adjust_pte()
ARM: fix memblock breakage
ARM: 6465/1: Fix data abort accessing proc_info from __lookup_processor_type
ARM: 6460/1: ixp2000: fix type of ixp2000_timer_interrupt
ARM: 6449/1: Fix for compiler warning of uninitialized variable.
ARM: 6445/1: fixup TCM memory types
ARM: imx: Add wake functionality to GPIO
ARM: mx5: Add gpio-keys to mx51 babbage board
ARM: imx: Add gpio-keys to plat-mxc
mx31_3ds: Fix spi registration
mx31_3ds: Fix the logic for detecting the debug board
...
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 | |||
| 720 | config ARCH_S5PV210 | 720 | config 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 | |||
| 733 | config ARCH_S5PV310 | 735 | config 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 | ||
| 1663 | source "drivers/cpufreq/Kconfig" | 1669 | source "drivers/cpufreq/Kconfig" |
| 1664 | 1670 | ||
| 1671 | config 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 | |||
| 1665 | config CPU_FREQ_SA1100 | 1677 | config 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 | |||
| 82 | CONFIG_INPUT_FF_MEMLESS=m | 82 | CONFIG_INPUT_FF_MEMLESS=m |
| 83 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | 83 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set |
| 84 | CONFIG_INPUT_EVDEV=y | 84 | CONFIG_INPUT_EVDEV=y |
| 85 | CONFIG_KEYBOARD_GPIO=y | ||
| 85 | CONFIG_INPUT_EVBUG=m | 86 | CONFIG_INPUT_EVBUG=m |
| 86 | CONFIG_MOUSE_PS2=m | 87 | CONFIG_MOUSE_PS2=m |
| 87 | CONFIG_MOUSE_PS2_ELANTECH=y | 88 | CONFIG_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__ |
| 58 | extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); | 65 | extern 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 | ||
| 5 | extern 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 | |||
| 11 | struct meminfo; | 4 | struct meminfo; |
| 12 | struct machine_desc; | 5 | struct 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 | ||
| 56 | static inline void outer_flush_all(void) | ||
| 57 | { | ||
| 58 | if (outer_cache.flush_all) | ||
| 59 | outer_cache.flush_all(); | ||
| 60 | } | ||
| 61 | |||
| 62 | static inline void outer_inv_all(void) | ||
| 63 | { | ||
| 64 | if (outer_cache.inv_all) | ||
| 65 | outer_cache.inv_all(); | ||
| 66 | } | ||
| 67 | |||
| 68 | static inline void outer_disable(void) | ||
| 69 | { | ||
| 70 | if (outer_cache.disable) | ||
| 71 | outer_cache.disable(); | ||
| 72 | } | ||
| 73 | |||
| 53 | #else | 74 | #else |
| 54 | 75 | ||
| 55 | static inline void outer_inv_range(unsigned long start, unsigned long end) | 76 | static 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 | { } |
| 59 | static inline void outer_flush_range(unsigned long start, unsigned long end) | 80 | static inline void outer_flush_range(unsigned long start, unsigned long end) |
| 60 | { } | 81 | { } |
| 82 | static inline void outer_flush_all(void) { } | ||
| 83 | static inline void outer_inv_all(void) { } | ||
| 84 | static 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 | |||
| 36 | static const int mx27pdk_pins[] __initconst = { | 40 | static 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 | ||
| 63 | static const struct imxuart_platform_data uart_pdata __initconst = { | 75 | static 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 | ||
| 100 | static 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 | |||
| 107 | static void mx27_3ds_sdhc1_exit(struct device *dev, void *data) | ||
| 108 | { | ||
| 109 | free_irq(IRQ_GPIOB(26), data); | ||
| 110 | } | ||
| 111 | |||
| 112 | static struct imxmmc_platform_data sdhc1_pdata = { | ||
| 113 | .init = mx27_3ds_sdhc1_init, | ||
| 114 | .exit = mx27_3ds_sdhc1_exit, | ||
| 115 | }; | ||
| 116 | |||
| 117 | static 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 | |||
| 88 | static void __init mx27pdk_init(void) | 124 | static 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 | ||
| 97 | static void __init mx27pdk_timer_init(void) | 135 | static 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 | ||
| 200 | static int ixp2000_timer_interrupt(int irq, void *dev_id) | 200 | static 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 | ||
| 10 | config MACH_EUKREA_CPUIMX25 | 11 | config 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 | ||
| 101 | static const struct fec_platform_data mx25_fec_pdata __initconst = { | 109 | static 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 | ||
| 198 | static void __init mx25pdk_timer_init(void) | 208 | static 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 | |||
| 143 | config MACH_MX35_3DS | 143 | config 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 |
| 73 | static struct resource mxcsdhc0_resources[] = { | 73 | static 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 | ||
| 85 | static struct resource mxcsdhc1_resources[] = { | 85 | static 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 | ||
| 289 | static void __init mx31_3ds_timer_init(void) | 259 | static 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 | |||
| 46 | static const struct imxuart_platform_data uart_pdata __initconst = { | 50 | static 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 | ||
| 145 | static void __init mx35pdk_timer_init(void) | 161 | static 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 | ||
| 10 | comment "MX5 platforms:" | 11 | comment "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. |
| 6 | obj-y := cpu.o mm.o clock-mx51.o devices.o | 6 | obj-y := cpu.o mm.o clock-mx51.o devices.o |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o | ||
| 8 | obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o | 9 | obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o |
| 9 | obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o | 10 | obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o |
| 10 | obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o | 11 | obj-$(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 | ||
| 53 | static 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 | |||
| 63 | static const struct gpio_keys_platform_data imx_button_data __initconst = { | ||
| 64 | .buttons = babbage_buttons, | ||
| 65 | .nbuttons = ARRAY_SIZE(babbage_buttons), | ||
| 66 | }; | ||
| 67 | |||
| 49 | static struct pad_desc mx51babbage_pads[] = { | 68 | static 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); | |||
| 281 | static void __init mxc_board_init(void) | 316 | static 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 | ||
| 309 | static void __init mx51_babbage_timer_init(void) | 356 | static 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 | ||
| 365 | static unsigned long clk_arm_get_rate(struct clk *clk) | 365 | static 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 | ||
| 377 | static 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 | |||
| 377 | static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent) | 393 | static 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 | ||
| 737 | static struct clk cpu_clk = { | 753 | static 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 | ||
| 742 | static struct clk ahb_clk = { | 759 | static 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 | ||
| 1069 | static void clk_tree_init(void) | 1087 | static 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 | |||
| 18 | static struct cpu_op mx51_cpu_op[] = { | ||
| 19 | { | ||
| 20 | .cpu_rate = 160000000,}, | ||
| 21 | { | ||
| 22 | .cpu_rate = 800000000,}, | ||
| 23 | }; | ||
| 24 | |||
| 25 | struct 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 | |||
| 14 | extern 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 | |||
| 16 | extern const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst; | 18 | extern 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 | |||
| 48 | static void omap4_l2x0_disable(void) | ||
| 49 | { | ||
| 50 | /* Disable PL310 L2 Cache controller */ | ||
| 51 | omap_smc1(0x102, 0x0); | ||
| 52 | } | ||
| 53 | |||
| 47 | static int __init omap_l2_cache_init(void) | 54 | static 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 | } |
| 75 | early_initcall(omap_l2_cache_init); | 88 | early_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 | ||
| 123 | static inline unsigned int | 125 | static 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 |
| 56 | void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; | 57 | void __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 | ||
| 28 | config S3C2416_PM | ||
| 29 | bool | ||
| 30 | help | ||
| 31 | Internal config node to apply S3C2416 power management | ||
| 32 | |||
| 28 | menu "S3C2416 Machines" | 33 | menu "S3C2416 Machines" |
| 29 | 34 | ||
| 30 | config MACH_SMDK2416 | 35 | config 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 | ||
| 12 | obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o | 12 | obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o |
| 13 | obj-$(CONFIG_CPU_S3C2416) += irq.o | 13 | obj-$(CONFIG_CPU_S3C2416) += irq.o |
| 14 | 14 | obj-$(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 | ||
| 244 | static struct sysdev_driver s3c2416_irq_driver = { | 244 | static 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 | ||
| 248 | static int __init s3c2416_irq_init(void) | 250 | static 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 | |||
| 24 | extern void s3c2412_sleep_enter(void); | ||
| 25 | |||
| 26 | static 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 | |||
| 39 | static 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 | |||
| 50 | static 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 | |||
| 58 | static int s3c2416_pm_suspend(struct sys_device *dev, pm_message_t state) | ||
| 59 | { | ||
| 60 | return 0; | ||
| 61 | } | ||
| 62 | |||
| 63 | static 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 | |||
| 73 | static struct sysdev_driver s3c2416_pm_driver = { | ||
| 74 | .add = s3c2416_pm_add, | ||
| 75 | .suspend = s3c2416_pm_suspend, | ||
| 76 | .resume = s3c2416_pm_resume, | ||
| 77 | }; | ||
| 78 | |||
| 79 | static __init int s3c2416_pm_init(void) | ||
| 80 | { | ||
| 81 | return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_pm_driver); | ||
| 82 | } | ||
| 83 | |||
| 84 | arch_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 | ||
| 60 | static struct map_desc s3c2416_iodesc[] __initdata = { | 61 | static 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 | ||
| 48 | static struct map_desc s3c244x_iodesc[] __initdata = { | 49 | static 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 | ||
| 40 | static struct map_desc s3c2443_iodesc[] __initdata = { | 41 | static 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 | ||
| 101 | config 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 | |||
| 101 | config MACH_REAL6410 | 116 | config 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 | |||
| 53 | obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o | 53 | obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o |
| 54 | obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o | 54 | obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o |
| 55 | obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o | 55 | obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o |
| 56 | obj-$(CONFIG_MACH_MINI6410) += mach-mini6410.o | ||
| 56 | obj-$(CONFIG_MACH_NCP) += mach-ncp.o | 57 | obj-$(CONFIG_MACH_NCP) += mach-ncp.o |
| 57 | obj-$(CONFIG_MACH_HMT) += mach-hmt.o | 58 | obj-$(CONFIG_MACH_HMT) += mach-hmt.o |
| 58 | obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o | 59 | obj-$(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 | |||
| 30 | static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) | 25 | static 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 | ||
| 56 | static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev) | 47 | static 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 | ||
| 171 | static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev) | 159 | static 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 | ||
| 265 | static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev) | 248 | static 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 | ||
| 276 | static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev) | 253 | static 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 | ||
| 287 | static struct resource s3c64xx_ac97_resource[] = { | 258 | static 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 | ||
| 198 | int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin) | ||
| 199 | { | ||
| 200 | return IRQ_EINT(0) + pin; | ||
| 201 | } | ||
| 202 | |||
| 203 | static struct s3c_gpio_chip gpio_2bit[] = { | 198 | static 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 | |||
| 52 | static 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 | |||
| 85 | static 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 | |||
| 103 | static struct dm9000_plat_data mini6410_dm9k_pdata = { | ||
| 104 | .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM), | ||
| 105 | }; | ||
| 106 | |||
| 107 | static 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 | |||
| 117 | static 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 | |||
| 135 | static 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 | |||
| 144 | static 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 | |||
| 152 | static 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 | |||
| 182 | static 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 | |||
| 189 | static 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 | |||
| 198 | static struct plat_lcd_data mini6410_lcd_power_data = { | ||
| 199 | .set_power = mini6410_lcd_power_set, | ||
| 200 | }; | ||
| 201 | |||
| 202 | static 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 | |||
| 208 | static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = { | ||
| 209 | .delay = 10000, | ||
| 210 | .presc = 49, | ||
| 211 | .oversampling_shift = 2, | ||
| 212 | }; | ||
| 213 | |||
| 214 | static 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 | |||
| 226 | static 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 | */ | ||
| 252 | static char mini6410_features_str[12] __initdata = "0"; | ||
| 253 | |||
| 254 | static 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 | |||
| 266 | struct mini6410_features_t { | ||
| 267 | int done; | ||
| 268 | int lcd_index; | ||
| 269 | }; | ||
| 270 | |||
| 271 | static 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 | |||
| 303 | static 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 | |||
| 350 | MACHINE_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, | ||
| 357 | MACHINE_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 | ||
| 118 | static 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 | |||
| 148 | static 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 | |||
| 155 | static 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 | |||
| 173 | static 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 | |||
| 182 | static 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 | |||
| 102 | static struct platform_device *real6410_devices[] __initdata = { | 190 | static 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 | |||
| 201 | static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = { | ||
| 202 | .delay = 10000, | ||
| 203 | .presc = 49, | ||
| 204 | .oversampling_shift = 2, | ||
| 106 | }; | 205 | }; |
| 107 | 206 | ||
| 108 | static void __init real6410_map_io(void) | 207 | static 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 | */ | ||
| 233 | static char real6410_features_str[12] __initdata = "0"; | ||
| 234 | |||
| 235 | static 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 | |||
| 247 | struct real6410_features_t { | ||
| 248 | int done; | ||
| 249 | int lcd_index; | ||
| 250 | }; | ||
| 251 | |||
| 252 | static 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 | ||
| 115 | static void __init real6410_machine_init(void) | 284 | static 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 | ||
| 24 | extern void s3c64xx_fb_gpio_setup_24bpp(void) | 24 | extern 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 | ||
| 21 | void s3c64xx_ide_setup_gpio(void) | 22 | void 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 | ||
| 16 | void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) | 17 | void 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 @@ | |||
| 24 | void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) | 24 | void 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) | |||
| 44 | void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) | 37 | void 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 | ||
| 64 | void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) | 50 | void 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 | ||
| 12 | config CPU_S5P6442 | 12 | config 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 | ||
| 195 | int s5p6442_clk_ip0_ctrl(struct clk *clk, int enable) | ||
| 196 | { | ||
| 197 | return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable); | ||
| 198 | } | ||
| 199 | |||
| 195 | int s5p6442_clk_ip3_ctrl(struct clk *clk, int enable) | 200 | int 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 | ||
| 343 | static 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 | |||
| 338 | static struct clk init_clocks[] = { | 353 | static struct clk init_clocks[] = { |
| 339 | { | 354 | { |
| 340 | .name = "systimer", | 355 | .name = "systimer", |
| @@ -393,10 +408,23 @@ static struct clk *clks[] __initdata = { | |||
| 393 | 408 | ||
| 394 | void __init s5p6442_register_clocks(void) | 409 | void __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 | ||
| 22 | static int s5p6442_cfg_i2s(struct platform_device *pdev) | 22 | static 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 | ||
| 112 | static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev) | 107 | static 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 | ||
| 83 | static struct platform_device s5p6442_device_pdma = { | 83 | static 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 | ||
| 10 | config CPU_S5P6440 | 10 | config 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 | ||
| 17 | config CPU_S5P6450 | 16 | config 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 | ||
| 87 | static struct clk_ops s5p6440_epll_ops = { | 90 | static 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 | ||
| 88 | static struct clk_ops s5p6450_epll_ops = { | 91 | static 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 | ||
| 76 | int 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 | |||
| 89 | unsigned long s5p64x0_epll_get_rate(struct clk *clk) | ||
| 90 | { | ||
| 91 | return clk->rate; | ||
| 92 | } | ||
| 93 | |||
| 94 | unsigned long s5p64x0_armclk_get_rate(struct clk *clk) | 76 | unsigned 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 | */ |
| 40 | static int s5p6440_spi_cfg_gpio(struct platform_device *pdev) | 40 | static 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 | ||
| 69 | static int s5p6450_spi_cfg_gpio(struct platform_device *pdev) | 64 | static 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 | ||
| 123 | static struct platform_device s5p64x0_device_pdma = { | 123 | static 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 | ||
| 26 | void s5p6440_i2c0_cfg_gpio(struct platform_device *dev) | 26 | void 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 | ||
| 34 | void s5p6450_i2c0_cfg_gpio(struct platform_device *dev) | 32 | void 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 | ||
| 42 | void s3c_i2c0_cfg_gpio(struct platform_device *dev) { } | 38 | void 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 | ||
| 26 | void s5p6440_i2c1_cfg_gpio(struct platform_device *dev) | 26 | void 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 | ||
| 34 | void s5p6450_i2c1_cfg_gpio(struct platform_device *dev) | 32 | void 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 | ||
| 42 | void s3c_i2c1_cfg_gpio(struct platform_device *dev) { } | 38 | void 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 | ||
| 10 | config CPU_S5PC100 | 10 | config 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 | ||
| 14 | obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o gpiolib.o irq-gpio.o | 14 | obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o gpiolib.o |
| 15 | obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o | 15 | obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o |
| 16 | obj-$(CONFIG_CPU_S5PC100) += dma.o | 16 | obj-$(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 | ||
| 276 | static 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 | |||
| 289 | static unsigned long s5pc100_epll_get_rate(struct clk *clk) | ||
| 290 | { | ||
| 291 | return clk->rate; | ||
| 292 | } | ||
| 293 | |||
| 294 | static u32 epll_div[][4] = { | 276 | static 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 | ||
| 349 | static struct clk_ops s5pc100_epll_ops = { | 334 | static 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 | ||
| 836 | static 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 | |||
| 851 | static struct clk *clk_src_group4_list[] = { | 848 | static 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 | ||
| 862 | static 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 | |||
| 865 | static struct clk *clk_src_group5_list[] = { | 874 | static 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 | ||
| 887 | static 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 | |||
| 878 | static struct clk *clk_src_group6_list[] = { | 899 | static 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 | ||
| 968 | static 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 | |||
| 974 | struct clksrc_sources clk_src_sclk_spdif = { | ||
| 975 | .sources = clk_sclk_spdif_list, | ||
| 976 | .nr_sources = ARRAY_SIZE(clk_sclk_spdif_list), | ||
| 977 | }; | ||
| 978 | |||
| 979 | static 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 | |||
| 994 | static 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 | |||
| 1009 | static struct clk_ops s5pc100_sclk_spdif_ops = { | ||
| 1010 | .set_rate = s5pc100_spdif_set_rate, | ||
| 1011 | .get_rate = s5pc100_spdif_get_rate, | ||
| 1012 | }; | ||
| 1013 | |||
| 1014 | static 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 | |||
| 947 | static struct clksrc_clk clksrcs[] = { | 1026 | static 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 | ||
| 1184 | void __init_or_cpufreq s5pc100_setup_clocks(void) | 1234 | void __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 | ||
| 232 | static int s5pc100_ac97_cfg_gpio(struct platform_device *pdev) | 216 | static 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 | ||
| 243 | static struct resource s5pc100_ac97_resource[] = { | 221 | static 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 */ | ||
| 268 | static 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 | |||
| 275 | static 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 | |||
| 282 | static 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 | |||
| 295 | static struct s3c_audio_pdata s5p_spdif_pdata = { | ||
| 296 | .cfg_gpio = s5pc100_spdif_cfg_gpd, | ||
| 297 | }; | ||
| 298 | |||
| 299 | static u64 s5pc100_spdif_dmamask = DMA_BIT_MASK(32); | ||
| 300 | |||
| 301 | struct 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 | |||
| 313 | void __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 | ||
| 82 | static struct platform_device s5pc100_device_pdma0 = { | 82 | static 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 | ||
| 144 | static struct platform_device s5pc100_device_pdma1 = { | 144 | static 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 | ||
| 64 | static int s5pc100_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) | ||
| 65 | { | ||
| 66 | return S3C_IRQ_GPIO(chip->base + offset); | ||
| 67 | } | ||
| 68 | |||
| 69 | static 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 | |||
| 88 | static struct s3c_gpio_cfg gpio_cfg = { | 66 | static 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 | */ | ||
| 107 | static struct s3c_gpio_chip s5pc100_gpio_chips[] = { | 101 | static 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 */ | 334 | static __init int s5pc100_gpiolib_init(void) |
| 384 | extern struct irq_chip s5pc100_gpioint; | ||
| 385 | extern void s5pc100_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc); | ||
| 386 | |||
| 387 | static __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 | |||
| 407 | static __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 | |||
| 37 | static int group_to_con_offset(int group) | ||
| 38 | { | ||
| 39 | return group << 2; | ||
| 40 | } | ||
| 41 | |||
| 42 | static int group_to_mask_offset(int group) | ||
| 43 | { | ||
| 44 | return group << 2; | ||
| 45 | } | ||
| 46 | |||
| 47 | static int group_to_pend_offset(int group) | ||
| 48 | { | ||
| 49 | return group << 2; | ||
| 50 | } | ||
| 51 | |||
| 52 | static 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 | |||
| 83 | static 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 | |||
| 137 | static 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 | |||
| 143 | static 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 | |||
| 157 | static 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 | |||
| 171 | static 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 | |||
| 185 | static void s5pc100_gpioint_mask_ack(unsigned int irq) | ||
| 186 | { | ||
| 187 | s5pc100_gpioint_mask(irq); | ||
| 188 | s5pc100_gpioint_ack(irq); | ||
| 189 | } | ||
| 190 | |||
| 191 | static 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 | |||
| 232 | struct 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 | |||
| 241 | void 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 | ||
| 201 | static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = { | 203 | static 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 | ||
| 25 | void s5pc100_fb_gpio_setup_24bpp(void) | 25 | static 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++) { | 30 | void 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 | ||
| 24 | void s3c_i2c0_cfg_gpio(struct platform_device *dev) | 24 | void 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 | ||
| 24 | void s3c_i2c1_cfg_gpio(struct platform_device *dev) | 24 | void 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 | ||
| 20 | static 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 | |||
| 20 | void s5pc100_ide_setup_gpio(void) | 28 | void 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 | ||
| 16 | void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) | 16 | void 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 @@ | |||
| 25 | void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) | 25 | void 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) | |||
| 58 | void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) | 47 | void 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) | |||
| 78 | void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) | 60 | void 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 | ||
| 12 | config CPU_S5PV210 | 12 | config 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" | |||
| 58 | config MACH_AQUILA | 58 | config 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 | |||
| 75 | config MACH_GONI | 74 | config 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 | |||
| 93 | config MACH_SMDKC110 | 99 | config 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" | |||
| 113 | config MACH_SMDKV210 | 118 | config 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 | ||
| 141 | config 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 | |||
| 137 | endmenu | 159 | endmenu |
| 138 | 160 | ||
| 161 | config S5PV210_PM | ||
| 162 | bool | ||
| 163 | help | ||
| 164 | Power Management code common to S5PV210 | ||
| 165 | |||
| 139 | endif | 166 | endif |
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 | ||
| 15 | obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o | 15 | obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o |
| 16 | obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o | 16 | obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o |
| 17 | obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o | ||
| 18 | obj-$(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 | |||
| 21 | obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o | 23 | obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o |
| 22 | obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o | 24 | obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o |
| 23 | obj-$(CONFIG_MACH_GONI) += mach-goni.o | 25 | obj-$(CONFIG_MACH_GONI) += mach-goni.o |
| 26 | obj-$(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 | ||
| 34 | static unsigned long xtal; | ||
| 35 | |||
| 34 | static struct clksrc_clk clk_mout_apll = { | 36 | static 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 | ||
| 264 | static 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 | |||
| 271 | static struct clksrc_sources clkset_moutdmc0src = { | ||
| 272 | .sources = clkset_moutdmc0src_list, | ||
| 273 | .nr_sources = ARRAY_SIZE(clkset_moutdmc0src_list), | ||
| 274 | }; | ||
| 275 | |||
| 276 | static 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 | |||
| 285 | static 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 | |||
| 262 | static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk) | 294 | static 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 | ||
| 303 | static 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 | |||
| 308 | static struct clk_ops clk_fout_apll_ops = { | ||
| 309 | .get_rate = s5pv210_clk_fout_apll_get_rate, | ||
| 310 | }; | ||
| 311 | |||
| 271 | static struct clk init_clocks_disable[] = { | 312 | static 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 | ||
| 722 | static 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 | |||
| 737 | static 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 | |||
| 752 | static struct clk_ops s5pv210_sclk_spdif_ops = { | ||
| 753 | .set_rate = s5pv210_spdif_set_rate, | ||
| 754 | .get_rate = s5pv210_spdif_get_rate, | ||
| 755 | }; | ||
| 756 | |||
| 757 | static 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 | |||
| 663 | static struct clk *clkset_group2_list[] = { | 769 | static 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 | |||
| 1061 | static 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 | |||
| 1086 | static 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 | |||
| 1132 | static struct clk_ops s5pv210_epll_ops = { | ||
| 1133 | .set_rate = s5pv210_epll_set_rate, | ||
| 1134 | .get_rate = s5p_epll_get_rate, | ||
| 956 | }; | 1135 | }; |
| 957 | 1136 | ||
| 958 | void __init_or_cpufreq s5pv210_setup_clocks(void) | 1137 | void __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 | |||
| 24 | static struct clk *cpu_clk; | ||
| 25 | static struct clk *dmc0_clk; | ||
| 26 | static struct clk *dmc1_clk; | ||
| 27 | static 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 | */ | ||
| 37 | struct dram_conf { | ||
| 38 | unsigned long freq; /* HZ */ | ||
| 39 | unsigned long refresh; /* DRAM refresh counter * 1000 */ | ||
| 40 | }; | ||
| 41 | |||
| 42 | /* DRAM configuration (DMC0 and DMC1) */ | ||
| 43 | static struct dram_conf s5pv210_dram_conf[2]; | ||
| 44 | |||
| 45 | enum perf_level { | ||
| 46 | L0, L1, L2, L3, L4, | ||
| 47 | }; | ||
| 48 | |||
| 49 | enum s5pv210_mem_type { | ||
| 50 | LPDDR = 0x1, | ||
| 51 | LPDDR2 = 0x2, | ||
| 52 | DDR2 = 0x4, | ||
| 53 | }; | ||
| 54 | |||
| 55 | enum s5pv210_dmc_port { | ||
| 56 | DMC0 = 0, | ||
| 57 | DMC1, | ||
| 58 | }; | ||
| 59 | |||
| 60 | static 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 | |||
| 69 | static 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 | */ | ||
| 99 | static 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 | |||
| 123 | int 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 | |||
| 131 | unsigned int s5pv210_getspeed(unsigned int cpu) | ||
| 132 | { | ||
| 133 | if (cpu) | ||
| 134 | return 0; | ||
| 135 | |||
| 136 | return clk_get_rate(cpu_clk) / 1000; | ||
| 137 | } | ||
| 138 | |||
| 139 | static 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 | ||
| 393 | static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy, | ||
| 394 | pm_message_t pmsg) | ||
| 395 | { | ||
| 396 | return 0; | ||
| 397 | } | ||
| 398 | |||
| 399 | static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy) | ||
| 400 | { | ||
| 401 | return 0; | ||
| 402 | } | ||
| 403 | #endif | ||
| 404 | |||
| 405 | static 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 | |||
| 415 | static 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 | |||
| 466 | static 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 | |||
| 479 | static int __init s5pv210_cpufreq_init(void) | ||
| 480 | { | ||
| 481 | return cpufreq_register_driver(&s5pv210_driver); | ||
| 482 | } | ||
| 483 | |||
| 484 | late_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 | ||
| 272 | static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev) | 246 | static 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 | ||
| 283 | static struct resource s5pv210_ac97_resource[] = { | 251 | static 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 | |||
| 299 | static 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 | |||
| 306 | static 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 | |||
| 319 | static struct s3c_audio_pdata samsung_spdif_pdata = { | ||
| 320 | .cfg_gpio = s5pv210_spdif_cfg_gpio, | ||
| 321 | }; | ||
| 322 | |||
| 323 | static u64 s5pv210_spdif_dmamask = DMA_BIT_MASK(32); | ||
| 324 | |||
| 325 | struct 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 | */ |
| 36 | static int s5pv210_spi_cfg_gpio(struct platform_device *pdev) | 36 | static 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 | ||
| 83 | static struct platform_device s5pv210_device_pdma0 = { | 83 | static 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 | ||
| 145 | static struct platform_device s5pv210_device_pdma1 = { | 145 | static 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 | |||
| 18 | static inline void s3c_pm_debug_init_uart(void) | ||
| 19 | { | ||
| 20 | /* nothing here yet */ | ||
| 21 | } | ||
| 22 | |||
| 23 | static 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 | |||
| 29 | static inline void s3c_pm_arch_stop_clocks(void) | ||
| 30 | { | ||
| 31 | /* nothing here yet */ | ||
| 32 | } | ||
| 33 | |||
| 34 | static inline void s3c_pm_arch_show_resume_irqs(void) | ||
| 35 | { | ||
| 36 | /* nothing here yet */ | ||
| 37 | } | ||
| 38 | |||
| 39 | static 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 | ||
| 384 | static 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 | |||
| 397 | static 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 | |||
| 407 | static 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 | |||
| 415 | static 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 | |||
| 423 | static 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 | |||
| 430 | static 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 | |||
| 437 | static 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 | |||
| 445 | static 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 | |||
| 453 | static struct regulator_consumer_supply wm8994_avdd1_supply = { | ||
| 454 | .dev_name = "5-001a", | ||
| 455 | .supply = "AVDD1", | ||
| 456 | }; | ||
| 457 | |||
| 458 | static struct regulator_consumer_supply wm8994_dcvdd_supply = { | ||
| 459 | .dev_name = "5-001a", | ||
| 460 | .supply = "DCVDD", | ||
| 461 | }; | ||
| 462 | |||
| 463 | static 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 | |||
| 472 | static 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 | |||
| 480 | static 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 |
| 384 | static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = { | 499 | static 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 | ||
| 524 | static 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 | |||
| 529 | static 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 | |||
| 537 | static 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 */ |
| 408 | static struct gpio_keys_button aquila_gpio_keys_table[] = { | 546 | static struct gpio_keys_button aquila_gpio_keys_table[] = { |
| 409 | { | 547 | { |
| @@ -475,6 +613,7 @@ static void aquila_setup_sdhci(void) | |||
| 475 | 613 | ||
| 476 | static struct platform_device *aquila_devices[] __initdata = { | 614 | static 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 | ||
| 631 | static 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 | |||
| 489 | static void __init aquila_map_io(void) | 653 | static 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 */ |
| 88 | static struct s3c_fb_pd_win goni_fb_win0 = { | 97 | static 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 | ||
| 122 | static int lcd_power_on(struct lcd_device *ld, int enable) | ||
| 123 | { | ||
| 124 | return 1; | ||
| 125 | } | ||
| 126 | |||
| 127 | static 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 | |||
| 143 | static 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 | ||
| 153 | static 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 | |||
| 165 | static 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 | |||
| 172 | static 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 */ | ||
| 182 | static 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 | |||
| 192 | static struct matrix_keymap_data keymap_data __initdata = { | ||
| 193 | .keymap = keymap, | ||
| 194 | .keymap_size = ARRAY_SIZE(keymap), | ||
| 195 | }; | ||
| 196 | |||
| 197 | static struct samsung_keypad_platdata keypad_data __initdata = { | ||
| 198 | .keymap_data = &keymap_data, | ||
| 199 | .rows = 3, | ||
| 200 | .cols = 3, | ||
| 201 | }; | ||
| 202 | |||
| 203 | /* Radio */ | ||
| 204 | static struct i2c_board_info i2c1_devs[] __initdata = { | ||
| 205 | { | ||
| 206 | I2C_BOARD_INFO("si470x", 0x10), | ||
| 207 | }, | ||
| 208 | }; | ||
| 209 | |||
| 210 | static 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 */ | ||
| 225 | static 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 | |||
| 236 | static 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 | |||
| 244 | static struct i2c_board_info i2c2_devs[] __initdata = { | ||
| 245 | { | ||
| 246 | I2C_BOARD_INFO("qt602240_ts", 0x4a), | ||
| 247 | .platform_data = &qt602240_platform_data, | ||
| 248 | }, | ||
| 249 | }; | ||
| 250 | |||
| 251 | static 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 | ||
| 272 | static struct regulator_consumer_supply goni_ldo5_consumers[] = { | ||
| 273 | REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"), | ||
| 274 | }; | ||
| 275 | |||
| 117 | static struct regulator_init_data goni_ldo2_data = { | 276 | static 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 | ||
| 158 | static struct regulator_init_data goni_ldo6_data = { | 319 | static 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 | ||
| 524 | static 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 | |||
| 537 | static 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 | |||
| 547 | static 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 | |||
| 555 | static 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 | |||
| 563 | static 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 | |||
| 570 | static 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 | |||
| 577 | static 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 | |||
| 585 | static 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 | |||
| 593 | static struct regulator_consumer_supply wm8994_avdd1_supply = { | ||
| 594 | .dev_name = "5-001a", | ||
| 595 | .supply = "AVDD1", | ||
| 596 | }; | ||
| 597 | |||
| 598 | static struct regulator_consumer_supply wm8994_dcvdd_supply = { | ||
| 599 | .dev_name = "5-001a", | ||
| 600 | .supply = "DCVDD", | ||
| 601 | }; | ||
| 602 | |||
| 603 | static 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 | |||
| 612 | static 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 | |||
| 620 | static 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 |
| 365 | static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = { | 639 | static 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 | ||
| 664 | static 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 | |||
| 669 | static 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 | |||
| 677 | static 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 */ |
| 389 | static struct gpio_keys_button goni_gpio_keys_table[] = { | 686 | static 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 | ||
| 744 | static struct regulator_consumer_supply mmc2_supplies[] = { | ||
| 745 | REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"), | ||
| 746 | }; | ||
| 747 | |||
| 748 | static 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 | |||
| 757 | static 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 | |||
| 765 | static 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 | |||
| 447 | static void goni_setup_sdhci(void) | 773 | static 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) | |||
| 457 | static struct platform_device *goni_devices[] __initdata = { | 780 | static 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 | ||
| 803 | static 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 | |||
| 470 | static void __init goni_map_io(void) | 812 | static 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 | ||
| 477 | static void __init goni_machine_init(void) | 819 | static 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 = { | |||
| 81 | static struct platform_device *smdkc110_devices[] __initdata = { | 82 | static 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 | ||
| 111 | static void __init smdkc110_machine_init(void) | 113 | static 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 = { | |||
| 103 | static struct platform_device *smdkv210_devices[] __initdata = { | 104 | static 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 | ||
| 146 | static void __init smdkv210_machine_init(void) | 148 | static 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 | |||
| 45 | static 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 | |||
| 76 | static 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 | |||
| 90 | static struct i2c_board_info torbreck_i2c_devs0[] __initdata = { | ||
| 91 | /* To Be Updated */ | ||
| 92 | }; | ||
| 93 | |||
| 94 | static struct i2c_board_info torbreck_i2c_devs1[] __initdata = { | ||
| 95 | /* To Be Updated */ | ||
| 96 | }; | ||
| 97 | |||
| 98 | static struct i2c_board_info torbreck_i2c_devs2[] __initdata = { | ||
| 99 | /* To Be Updated */ | ||
| 100 | }; | ||
| 101 | |||
| 102 | static 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 | |||
| 109 | static 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 | |||
| 124 | MACHINE_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, | ||
| 131 | MACHINE_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 | |||
| 28 | static 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 | |||
| 90 | void 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 | |||
| 110 | static 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 | |||
| 135 | static 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 | |||
| 143 | static 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 | |||
| 157 | static struct sysdev_driver s5pv210_pm_driver = { | ||
| 158 | .add = s5pv210_pm_add, | ||
| 159 | .resume = s5pv210_pm_resume, | ||
| 160 | }; | ||
| 161 | |||
| 162 | static __init int s5pv210_pm_drvinit(void) | ||
| 163 | { | ||
| 164 | return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver); | ||
| 165 | } | ||
| 166 | arch_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 | ||
| 24 | void s5pv210_fb_gpio_setup_24bpp(void) | 24 | static 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++) { | 33 | void 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 | ||
| 24 | void s3c_i2c0_cfg_gpio(struct platform_device *dev) | 24 | void 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 | ||
| 24 | void s3c_i2c1_cfg_gpio(struct platform_device *dev) | 24 | void 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 | ||
| 24 | void s3c_i2c2_cfg_gpio(struct platform_device *dev) | 24 | void 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 | ||
| 18 | static 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 | |||
| 18 | void s5pv210_ide_setup_gpio(void) | 26 | void 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 | ||
| 17 | void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) | 17 | void 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 @@ | |||
| 26 | void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) | 26 | void 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) | |||
| 59 | void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) | 50 | void 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) | |||
| 82 | void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) | 66 | void 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) | |||
| 116 | void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width) | 90 | void 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 | |||
| 41 | ENTRY(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 | |||
| 64 | resume_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 | ||
| 79 | s3c_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 | |||
| 98 | ENTRY(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 | ||
| 12 | config CPU_S5PV310 | 12 | config 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 | ||
| 27 | config S5PV310_SETUP_I2C3 | ||
| 28 | bool | ||
| 29 | help | ||
| 30 | Common setup code for i2c bus 3. | ||
| 31 | |||
| 32 | config S5PV310_SETUP_I2C4 | ||
| 33 | bool | ||
| 34 | help | ||
| 35 | Common setup code for i2c bus 4. | ||
| 36 | |||
| 37 | config S5PV310_SETUP_I2C5 | ||
| 38 | bool | ||
| 39 | help | ||
| 40 | Common setup code for i2c bus 5. | ||
| 41 | |||
| 42 | config S5PV310_SETUP_I2C6 | ||
| 43 | bool | ||
| 44 | help | ||
| 45 | Common setup code for i2c bus 6. | ||
| 46 | |||
| 47 | config S5PV310_SETUP_I2C7 | ||
| 48 | bool | ||
| 49 | help | ||
| 50 | Common setup code for i2c bus 7. | ||
| 51 | |||
| 52 | config S5PV310_SETUP_SDHCI | ||
| 53 | bool | ||
| 54 | select S5PV310_SETUP_SDHCI_GPIO | ||
| 55 | help | ||
| 56 | Internal helper functions for S5PV310 based SDHCI systems. | ||
| 57 | |||
| 58 | config S5PV310_SETUP_SDHCI_GPIO | ||
| 59 | bool | ||
| 60 | help | ||
| 61 | Common setup code for SDHCI gpio. | ||
| 62 | |||
| 28 | # machine support | 63 | # machine support |
| 29 | 64 | ||
| 30 | config MACH_SMDKV310 | 65 | menu "S5PC210 Machines" |
| 31 | bool "SMDKV310" | 66 | |
| 67 | config 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 | ||
| 37 | config MACH_UNIVERSAL_C210 | 81 | config 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 | ||
| 91 | endmenu | ||
| 92 | |||
| 93 | menu "S5PV310 Machines" | ||
| 94 | |||
| 95 | config 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 | |||
| 108 | endmenu | ||
| 109 | |||
| 110 | comment "Configuration for HSMMC bus width" | ||
| 111 | |||
| 112 | menu "Use 8-bit bus width" | ||
| 113 | |||
| 114 | config 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 | |||
| 120 | config 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 | |||
| 126 | endmenu | ||
| 127 | |||
| 45 | endif | 128 | endif |
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 | ||
| 15 | obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o | 15 | obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o |
| 16 | obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o | 16 | obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o |
| 17 | 17 | ||
| 18 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 18 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
| 19 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o | 19 | obj-$(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 | ||
| 24 | obj-$(CONFIG_MACH_SMDKC210) += mach-smdkc210.o | ||
| 24 | obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o | 25 | obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o |
| 25 | obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o | 26 | obj-$(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 | ||
| 29 | obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o | 30 | obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o |
| 30 | obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o | 31 | obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o |
| 32 | obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o | ||
| 33 | obj-$(CONFIG_S5PV310_SETUP_I2C4) += setup-i2c4.o | ||
| 34 | obj-$(CONFIG_S5PV310_SETUP_I2C5) += setup-i2c5.o | ||
| 35 | obj-$(CONFIG_S5PV310_SETUP_I2C6) += setup-i2c6.o | ||
| 36 | obj-$(CONFIG_S5PV310_SETUP_I2C7) += setup-i2c7.o | ||
| 37 | obj-$(CONFIG_S5PV310_SETUP_SDHCI) += setup-sdhci.o | ||
| 38 | obj-$(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 | ||
| 33 | static struct clk clk_sclk_hdmiphy = { | ||
| 34 | .name = "sclk_hdmiphy", | ||
| 35 | .id = -1, | ||
| 36 | }; | ||
| 37 | |||
| 38 | static struct clk clk_sclk_usbphy0 = { | ||
| 39 | .name = "sclk_usbphy0", | ||
| 40 | .id = -1, | ||
| 41 | .rate = 27000000, | ||
| 42 | }; | ||
| 43 | |||
| 44 | static struct clk clk_sclk_usbphy1 = { | ||
| 45 | .name = "sclk_usbphy1", | ||
| 46 | .id = -1, | ||
| 47 | }; | ||
| 48 | |||
| 49 | static int s5pv310_clksrc_mask_top_ctrl(struct clk *clk, int enable) | ||
| 50 | { | ||
| 51 | return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable); | ||
| 52 | } | ||
| 53 | |||
| 54 | static int s5pv310_clksrc_mask_cam_ctrl(struct clk *clk, int enable) | ||
| 55 | { | ||
| 56 | return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable); | ||
| 57 | } | ||
| 58 | |||
| 59 | static int s5pv310_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable) | ||
| 60 | { | ||
| 61 | return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable); | ||
| 62 | } | ||
| 63 | |||
| 64 | static int s5pv310_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable) | ||
| 65 | { | ||
| 66 | return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable); | ||
| 67 | } | ||
| 68 | |||
| 69 | static int s5pv310_clksrc_mask_fsys_ctrl(struct clk *clk, int enable) | ||
| 70 | { | ||
| 71 | return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable); | ||
| 72 | } | ||
| 73 | |||
| 33 | static int s5pv310_clksrc_mask_peril0_ctrl(struct clk *clk, int enable) | 74 | static 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 | ||
| 79 | static int s5pv310_clksrc_mask_peril1_ctrl(struct clk *clk, int enable) | ||
| 80 | { | ||
| 81 | return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable); | ||
| 82 | } | ||
| 83 | |||
| 84 | static int s5pv310_clk_ip_cam_ctrl(struct clk *clk, int enable) | ||
| 85 | { | ||
| 86 | return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable); | ||
| 87 | } | ||
| 88 | |||
| 89 | static int s5pv310_clk_ip_image_ctrl(struct clk *clk, int enable) | ||
| 90 | { | ||
| 91 | return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable); | ||
| 92 | } | ||
| 93 | |||
| 94 | static int s5pv310_clk_ip_lcd0_ctrl(struct clk *clk, int enable) | ||
| 95 | { | ||
| 96 | return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable); | ||
| 97 | } | ||
| 98 | |||
| 99 | static int s5pv310_clk_ip_lcd1_ctrl(struct clk *clk, int enable) | ||
| 100 | { | ||
| 101 | return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable); | ||
| 102 | } | ||
| 103 | |||
| 104 | static int s5pv310_clk_ip_fsys_ctrl(struct clk *clk, int enable) | ||
| 105 | { | ||
| 106 | return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable); | ||
| 107 | } | ||
| 108 | |||
| 38 | static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable) | 109 | static 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 | ||
| 114 | static 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 | ||
| 45 | static struct clksrc_clk clk_mout_apll = { | 121 | static struct clksrc_clk clk_mout_apll = { |
| @@ -79,7 +155,7 @@ static struct clksrc_clk clk_mout_mpll = { | |||
| 79 | }; | 155 | }; |
| 80 | 156 | ||
| 81 | static struct clk *clkset_moutcore_list[] = { | 157 | static 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 | ||
| 153 | static 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 | |||
| 162 | static 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 | ||
| 173 | static struct clk *clkset_corebus_list[] = { | 231 | static 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 | ||
| 244 | static struct clksrc_sources clkset_aclk_200 = { | 302 | static 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 | ||
| 259 | static struct clksrc_sources clkset_aclk_100 = { | ||
| 260 | .sources = clkset_aclk_top_list, | ||
| 261 | .nr_sources = ARRAY_SIZE(clkset_aclk_top_list), | ||
| 262 | }; | ||
| 263 | |||
| 264 | static struct clksrc_clk clk_aclk_100 = { | 317 | static 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 | ||
| 274 | static struct clksrc_sources clkset_aclk_160 = { | ||
| 275 | .sources = clkset_aclk_top_list, | ||
| 276 | .nr_sources = ARRAY_SIZE(clkset_aclk_top_list), | ||
| 277 | }; | ||
| 278 | |||
| 279 | static struct clksrc_clk clk_aclk_160 = { | 327 | static 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 | ||
| 289 | static struct clksrc_sources clkset_aclk_133 = { | ||
| 290 | .sources = clkset_aclk_top_list, | ||
| 291 | .nr_sources = ARRAY_SIZE(clkset_aclk_top_list), | ||
| 292 | }; | ||
| 293 | |||
| 294 | static struct clksrc_clk clk_aclk_133 = { | 337 | static 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 | ||
| 352 | static struct clk init_clocks[] = { | 565 | static 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 | ||
| 616 | static struct clk *clkset_mout_g2d0_list[] = { | ||
| 617 | [0] = &clk_mout_mpll.clk, | ||
| 618 | [1] = &clk_sclk_apll.clk, | ||
| 619 | }; | ||
| 620 | |||
| 621 | static struct clksrc_sources clkset_mout_g2d0 = { | ||
| 622 | .sources = clkset_mout_g2d0_list, | ||
| 623 | .nr_sources = ARRAY_SIZE(clkset_mout_g2d0_list), | ||
| 624 | }; | ||
| 625 | |||
| 626 | static 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 | |||
| 635 | static struct clk *clkset_mout_g2d1_list[] = { | ||
| 636 | [0] = &clk_mout_epll.clk, | ||
| 637 | [1] = &clk_sclk_vpll.clk, | ||
| 638 | }; | ||
| 639 | |||
| 640 | static struct clksrc_sources clkset_mout_g2d1 = { | ||
| 641 | .sources = clkset_mout_g2d1_list, | ||
| 642 | .nr_sources = ARRAY_SIZE(clkset_mout_g2d1_list), | ||
| 643 | }; | ||
| 644 | |||
| 645 | static 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 | |||
| 654 | static struct clk *clkset_mout_g2d_list[] = { | ||
| 655 | [0] = &clk_mout_g2d0.clk, | ||
| 656 | [1] = &clk_mout_g2d1.clk, | ||
| 657 | }; | ||
| 658 | |||
| 659 | static struct clksrc_sources clkset_mout_g2d = { | ||
| 660 | .sources = clkset_mout_g2d_list, | ||
| 661 | .nr_sources = ARRAY_SIZE(clkset_mout_g2d_list), | ||
| 662 | }; | ||
| 663 | |||
| 664 | static 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 | |||
| 674 | static 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 | |||
| 684 | static 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 | |||
| 694 | static 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 | |||
| 704 | static 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 | |||
| 400 | static struct clksrc_clk clksrcs[] = { | 714 | static 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 | ||
| 483 | void __init_or_cpufreq s5pv310_setup_clocks(void) | 993 | void __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) | |||
| 83 | void __init s5pv310_map_io(void) | 100 | void __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 | ||
| 88 | void __init s5pv310_init_clocks(int xtal) | 111 | void __init s5pv310_init_clocks(int xtal) |
| @@ -131,6 +154,28 @@ static int __init s5pv310_core_init(void) | |||
| 131 | 154 | ||
| 132 | core_initcall(s5pv310_core_init); | 155 | core_initcall(s5pv310_core_init); |
| 133 | 156 | ||
| 157 | #ifdef CONFIG_CACHE_L2X0 | ||
| 158 | static 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 | |||
| 176 | early_initcall(s5pv310_l2x0_cache_init); | ||
| 177 | #endif | ||
| 178 | |||
| 134 | int __init s5pv310_init(void) | 179 | int __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 | |||
| 24 | static 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 | |||
| 30 | static 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 | */ | ||
| 46 | static 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 | |||
| 146 | static 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 | |||
| 244 | static 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 | |||
| 254 | static __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 | } | ||
| 304 | core_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 | |||
| 20 | extern volatile int pen_release; | ||
| 21 | |||
| 22 | static DECLARE_COMPLETION(cpu_killed); | ||
| 23 | |||
| 24 | static 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 | |||
| 46 | static 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 | |||
| 62 | static 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 | |||
| 99 | int 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 | */ | ||
| 109 | void 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 | |||
| 137 | int 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 | |||
| 26 | static DEFINE_SPINLOCK(eint_lock); | ||
| 27 | |||
| 28 | static unsigned int eint0_15_data[16]; | ||
| 29 | |||
| 30 | static 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 | |||
| 51 | static 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 | |||
| 62 | static 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 | |||
| 73 | static 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 | |||
| 78 | static void s5pv310_irq_eint_maskack(unsigned int irq) | ||
| 79 | { | ||
| 80 | s5pv310_irq_eint_mask(irq); | ||
| 81 | s5pv310_irq_eint_ack(irq); | ||
| 82 | } | ||
| 83 | |||
| 84 | static 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 | |||
| 147 | static 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 | */ | ||
| 167 | static 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 | |||
| 184 | static 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 | |||
| 190 | static 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 | |||
| 205 | int __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 | |||
| 228 | arch_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 | |||
| 44 | static 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 | |||
| 75 | static 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 | |||
| 86 | static 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 | |||
| 93 | static 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 | |||
| 104 | static 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 | |||
| 111 | static 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 | |||
| 124 | static 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 | |||
| 132 | static 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 | |||
| 142 | static 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 | |||
| 152 | static 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 | |||
| 176 | static 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 | |||
| 183 | static 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 | |||
| 195 | MACHINE_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, | ||
| 202 | MACHINE_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 | ||
| 75 | static 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 | |||
| 86 | static 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 | |||
| 93 | static 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 | |||
| 104 | static 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 | |||
| 111 | static 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 | |||
| 124 | static 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 | |||
| 132 | static 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 | |||
| 142 | static 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 | |||
| 152 | static 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 | |||
| 68 | static void __init smdkv310_map_io(void) | 176 | static 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 | ||
| 75 | static void __init smdkv310_machine_init(void) | 183 | static 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 | ||
| 82 | MACHINE_START(SMDKV310, "SMDKV310") | 195 | MACHINE_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 | ||
| 68 | static 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 | |||
| 107 | static 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 | |||
| 112 | static struct platform_device universal_gpio_keys = { | ||
| 113 | .name = "gpio-keys", | ||
| 114 | .dev = { | ||
| 115 | .platform_data = &universal_gpio_keys_data, | ||
| 116 | }, | ||
| 117 | }; | ||
| 118 | |||
| 119 | /* I2C0 */ | ||
| 120 | static struct i2c_board_info i2c0_devs[] __initdata = { | ||
| 121 | /* Camera, To be updated */ | ||
| 122 | }; | ||
| 123 | |||
| 124 | /* I2C1 */ | ||
| 125 | static struct i2c_board_info i2c1_devs[] __initdata = { | ||
| 126 | /* Gyro, To be updated */ | ||
| 127 | }; | ||
| 128 | |||
| 129 | static struct platform_device *universal_devices[] __initdata = { | ||
| 130 | &universal_gpio_keys, | ||
| 131 | &s5p_device_onenand, | ||
| 132 | }; | ||
| 133 | |||
| 63 | static void __init universal_map_io(void) | 134 | static 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 | ||
| 70 | static void __init universal_machine_init(void) | 141 | static 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 | ||
| 77 | MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") | 150 | MACHINE_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 | ||
| 22 | void s3c_i2c0_cfg_gpio(struct platform_device *dev) | 22 | void 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 | ||
| 19 | void s3c_i2c1_cfg_gpio(struct platform_device *dev) | 19 | void 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 | ||
| 19 | void s3c_i2c2_cfg_gpio(struct platform_device *dev) | 19 | void 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 | |||
| 13 | struct 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 | |||
| 19 | void 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 | |||
| 13 | struct 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 | |||
| 19 | void 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 | |||
| 13 | struct 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 | |||
| 19 | void 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 | |||
| 13 | struct 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 | |||
| 19 | void 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 | |||
| 13 | struct 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 | |||
| 19 | void 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 | |||
| 26 | void 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 | |||
| 64 | void 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 | |||
| 90 | void 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 | |||
| 128 | void 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 | |||
| 26 | char *s5pv310_hsmmc_clksrcs[4] = { | ||
| 27 | [0] = NULL, | ||
| 28 | [1] = NULL, | ||
| 29 | [2] = "sclk_mmc", /* mmc_bus */ | ||
| 30 | [3] = NULL, | ||
| 31 | }; | ||
| 32 | |||
| 33 | void 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 */ |
| 251 | static struct resource sh_mmcif_resources[] = { | 254 | static 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 | ||
| 396 | const 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 | |||
| 393 | static struct sh_mobile_lcdc_info lcdc_info = { | 424 | static 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 | ||
| 536 | static 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 | |||
| 546 | static struct clk_ops fsiackcr_clk_ops = { | ||
| 547 | .init = fsiackcr_init, | ||
| 548 | }; | ||
| 549 | |||
| 550 | static struct clk fsiackcr_clk = { | ||
| 551 | .ops = &fsiackcr_clk_ops, | ||
| 552 | .enable_reg = (void __iomem *)FSIACKCR, | ||
| 553 | .rate = 0, /* unknown */ | ||
| 554 | }; | ||
| 555 | |||
| 556 | static struct sh_fsi_platform_info fsi_info = { | 568 | static 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 | ||
| 699 | static struct i2c_board_info imx074_info = { | ||
| 700 | I2C_BOARD_INFO("imx074", 0x1a), | ||
| 701 | }; | ||
| 702 | |||
| 703 | struct 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 | |||
| 710 | static struct platform_device ap4evb_camera = { | ||
| 711 | .name = "soc-camera-pdrv", | ||
| 712 | .id = 0, | ||
| 713 | .dev = { | ||
| 714 | .platform_data = &imx074_link, | ||
| 715 | }, | ||
| 716 | }; | ||
| 717 | |||
| 718 | static 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 | |||
| 727 | static 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 | |||
| 734 | static 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 | |||
| 747 | static 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 | |||
| 757 | static 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 | |||
| 762 | static 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 | |||
| 778 | static 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 | |||
| 707 | static struct platform_device *ap4evb_devices[] __initdata = { | 788 | static 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 | ||
| 721 | static int __init hdmi_init_pm_clock(void) | 805 | static 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 | ||
| 768 | device_initcall(hdmi_init_pm_clock); | 852 | device_initcall(hdmi_init_pm_clock); |
| 769 | 853 | ||
| 854 | #define FSIACK_DUMMY_RATE 48000 | ||
| 855 | static 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 | |||
| 888 | out: | ||
| 889 | clk_put(fsia_ick); | ||
| 890 | |||
| 891 | return ret; | ||
| 892 | } | ||
| 893 | device_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 | ||
| 786 | static 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 */ |
| 798 | static int ts_get_pendown_state(void) | 921 | static 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 | ||
| 822 | static int ts_init(void) | 938 | static 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 | ||
| 1122 | static struct sys_timer ap4evb_timer = { | 1226 | static 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 */ |
| 54 | struct clk dv_clki_clk = { | 54 | struct 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 */ |
| 89 | struct clk dv_clki_div2_clk = { | 89 | struct 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 = { | |||
| 150 | static struct clk *pllc2_parent[] = { | 150 | static 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 | ||
| 287 | struct clk pllc2_clk = { | 287 | struct 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 ) */ | ||
| 296 | struct clk sh7372_fsiack_clk = { | ||
| 297 | }; | ||
| 298 | |||
| 299 | struct clk sh7372_fsibck_clk = { | ||
| 300 | }; | ||
| 301 | |||
| 295 | static struct clk *main_clks[] = { | 302 | static 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 | ||
| 310 | static void div4_kick(struct clk *clk) | 319 | static void div4_kick(struct clk *clk) |
| @@ -357,7 +366,7 @@ static struct clk div4_clks[DIV4_NR] = { | |||
| 357 | }; | 366 | }; |
| 358 | 367 | ||
| 359 | enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO, | 368 | enum { 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 | ||
| 380 | enum { DIV6_HDMI, DIV6_REPARENT_NR }; | 387 | enum { 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 */ |
| 383 | static struct clk *hdmi_parent[] = { | 390 | static 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 | ||
| 397 | static 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 | |||
| 404 | static 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 | |||
| 390 | static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { | 411 | static 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 | ||
| 395 | enum { MSTP001, | 420 | enum { 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 | ||
| 449 | static struct clk_lookup lookups[] = { | 476 | static 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 | ||
| 537 | void __init sh7372_clock_init(void) | 569 | void __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 | ||
| 460 | extern struct clk dv_clki_clk; | 460 | extern struct clk sh7372_extal1_clk; |
| 461 | extern struct clk dv_clki_div2_clk; | 461 | extern struct clk sh7372_extal2_clk; |
| 462 | extern struct clk pllc2_clk; | 462 | extern struct clk sh7372_dv_clki_clk; |
| 463 | extern struct clk sh7372_dv_clki_div2_clk; | ||
| 464 | extern struct clk sh7372_pllc2_clk; | ||
| 465 | extern struct clk sh7372_fsiack_clk; | ||
| 466 | extern 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 | ||
| 412 | static struct intc_vect intcs_vectors[] = { | 426 | static 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 */ | ||
| 189 | static struct sh_timer_config tmu00_platform_data = { | ||
| 190 | .name = "TMU00", | ||
| 191 | .channel_offset = 0x4, | ||
| 192 | .timer_bit = 0, | ||
| 193 | .clockevent_rating = 200, | ||
| 194 | }; | ||
| 195 | |||
| 196 | static 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 | |||
| 209 | static 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 | |||
| 219 | static struct sh_timer_config tmu01_platform_data = { | ||
| 220 | .name = "TMU01", | ||
| 221 | .channel_offset = 0x10, | ||
| 222 | .timer_bit = 1, | ||
| 223 | .clocksource_rating = 200, | ||
| 224 | }; | ||
| 225 | |||
| 226 | static 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 | |||
| 239 | static 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 */ |
| 190 | static struct resource iic0_resources[] = { | 250 | static 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 | |||
| 593 | static 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 | ||
| 542 | void __init sh7372_add_early_devices(void) | 610 | void __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 |
| 75 | static 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 | |||
| 82 | static 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 | */ | ||
| 93 | static 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 | */ | ||
| 104 | static 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 | |||
| 74 | static int ux500_l2x0_init(void) | 115 | static 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 | } |
| 85 | early_initcall(ux500_l2x0_init); | 130 | early_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 | ||
| 782 | config 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 | |||
| 782 | config CACHE_TAUROS2 | 790 | config 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 | */ | ||
| 45 | ENTRY(fa_flush_icache_all) | ||
| 46 | mov r0, #0 | ||
| 47 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 48 | mov pc, lr | ||
| 49 | ENDPROC(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 |
| 235 | ENTRY(fa_cache_fns) | 246 | ENTRY(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 @@ | |||
| 28 | static void __iomem *l2x0_base; | 28 | static void __iomem *l2x0_base; |
| 29 | static DEFINE_SPINLOCK(l2x0_lock); | 29 | static DEFINE_SPINLOCK(l2x0_lock); |
| 30 | static uint32_t l2x0_way_mask; /* Bitmask of active ways */ | 30 | static uint32_t l2x0_way_mask; /* Bitmask of active ways */ |
| 31 | static uint32_t l2x0_size; | ||
| 31 | 32 | ||
| 32 | static inline void cache_wait(void __iomem *reg, unsigned long mask) | 33 | static 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 | ||
| 41 | static 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 | |||
| 39 | static inline void cache_sync(void) | 49 | static 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 | ||
| 106 | static inline void l2x0_inv_all(void) | 116 | static 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 | |||
| 128 | static 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 | |||
| 140 | static 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 | ||
| 255 | static 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 | |||
| 209 | void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) | 264 | void __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 | */ | ||
| 20 | ENTRY(v3_flush_icache_all) | ||
| 21 | mov pc, lr | ||
| 22 | ENDPROC(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 |
| 124 | ENTRY(v3_cache_fns) | 133 | ENTRY(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 | */ | ||
| 20 | ENTRY(v4_flush_icache_all) | ||
| 21 | mov pc, lr | ||
| 22 | ENDPROC(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 |
| 136 | ENTRY(v4_cache_fns) | 145 | ENTRY(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 | */ | ||
| 58 | ENTRY(v4wb_flush_icache_all) | ||
| 59 | mov r0, #0 | ||
| 60 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 61 | mov pc, lr | ||
| 62 | ENDPROC(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 |
| 246 | ENTRY(v4wb_cache_fns) | 257 | ENTRY(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 | */ | ||
| 48 | ENTRY(v4wt_flush_icache_all) | ||
| 49 | mov r0, #0 | ||
| 50 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 51 | mov pc, lr | ||
| 52 | ENDPROC(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 |
| 190 | ENTRY(v4wt_cache_fns) | 201 | ENTRY(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 | */ | ||
| 75 | static 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 | |||
| 84 | static inline void do_pte_unlock(spinlock_t *ptl) | ||
| 85 | { | ||
| 86 | spin_unlock(ptl); | ||
| 87 | } | ||
| 88 | #else /* !USE_SPLIT_PTLOCKS */ | ||
| 89 | static inline void do_pte_lock(spinlock_t *ptl) {} | ||
| 90 | static inline void do_pte_unlock(spinlock_t *ptl) {} | ||
| 91 | #endif /* USE_SPLIT_PTLOCKS */ | ||
| 92 | |||
| 69 | static int adjust_pte(struct vm_area_struct *vma, unsigned long address, | 93 | static 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 | ||
| 124 | static void __init find_limits(struct meminfo *mi, | 125 | static 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 | ||
| 150 | static void __init arm_bootmem_init(struct meminfo *mi, | 152 | static 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 | ||
| 194 | static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min, | 204 | static 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 | ||
| 276 | static 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 | |||
| 259 | void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) | 283 | void __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 | ||
| 293 | void __init bootmem_init(void) | 319 | void __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 | ||
| 439 | static 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) | |||
| 419 | void __init mem_init(void) | 494 | void __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 | } |
| 746 | early_param("vmalloc", early_vmalloc); | 745 | early_param("vmalloc", early_vmalloc); |
| 747 | 746 | ||
| 748 | phys_addr_t lowmem_end_addr; | 747 | static phys_addr_t lowmem_limit __initdata = 0; |
| 749 | 748 | ||
| 750 | static void __init sanity_check_meminfo(void) | 749 | static 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) | |||
| 852 | static inline void prepare_page_table(void) | 852 | static 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 | ||
| 990 | static 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 | |||
| 1002 | static void __init map_lowmem(void) | 998 | static 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 | ||
| 1016 | static 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 | */ | ||
| 128 | ENTRY(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 | ||
| 134 | ENDPROC(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) | |||
| 351 | ENDPROC(arm1020_dma_unmap_area) | 365 | ENDPROC(arm1020_dma_unmap_area) |
| 352 | 366 | ||
| 353 | ENTRY(arm1020_cache_fns) | 367 | ENTRY(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 | */ | ||
| 128 | ENTRY(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 | ||
| 134 | ENDPROC(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) | |||
| 337 | ENDPROC(arm1020e_dma_unmap_area) | 351 | ENDPROC(arm1020e_dma_unmap_area) |
| 338 | 352 | ||
| 339 | ENTRY(arm1020e_cache_fns) | 353 | ENTRY(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 | */ | ||
| 117 | ENTRY(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 | ||
| 123 | ENDPROC(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) | |||
| 326 | ENDPROC(arm1022_dma_unmap_area) | 340 | ENDPROC(arm1022_dma_unmap_area) |
| 327 | 341 | ||
| 328 | ENTRY(arm1022_cache_fns) | 342 | ENTRY(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 | */ | ||
| 117 | ENTRY(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 | ||
| 123 | ENDPROC(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) | |||
| 320 | ENDPROC(arm1026_dma_unmap_area) | 334 | ENDPROC(arm1026_dma_unmap_area) |
| 321 | 335 | ||
| 322 | ENTRY(arm1026_cache_fns) | 336 | ENTRY(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 | */ | ||
| 117 | ENTRY(arm920_flush_icache_all) | ||
| 118 | mov r0, #0 | ||
| 119 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 120 | mov pc, lr | ||
| 121 | ENDPROC(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) | |||
| 305 | ENDPROC(arm920_dma_unmap_area) | 316 | ENDPROC(arm920_dma_unmap_area) |
| 306 | 317 | ||
| 307 | ENTRY(arm920_cache_fns) | 318 | ENTRY(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 | */ | ||
| 119 | ENTRY(arm922_flush_icache_all) | ||
| 120 | mov r0, #0 | ||
| 121 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 122 | mov pc, lr | ||
| 123 | ENDPROC(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) | |||
| 307 | ENDPROC(arm922_dma_unmap_area) | 318 | ENDPROC(arm922_dma_unmap_area) |
| 308 | 319 | ||
| 309 | ENTRY(arm922_cache_fns) | 320 | ENTRY(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 | */ | ||
| 152 | ENTRY(arm925_flush_icache_all) | ||
| 153 | mov r0, #0 | ||
| 154 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 155 | mov pc, lr | ||
| 156 | ENDPROC(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) | |||
| 362 | ENDPROC(arm925_dma_unmap_area) | 373 | ENDPROC(arm925_dma_unmap_area) |
| 363 | 374 | ||
| 364 | ENTRY(arm925_cache_fns) | 375 | ENTRY(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 | */ | ||
| 118 | ENTRY(arm926_flush_icache_all) | ||
| 119 | mov r0, #0 | ||
| 120 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 121 | mov pc, lr | ||
| 122 | ENDPROC(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) | |||
| 325 | ENDPROC(arm926_dma_unmap_area) | 336 | ENDPROC(arm926_dma_unmap_area) |
| 326 | 337 | ||
| 327 | ENTRY(arm926_cache_fns) | 338 | ENTRY(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 | */ | ||
| 75 | ENTRY(arm940_flush_icache_all) | ||
| 76 | mov r0, #0 | ||
| 77 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 78 | mov pc, lr | ||
| 79 | ENDPROC(arm940_flush_icache_all) | ||
| 80 | |||
| 81 | /* | ||
| 71 | * flush_user_cache_all() | 82 | * flush_user_cache_all() |
| 72 | */ | 83 | */ |
| 73 | ENTRY(arm940_flush_user_cache_all) | 84 | ENTRY(arm940_flush_user_cache_all) |
| @@ -254,6 +265,7 @@ ENTRY(arm940_dma_unmap_area) | |||
| 254 | ENDPROC(arm940_dma_unmap_area) | 265 | ENDPROC(arm940_dma_unmap_area) |
| 255 | 266 | ||
| 256 | ENTRY(arm940_cache_fns) | 267 | ENTRY(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 | */ | ||
| 82 | ENTRY(arm946_flush_icache_all) | ||
| 83 | mov r0, #0 | ||
| 84 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 85 | mov pc, lr | ||
| 86 | ENDPROC(arm946_flush_icache_all) | ||
| 87 | |||
| 88 | /* | ||
| 78 | * flush_user_cache_all() | 89 | * flush_user_cache_all() |
| 79 | */ | 90 | */ |
| 80 | ENTRY(arm946_flush_user_cache_all) | 91 | ENTRY(arm946_flush_user_cache_all) |
| @@ -296,6 +307,7 @@ ENTRY(arm946_dma_unmap_area) | |||
| 296 | ENDPROC(arm946_dma_unmap_area) | 307 | ENDPROC(arm946_dma_unmap_area) |
| 297 | 308 | ||
| 298 | ENTRY(arm946_cache_fns) | 309 | ENTRY(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 | */ | ||
| 131 | ENTRY(feroceon_flush_icache_all) | ||
| 132 | mov r0, #0 | ||
| 133 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 134 | mov pc, lr | ||
| 135 | ENDPROC(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) | |||
| 401 | ENDPROC(feroceon_dma_unmap_area) | 412 | ENDPROC(feroceon_dma_unmap_area) |
| 402 | 413 | ||
| 403 | ENTRY(feroceon_cache_fns) | 414 | ENTRY(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 | ||
| 414 | ENTRY(feroceon_range_cache_fns) | 426 | ENTRY(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 | */ | ||
| 148 | ENTRY(xsc3_flush_icache_all) | ||
| 149 | mov r0, #0 | ||
| 150 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 151 | mov pc, lr | ||
| 152 | ENDPROC(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) | |||
| 325 | ENDPROC(xsc3_dma_unmap_area) | 336 | ENDPROC(xsc3_dma_unmap_area) |
| 326 | 337 | ||
| 327 | ENTRY(xsc3_cache_fns) | 338 | ENTRY(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 | */ | ||
| 188 | ENTRY(xscale_flush_icache_all) | ||
| 189 | mov r0, #0 | ||
| 190 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
| 191 | mov pc, lr | ||
| 192 | ENDPROC(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) | |||
| 397 | ENDPROC(xscale_dma_unmap_area) | 408 | ENDPROC(xscale_dma_unmap_area) |
| 398 | 409 | ||
| 399 | ENTRY(xscale_cache_fns) | 410 | ENTRY(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 | |||
| 18 | obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o | 18 | obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o |
| 19 | obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o | 19 | obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o |
| 20 | obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o | 20 | obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o |
| 21 | obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o | ||
| 21 | ifdef CONFIG_SND_IMX_SOC | 22 | ifdef CONFIG_SND_IMX_SOC |
| 22 | obj-y += ssi-fiq.o | 23 | obj-y += ssi-fiq.o |
| 23 | obj-y += ssi-fiq-ksym.o | 24 | obj-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 | |||
| 30 | struct cpu_op *(*get_cpu_op)(int *op); | ||
| 31 | |||
| 32 | static int cpu_freq_khz_min; | ||
| 33 | static int cpu_freq_khz_max; | ||
| 34 | |||
| 35 | static struct clk *cpu_clk; | ||
| 36 | static struct cpufreq_frequency_table *imx_freq_table; | ||
| 37 | |||
| 38 | static int cpu_op_nr; | ||
| 39 | static struct cpu_op *cpu_op_tbl; | ||
| 40 | |||
| 41 | static 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 | |||
| 59 | static 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 | |||
| 67 | static 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 | |||
| 75 | static 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 | |||
| 100 | static 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; | ||
| 164 | err: | ||
| 165 | kfree(imx_freq_table); | ||
| 166 | err1: | ||
| 167 | clk_put(cpu_clk); | ||
| 168 | return ret; | ||
| 169 | } | ||
| 170 | |||
| 171 | static 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 | |||
| 181 | static 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 | |||
| 191 | static int __devinit mxc_cpufreq_driver_init(void) | ||
| 192 | { | ||
| 193 | return cpufreq_register_driver(&mxc_driver); | ||
| 194 | } | ||
| 195 | |||
| 196 | static void mxc_cpufreq_driver_exit(void) | ||
| 197 | { | ||
| 198 | cpufreq_unregister_driver(&mxc_driver); | ||
| 199 | } | ||
| 200 | |||
| 201 | module_init(mxc_cpufreq_driver_init); | ||
| 202 | module_exit(mxc_cpufreq_driver_exit); | ||
| 203 | |||
| 204 | MODULE_AUTHOR("Freescale Semiconductor Inc. Yong Shen <yong.shen@linaro.org>"); | ||
| 205 | MODULE_DESCRIPTION("CPUfreq driver for i.MX"); | ||
| 206 | MODULE_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 | ||
| 8 | config IMX_HAVE_PLATFORM_FLEXCAN | 8 | config IMX_HAVE_PLATFORM_FLEXCAN |
| 9 | select HAVE_CAN_FLEXCAN | 9 | select HAVE_CAN_FLEXCAN if CAN |
| 10 | bool | 10 | bool |
| 11 | 11 | ||
| 12 | config IMX_HAVE_PLATFORM_GPIO_KEYS | ||
| 13 | bool | ||
| 14 | default y if ARCH_MX51 | ||
| 15 | |||
| 12 | config IMX_HAVE_PLATFORM_IMX_I2C | 16 | config 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 @@ | |||
| 1 | obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o | 1 | obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o |
| 2 | obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o | 2 | obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o |
| 3 | obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o | 3 | obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o |
| 4 | obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o | ||
| 4 | obj-y += platform-imx-dma.o | 5 | obj-y += platform-imx-dma.o |
| 5 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o | 6 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o |
| 6 | obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o | 7 | obj-$(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 | |||
| 22 | struct 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 | */ | ||
| 214 | static 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 | |||
| 204 | static struct irq_chip gpio_irq_chip = { | 235 | static 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 | ||
| 211 | static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, | 243 | static 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> | ||
| 33 | struct 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> |
| 33 | struct imx_imx_i2c_data { | 37 | struct 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 | |||
| 140 | struct cpu_op { | ||
| 141 | u32 cpu_rate; | ||
| 142 | }; | ||
| 143 | |||
| 144 | extern 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 | ||
| 77 | static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset) | ||
| 78 | { | ||
| 79 | return IRQ_EINT8 + offset; | ||
| 80 | } | ||
| 81 | |||
| 82 | static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = { | 77 | static 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 | ||
| 35 | config S5P_GPIO_INT | ||
| 36 | bool | ||
| 37 | help | ||
| 38 | Common code for the GPIO interrupts (other than external interrupts.) | ||
| 39 | |||
| 35 | config S5P_DEV_FIMC0 | 40 | config 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 | |||
| 18 | obj-y += clock.o | 18 | obj-y += clock.o |
| 19 | obj-y += irq.o | 19 | obj-y += irq.o |
| 20 | obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o | 20 | obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o |
| 21 | obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o | ||
| 22 | obj-$(CONFIG_PM) += pm.o | ||
| 23 | obj-$(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 */ | ||
| 92 | struct 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 */ |
| 100 | static struct clk *clk_src_apll_list[] = { | 94 | static 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 | ||
| 153 | int 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 | |||
| 166 | unsigned long s5p_epll_get_rate(struct clk *clk) | ||
| 167 | { | ||
| 168 | return clk->rate; | ||
| 169 | } | ||
| 170 | |||
| 159 | static struct clk *s5p_clks[] __initdata = { | 171 | static 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 | ||
| 44 | extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable); | 44 | extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable); |
| 45 | 45 | ||
| 46 | /* Common EPLL operations for S5P platform */ | ||
| 47 | extern int s5p_epll_enable(struct clk *clk, int enable); | ||
| 48 | extern 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 | |||
| 31 | static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR]; | ||
| 32 | |||
| 33 | static 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 | |||
| 47 | static 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 | |||
| 56 | static 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 | |||
| 70 | static 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 | |||
| 84 | static 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 | |||
| 98 | static void s5p_gpioint_mask_ack(unsigned int irq) | ||
| 99 | { | ||
| 100 | s5p_gpioint_mask(irq); | ||
| 101 | s5p_gpioint_ack(irq); | ||
| 102 | } | ||
| 103 | |||
| 104 | static 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 | |||
| 143 | struct 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 | |||
| 152 | static 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 | |||
| 182 | static __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 | |||
| 212 | int __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 | |||
| 37 | unsigned long s3c_irqwake_intallow = 0x00000006L; | ||
| 38 | unsigned long s3c_irqwake_eintallow = 0xffffffffL; | ||
| 39 | |||
| 40 | int 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 | |||
| 59 | static 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 | |||
| 80 | int 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 | |||
| 87 | int 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 | |||
| 28 | static 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 | |||
| 38 | void s3c_pm_configure_extint(void) | ||
| 39 | { | ||
| 40 | /* nothing here yet */ | ||
| 41 | } | ||
| 42 | |||
| 43 | void s3c_pm_restore_core(void) | ||
| 44 | { | ||
| 45 | /* nothing here yet */ | ||
| 46 | } | ||
| 47 | |||
| 48 | void 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 | ||
| 183 | config S3C_DEV_I2C3 | ||
| 184 | bool | ||
| 185 | help | ||
| 186 | Compile in platform device definition for I2C controller 3 | ||
| 187 | |||
| 188 | config S3C_DEV_I2C4 | ||
| 189 | bool | ||
| 190 | help | ||
| 191 | Compile in platform device definition for I2C controller 4 | ||
| 192 | |||
| 193 | config S3C_DEV_I2C5 | ||
| 194 | bool | ||
| 195 | help | ||
| 196 | Compile in platform device definition for I2C controller 5 | ||
| 197 | |||
| 198 | config S3C_DEV_I2C6 | ||
| 199 | bool | ||
| 200 | help | ||
| 201 | Compile in platform device definition for I2C controller 6 | ||
| 202 | |||
| 203 | config S3C_DEV_I2C7 | ||
| 204 | bool | ||
| 205 | help | ||
| 206 | Compile in platform device definition for I2C controller 7 | ||
| 207 | |||
| 183 | config S3C_DEV_FB | 208 | config 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 | |||
| 40 | obj-y += dev-i2c0.o | 40 | obj-y += dev-i2c0.o |
| 41 | obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o | 41 | obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o |
| 42 | obj-$(CONFIG_S3C_DEV_I2C2) += dev-i2c2.o | 42 | obj-$(CONFIG_S3C_DEV_I2C2) += dev-i2c2.o |
| 43 | obj-$(CONFIG_S3C_DEV_I2C3) += dev-i2c3.o | ||
| 44 | obj-$(CONFIG_S3C_DEV_I2C4) += dev-i2c4.o | ||
| 45 | obj-$(CONFIG_S3C_DEV_I2C5) += dev-i2c5.o | ||
| 46 | obj-$(CONFIG_S3C_DEV_I2C6) += dev-i2c6.o | ||
| 47 | obj-$(CONFIG_S3C_DEV_I2C7) += dev-i2c7.o | ||
| 43 | obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o | 48 | obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o |
| 44 | obj-y += dev-uart.o | 49 | obj-y += dev-uart.o |
| 45 | obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o | 50 | obj-$(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 | ||
| 46 | struct platform_device s3c_device_hsmmc0 = { | 47 | struct 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 | ||
| 46 | struct platform_device s3c_device_hsmmc1 = { | 47 | struct 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 | ||
| 47 | struct platform_device s3c_device_hsmmc2 = { | 48 | struct 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 | ||
| 50 | struct platform_device s3c_device_hsmmc3 = { | 51 | struct 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 | |||
| 26 | static 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 | |||
| 39 | struct 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 | |||
| 46 | static 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 | |||
| 54 | void __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 | |||
| 26 | static 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 | |||
| 39 | struct 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 | |||
| 46 | static 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 | |||
| 54 | void __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 | |||
| 26 | static 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 | |||
| 39 | struct 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 | |||
| 46 | static 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 | |||
| 54 | void __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 | |||
| 26 | static 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 | |||
| 39 | struct 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 | |||
| 46 | static 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 | |||
| 54 | void __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 | |||
| 26 | static 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 | |||
| 39 | struct 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 | |||
| 46 | static 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 | |||
| 54 | void __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 | } |
| 42 | EXPORT_SYMBOL(s3c_gpio_cfgpin); | 42 | EXPORT_SYMBOL(s3c_gpio_cfgpin); |
| 43 | 43 | ||
| 44 | int 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 | } | ||
| 57 | EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range); | ||
| 58 | |||
| 59 | int 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 | } | ||
| 73 | EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range); | ||
| 74 | |||
| 44 | unsigned s3c_gpio_getcfg(unsigned int pin) | 75 | unsigned 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 | } |
| 81 | EXPORT_SYMBOL(s3c_gpio_setpull); | 112 | EXPORT_SYMBOL(s3c_gpio_setpull); |
| 82 | 113 | ||
| 114 | s3c_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 | } | ||
| 131 | EXPORT_SYMBOL(s3c_gpio_getpull); | ||
| 132 | |||
| 83 | #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX | 133 | #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX |
| 84 | int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, | 134 | int 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 | |||
| 161 | int 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 |
| 17 | extern void s3c64xx_ac97_setup_gpio(int); | 17 | extern 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 | ||
| 26 | extern 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; | |||
| 48 | extern struct platform_device s3c_device_i2c0; | 48 | extern struct platform_device s3c_device_i2c0; |
| 49 | extern struct platform_device s3c_device_i2c1; | 49 | extern struct platform_device s3c_device_i2c1; |
| 50 | extern struct platform_device s3c_device_i2c2; | 50 | extern struct platform_device s3c_device_i2c2; |
| 51 | extern struct platform_device s3c_device_i2c3; | ||
| 52 | extern struct platform_device s3c_device_i2c4; | ||
| 53 | extern struct platform_device s3c_device_i2c5; | ||
| 54 | extern struct platform_device s3c_device_i2c6; | ||
| 55 | extern struct platform_device s3c_device_i2c7; | ||
| 51 | extern struct platform_device s3c_device_rtc; | 56 | extern struct platform_device s3c_device_rtc; |
| 52 | extern struct platform_device s3c_device_adc; | 57 | extern struct platform_device s3c_device_adc; |
| 53 | extern struct platform_device s3c_device_sdi; | 58 | extern struct platform_device s3c_device_sdi; |
| @@ -89,6 +94,7 @@ extern struct platform_device s5pv210_device_pcm2; | |||
| 89 | extern struct platform_device s5pv210_device_iis0; | 94 | extern struct platform_device s5pv210_device_iis0; |
| 90 | extern struct platform_device s5pv210_device_iis1; | 95 | extern struct platform_device s5pv210_device_iis1; |
| 91 | extern struct platform_device s5pv210_device_iis2; | 96 | extern struct platform_device s5pv210_device_iis2; |
| 97 | extern struct platform_device s5pv210_device_spdif; | ||
| 92 | 98 | ||
| 93 | extern struct platform_device s5p6442_device_pcm0; | 99 | extern struct platform_device s5p6442_device_pcm0; |
| 94 | extern struct platform_device s5p6442_device_pcm1; | 100 | extern struct platform_device s5p6442_device_pcm1; |
| @@ -108,6 +114,7 @@ extern struct platform_device s5pc100_device_pcm1; | |||
| 108 | extern struct platform_device s5pc100_device_iis0; | 114 | extern struct platform_device s5pc100_device_iis0; |
| 109 | extern struct platform_device s5pc100_device_iis1; | 115 | extern struct platform_device s5pc100_device_iis1; |
| 110 | extern struct platform_device s5pc100_device_iis2; | 116 | extern struct platform_device s5pc100_device_iis2; |
| 117 | extern struct platform_device s5pc100_device_spdif; | ||
| 111 | 118 | ||
| 112 | extern struct platform_device samsung_device_keypad; | 119 | extern 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 | ||
| 45 | static 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 | */ |
| 109 | extern unsigned s3c_gpio_getcfg(unsigned int pin); | 109 | extern 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 | */ | ||
| 121 | extern 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 | */ |
| 141 | extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); | 154 | extern 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 | */ | ||
| 172 | extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, | ||
| 173 | unsigned int cfg, s3c_gpio_pull_t pull); | ||
| 174 | |||
| 175 | static 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 | */ |
| 170 | extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr); | 208 | extern 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 | */ | ||
| 226 | extern 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, | |||
| 118 | extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip); | 122 | extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip); |
| 119 | extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip); | 123 | extern 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 | */ | ||
| 134 | extern 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 */ |
| 122 | extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default; | 137 | extern 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 { | |||
| 55 | extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c); | 55 | extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c); |
| 56 | extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c); | 56 | extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c); |
| 57 | extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c); | 57 | extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c); |
| 58 | extern void s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
| 59 | extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
| 60 | extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
| 61 | extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c); | ||
| 62 | extern 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 */ |
| 60 | extern void s3c_i2c0_cfg_gpio(struct platform_device *dev); | 65 | extern void s3c_i2c0_cfg_gpio(struct platform_device *dev); |
| 61 | extern void s3c_i2c1_cfg_gpio(struct platform_device *dev); | 66 | extern void s3c_i2c1_cfg_gpio(struct platform_device *dev); |
| 62 | extern void s3c_i2c2_cfg_gpio(struct platform_device *dev); | 67 | extern void s3c_i2c2_cfg_gpio(struct platform_device *dev); |
| 68 | extern void s3c_i2c3_cfg_gpio(struct platform_device *dev); | ||
| 69 | extern void s3c_i2c4_cfg_gpio(struct platform_device *dev); | ||
| 70 | extern void s3c_i2c5_cfg_gpio(struct platform_device *dev); | ||
| 71 | extern void s3c_i2c6_cfg_gpio(struct platform_device *dev); | ||
| 72 | extern 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. */ | ||
| 21 | static 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 | ||
| 31 | enum 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); | |||
| 110 | extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w); | 117 | extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w); |
| 111 | extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w); | 118 | extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w); |
| 112 | extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w); | 119 | extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w); |
| 120 | extern void s5pv310_setup_sdhci0_cfg_gpio(struct platform_device *, int w); | ||
| 121 | extern void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *, int w); | ||
| 122 | extern void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *, int w); | ||
| 123 | extern 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 | ||
| 304 | extern char *s5pv310_hsmmc_clksrcs[4]; | ||
| 305 | |||
| 306 | extern 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 | |||
| 311 | static 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 | |||
| 320 | static 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 | |||
| 329 | static 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 | |||
| 338 | static 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 | ||
| 348 | static inline void s5pv310_default_sdhci0(void) { } | ||
| 349 | static inline void s5pv310_default_sdhci1(void) { } | ||
| 350 | static inline void s5pv310_default_sdhci2(void) { } | ||
| 351 | static 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) |
| 196 | static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip) | 196 | static 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 | */ |
| 31 | struct s3c_pl330_dmac { | 34 | struct 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 | ||
| 1136 | probe_err8: | ||
| 1137 | pl330_del(pl330_info); | ||
| 1123 | probe_err7: | 1138 | probe_err7: |
| 1124 | kfree(s3c_pl330_dmac); | 1139 | clk_disable(s3c_pl330_dmac->clk); |
| 1140 | clk_put(s3c_pl330_dmac->clk); | ||
| 1125 | probe_err6: | 1141 | probe_err6: |
| 1126 | pl330_del(pl330_info); | 1142 | kfree(s3c_pl330_dmac); |
| 1127 | probe_err5: | 1143 | probe_err5: |
| 1128 | free_irq(irq, pl330_info); | 1144 | free_irq(irq, pl330_info); |
| 1129 | probe_err4: | 1145 | probe_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 | ||
| 179 | const 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 | |||
| 179 | static struct sh_mobile_lcdc_info lcdc_info = { | 194 | static 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 */ |
| 234 | const 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 | |||
| 249 | const 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 | |||
| 234 | static struct sh_mobile_lcdc_info lcdc_info = { | 264 | static 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 | ||
| 129 | const 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 | |||
| 129 | static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = { | 144 | static 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 | ||
| 216 | const 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 | |||
| 216 | static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = { | 241 | static 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 */ |
| 147 | const 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 | |||
| 162 | const 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 | |||
| 147 | static struct sh_mobile_lcdc_info lcdc_info = { | 177 | static 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 | ||
| 207 | struct sh_hdmi { | 209 | struct 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 | ||
| 217 | static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg) | 222 | static 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 */ |
| 280 | static void hdmi_external_video_param(struct sh_hdmi *hdmi) | 285 | static 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 | */ |
| 459 | static void sh_hdmi_phy_config(struct sh_hdmi *hdmi) | 467 | static 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 | */ |
| 477 | static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi) | 525 | static 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 | */ | ||
| 597 | static 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 | */ | ||
| 620 | static 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 | */ | ||
| 643 | static 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 | */ | ||
| 667 | static 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 | */ |
| 691 | static void sh_hdmi_configure(struct sh_hdmi *hdmi) | 653 | static 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 | ||
| 737 | static void sh_hdmi_read_edid(struct sh_hdmi *hdmi) | 687 | static 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 | |||
| 707 | static 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 | ||
| 787 | static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id) | 830 | static 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 | ||
| 860 | static void hdmi_display_on(void *arg, struct fb_info *info) | 903 | /* locking: called with info->lock held, or before register_framebuffer() */ |
| 904 | static 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 | ||
| 890 | static void hdmi_display_off(void *arg) | 939 | /* locking: called with info->lock held */ |
| 940 | static 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 | ||
| 950 | static 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 | */ | ||
| 981 | static 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 */ |
| 901 | static void edid_work_fn(struct work_struct *work) | 1011 | static 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); | 1084 | out: |
| 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 | |||
| 1092 | static int sh_hdmi_notify(struct notifier_block *nb, | ||
| 1093 | unsigned long action, void *data); | ||
| 1094 | |||
| 1095 | static struct notifier_block sh_hdmi_notifier = { | ||
| 1096 | .notifier_call = sh_hdmi_notify, | ||
| 1097 | }; | ||
| 1098 | |||
| 1099 | static 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 | ||
| 950 | static int __init sh_hdmi_probe(struct platform_device *pdev) | 1137 | static 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 | ||
| 1222 | ecodec: | ||
| 1223 | free_irq(irq, hdmi); | ||
| 1046 | ereqirq: | 1224 | ereqirq: |
| 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)); |
| 1051 | ereqreg: | 1229 | ereqreg: |
| 1052 | clk_disable(hdmi->hdmi_clk); | 1230 | clk_disable(hdmi->hdmi_clk); |
| 1053 | eclkenable: | ||
| 1054 | erate: | 1231 | erate: |
| 1055 | clk_put(hdmi->hdmi_clk); | 1232 | clk_put(hdmi->hdmi_clk); |
| 1056 | egetclk: | 1233 | egetclk: |
| 1057 | snd_soc_unregister_codec(&pdev->dev); | 1234 | mutex_destroy(&hdmi->mutex); |
| 1058 | esndreg: | ||
| 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 |
| 57 | enum { 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 | ||
| 62 | static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { | 60 | static 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 | ||
| 115 | struct sh_mobile_lcdc_priv; | 113 | static const struct fb_videomode default_720p = { |
| 116 | struct 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 | ||
| 134 | struct sh_mobile_lcdc_priv { | 130 | struct sh_mobile_lcdc_priv { |
| @@ -409,8 +405,8 @@ static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv, | |||
| 409 | 405 | ||
| 410 | static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) | 406 | static 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) | |||
| 460 | static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | 458 | static 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 | ||
| 840 | static 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 | */ | ||
| 878 | static 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 | |||
| 899 | static 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 | |||
| 912 | static 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 | ||
| 841 | static struct fb_ops sh_mobile_lcdc_ops = { | 937 | static 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 | ||
| 853 | static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) | 952 | static 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 */ | ||
| 961 | static int sh_mobile_lcdc_notify(struct notifier_block *nb, | 1061 | static 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 | ||
| 1017 | static int sh_mobile_lcdc_remove(struct platform_device *pdev); | 1104 | static 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 */ | ||
| 10 | enum { 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 | |||
| 17 | struct sh_mobile_lcdc_priv; | ||
| 18 | struct fb_info; | ||
| 19 | |||
| 20 | struct 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 | ||
| 52 | struct module; | ||
| 52 | struct sh_mobile_lcdc_board_cfg { | 53 | struct 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 */ |
