Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'devel-stable' into devel

+8458 -1985
+12
arch/arm/Kconfig
··· 727 727 config ARCH_S5PV210 728 728 bool "Samsung S5PV210/S5PC110" 729 729 select CPU_V7 730 + select ARCH_SPARSEMEM_ENABLE 730 731 select GENERIC_GPIO 731 732 select HAVE_CLK 732 733 select ARM_L1_CACHE_SHIFT_6 734 + select ARCH_HAS_CPUFREQ 733 735 select ARCH_USES_GETTIMEOFFSET 734 736 select HAVE_S3C2410_I2C 735 737 select HAVE_S3C_RTC ··· 742 740 config ARCH_S5PV310 743 741 bool "Samsung S5PV310/S5PC210" 744 742 select CPU_V7 743 + select ARCH_SPARSEMEM_ENABLE 745 744 select GENERIC_GPIO 746 745 select HAVE_CLK 747 746 select GENERIC_CLOCKEVENTS 747 + select HAVE_S3C_RTC 748 + select HAVE_S3C2410_I2C 749 + select HAVE_S3C2410_WATCHDOG 748 750 help 749 751 Samsung S5PV310 series based systems 750 752 ··· 1674 1668 if ARCH_HAS_CPUFREQ 1675 1669 1676 1670 source "drivers/cpufreq/Kconfig" 1671 + 1672 + config CPU_FREQ_IMX 1673 + tristate "CPUfreq driver for i.MX CPUs" 1674 + depends on ARCH_MXC && CPU_FREQ 1675 + help 1676 + This enables the CPUfreq driver for i.MX CPUs. 1677 1677 1678 1678 config CPU_FREQ_SA1100 1679 1679 bool
+1
arch/arm/configs/mx51_defconfig
··· 82 82 CONFIG_INPUT_FF_MEMLESS=m 83 83 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set 84 84 CONFIG_INPUT_EVDEV=y 85 + CONFIG_KEYBOARD_GPIO=y 85 86 CONFIG_INPUT_EVBUG=m 86 87 CONFIG_MOUSE_PS2=m 87 88 CONFIG_MOUSE_PS2_ELANTECH=y
+10 -3
arch/arm/include/asm/hardware/cache-l2x0.h
··· 21 21 #define __ASM_ARM_HARDWARE_L2X0_H 22 22 23 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 24 #define L2X0_CACHE_TYPE 0x004 28 25 #define L2X0_CTRL 0x100 29 26 #define L2X0_AUX_CTRL 0x104 ··· 50 53 #define L2X0_LINE_DATA 0xF10 51 54 #define L2X0_LINE_TAG 0xF30 52 55 #define L2X0_DEBUG_CTRL 0xF40 56 + #define L2X0_PREFETCH_CTRL 0xF60 57 + #define L2X0_POWER_CTRL 0xF80 58 + #define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1) 59 + #define L2X0_STNDBY_MODE_EN (1 << 0) 60 + 61 + /* Registers shifts and masks */ 62 + #define L2X0_CACHE_ID_PART_MASK (0xf << 6) 63 + #define L2X0_CACHE_ID_PART_L210 (1 << 6) 64 + #define L2X0_CACHE_ID_PART_L310 (3 << 6) 65 + #define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17) 53 66 54 67 #ifndef __ASSEMBLY__ 55 68 extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
+24
arch/arm/include/asm/outercache.h
··· 25 25 void (*inv_range)(unsigned long, unsigned long); 26 26 void (*clean_range)(unsigned long, unsigned long); 27 27 void (*flush_range)(unsigned long, unsigned long); 28 + void (*flush_all)(void); 29 + void (*inv_all)(void); 30 + void (*disable)(void); 28 31 #ifdef CONFIG_OUTER_CACHE_SYNC 29 32 void (*sync)(void); 30 33 #endif ··· 53 50 outer_cache.flush_range(start, end); 54 51 } 55 52 53 + static inline void outer_flush_all(void) 54 + { 55 + if (outer_cache.flush_all) 56 + outer_cache.flush_all(); 57 + } 58 + 59 + static inline void outer_inv_all(void) 60 + { 61 + if (outer_cache.inv_all) 62 + outer_cache.inv_all(); 63 + } 64 + 65 + static inline void outer_disable(void) 66 + { 67 + if (outer_cache.disable) 68 + outer_cache.disable(); 69 + } 70 + 56 71 #else 57 72 58 73 static inline void outer_inv_range(unsigned long start, unsigned long end) ··· 79 58 { } 80 59 static inline void outer_flush_range(unsigned long start, unsigned long end) 81 60 { } 61 + static inline void outer_flush_all(void) { } 62 + static inline void outer_inv_all(void) { } 63 + static inline void outer_disable(void) { } 82 64 83 65 #endif 84 66
+3
arch/arm/kernel/machine_kexec.c
··· 78 78 local_fiq_disable(); 79 79 setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/ 80 80 flush_cache_all(); 81 + outer_flush_all(); 82 + outer_disable(); 81 83 cpu_proc_fin(); 84 + outer_inv_all(); 82 85 flush_cache_all(); 83 86 cpu_reset(reboot_code_buffer_phys); 84 87 }
+38
arch/arm/mach-imx/mach-mx27_3ds.c
··· 23 23 #include <linux/platform_device.h> 24 24 #include <linux/gpio.h> 25 25 #include <linux/input/matrix_keypad.h> 26 + #include <linux/irq.h> 26 27 #include <asm/mach-types.h> 27 28 #include <asm/mach/arch.h> 28 29 #include <asm/mach/time.h> 29 30 #include <mach/hardware.h> 30 31 #include <mach/common.h> 31 32 #include <mach/iomux-mx27.h> 33 + #include <mach/mmc.h> 32 34 33 35 #include "devices-imx27.h" 34 36 #include "devices.h" 37 + 38 + #define SD1_EN_GPIO (GPIO_PORTB + 25) 35 39 36 40 static const int mx27pdk_pins[] __initconst = { 37 41 /* UART1 */ ··· 62 58 PD15_AOUT_FEC_COL, 63 59 PD16_AIN_FEC_TX_ER, 64 60 PF23_AIN_FEC_TX_EN, 61 + /* SDHC1 */ 62 + PE18_PF_SD1_D0, 63 + PE19_PF_SD1_D1, 64 + PE20_PF_SD1_D2, 65 + PE21_PF_SD1_D3, 66 + PE22_PF_SD1_CMD, 67 + PE23_PF_SD1_CLK, 68 + SD1_EN_GPIO | GPIO_GPIO | GPIO_OUT, 65 69 }; 66 70 67 71 static const struct imxuart_platform_data uart_pdata __initconst = { ··· 97 85 .keymap_size = ARRAY_SIZE(mx27_3ds_keymap), 98 86 }; 99 87 88 + static int mx27_3ds_sdhc1_init(struct device *dev, irq_handler_t detect_irq, 89 + void *data) 90 + { 91 + return request_irq(IRQ_GPIOB(26), detect_irq, IRQF_TRIGGER_FALLING | 92 + IRQF_TRIGGER_RISING, "sdhc1-card-detect", data); 93 + } 94 + 95 + static void mx27_3ds_sdhc1_exit(struct device *dev, void *data) 96 + { 97 + free_irq(IRQ_GPIOB(26), data); 98 + } 99 + 100 + static struct imxmmc_platform_data sdhc1_pdata = { 101 + .init = mx27_3ds_sdhc1_init, 102 + .exit = mx27_3ds_sdhc1_exit, 103 + }; 104 + 105 + static void mx27_3ds_sdhc1_enable_level_translator(void) 106 + { 107 + /* Turn on TXB0108 OE pin */ 108 + gpio_request(SD1_EN_GPIO, "sd1_enable"); 109 + gpio_direction_output(SD1_EN_GPIO, 1); 110 + } 111 + 100 112 static void __init mx27pdk_init(void) 101 113 { 102 114 mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins), 103 115 "mx27pdk"); 116 + mx27_3ds_sdhc1_enable_level_translator(); 104 117 imx27_add_imx_uart0(&uart_pdata); 105 118 imx27_add_fec(NULL); 106 119 mxc_register_device(&imx_kpp_device, &mx27_3ds_keymap_data); 120 + mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata); 107 121 } 108 122 109 123 static void __init mx27pdk_timer_init(void)
+1
arch/arm/mach-mx25/Kconfig
··· 6 6 bool "Support MX25PDK (3DS) Platform" 7 7 select IMX_HAVE_PLATFORM_IMX_UART 8 8 select IMX_HAVE_PLATFORM_MXC_NAND 9 + select IMX_HAVE_PLATFORM_ESDHC 9 10 10 11 config MACH_EUKREA_CPUIMX25 11 12 bool "Support Eukrea CPUIMX25 Platform"
+10
arch/arm/mach-mx25/mach-mx25_3ds.c
··· 96 96 MX25_PAD_KPP_COL1__KPP_COL1, 97 97 MX25_PAD_KPP_COL2__KPP_COL2, 98 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 109 static const struct fec_platform_data mx25_fec_pdata __initconst = { ··· 201 193 mx25pdk_fec_reset(); 202 194 imx25_add_fec(&mx25_fec_pdata); 203 195 mxc_register_device(&mx25_kpp_device, &mx25pdk_keymap_data); 196 + 197 + imx25_add_esdhc(0, NULL); 204 198 } 205 199 206 200 static void __init mx25pdk_timer_init(void)
+2
arch/arm/mach-mx3/Kconfig
··· 143 143 config MACH_MX35_3DS 144 144 bool "Support MX35PDK platform" 145 145 select ARCH_MX35 146 + select MXC_DEBUG_BOARD 146 147 select IMX_HAVE_PLATFORM_IMX_UART 147 148 select IMX_HAVE_PLATFORM_MXC_NAND 149 + select IMX_HAVE_PLATFORM_ESDHC 148 150 default n 149 151 help 150 152 Include support for MX35PDK platform. This includes specific
+8 -8
arch/arm/mach-mx3/devices.c
··· 72 72 #ifdef CONFIG_ARCH_MX31 73 73 static struct resource mxcsdhc0_resources[] = { 74 74 { 75 - .start = MMC_SDHC1_BASE_ADDR, 76 - .end = MMC_SDHC1_BASE_ADDR + SZ_16K - 1, 75 + .start = MX31_MMC_SDHC1_BASE_ADDR, 76 + .end = MX31_MMC_SDHC1_BASE_ADDR + SZ_16K - 1, 77 77 .flags = IORESOURCE_MEM, 78 78 }, { 79 - .start = MXC_INT_MMC_SDHC1, 80 - .end = MXC_INT_MMC_SDHC1, 79 + .start = MX31_INT_MMC_SDHC1, 80 + .end = MX31_INT_MMC_SDHC1, 81 81 .flags = IORESOURCE_IRQ, 82 82 }, 83 83 }; 84 84 85 85 static struct resource mxcsdhc1_resources[] = { 86 86 { 87 - .start = MMC_SDHC2_BASE_ADDR, 88 - .end = MMC_SDHC2_BASE_ADDR + SZ_16K - 1, 87 + .start = MX31_MMC_SDHC2_BASE_ADDR, 88 + .end = MX31_MMC_SDHC2_BASE_ADDR + SZ_16K - 1, 89 89 .flags = IORESOURCE_MEM, 90 90 }, { 91 - .start = MXC_INT_MMC_SDHC2, 92 - .end = MXC_INT_MMC_SDHC2, 91 + .start = MX31_INT_MMC_SDHC2, 92 + .end = MX31_INT_MMC_SDHC2, 93 93 .flags = IORESOURCE_IRQ, 94 94 }, 95 95 };
+4 -34
arch/arm/mach-mx3/mach-mx31_3ds.c
··· 38 38 #include "devices-imx31.h" 39 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 41 /* CPLD IRQ line for external uart, external ethernet etc */ 65 42 #define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1) 66 - 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 43 74 44 /* 75 45 * This file contains the board-specific initialization routines. ··· 242 272 imx31_add_imx_uart0(&uart_pdata); 243 273 imx31_add_mxc_nand(&mx31_3ds_nand_board_info); 244 274 245 - imx31_add_spi_imx0(&spi1_pdata); 275 + imx31_add_spi_imx1(&spi1_pdata); 246 276 spi_register_board_info(mx31_3ds_spi_devs, 247 277 ARRAY_SIZE(mx31_3ds_spi_devs)); 248 278 ··· 251 281 mx31_3ds_usbotg_init(); 252 282 mxc_register_device(&mxc_otg_udc_device, &usbotg_pdata); 253 283 254 - if (!mxc_expio_init(CS5_BASE_ADDR, EXPIO_PARENT_INT)) 255 - printk(KERN_WARNING "Init of the debugboard failed, all " 256 - "devices on the board are unusable.\n"); 284 + if (mxc_expio_init(MX31_CS5_BASE_ADDR, EXPIO_PARENT_INT)) 285 + printk(KERN_WARNING "Init of the debug board failed, all " 286 + "devices on the debug board are unusable.\n"); 257 287 } 258 288 259 289 static void __init mx31_3ds_timer_init(void)
+16
arch/arm/mach-mx3/mach-mx35_3ds.c
··· 38 38 #include <mach/hardware.h> 39 39 #include <mach/common.h> 40 40 #include <mach/iomux-mx35.h> 41 + #include <mach/irqs.h> 42 + #include <mach/3ds_debugboard.h> 41 43 #include <mach/mxc_ehci.h> 42 44 43 45 #include "devices-imx35.h" 44 46 #include "devices.h" 47 + 48 + #define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTA + 1) 45 49 46 50 static const struct imxuart_platform_data uart_pdata __initconst = { 47 51 .flags = IMXUART_HAVE_RTSCTS, ··· 112 108 /* USBH1 */ 113 109 MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR, 114 110 MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC, 111 + /* SDCARD */ 112 + MX35_PAD_SD1_CMD__ESDHC1_CMD, 113 + MX35_PAD_SD1_CLK__ESDHC1_CLK, 114 + MX35_PAD_SD1_DATA0__ESDHC1_DAT0, 115 + MX35_PAD_SD1_DATA1__ESDHC1_DAT1, 116 + MX35_PAD_SD1_DATA2__ESDHC1_DAT2, 117 + MX35_PAD_SD1_DATA3__ESDHC1_DAT3, 115 118 }; 116 119 117 120 /* OTG config */ ··· 151 140 mxc_register_device(&mxc_usbh1, &usb_host_pdata); 152 141 153 142 imx35_add_mxc_nand(&mx35pdk_nand_board_info); 143 + imx35_add_esdhc(0, NULL); 144 + 145 + if (mxc_expio_init(MX35_CS5_BASE_ADDR, EXPIO_PARENT_INT)) 146 + pr_warn("Init of the debugboard failed, all " 147 + "devices on the debugboard are unusable.\n"); 154 148 } 155 149 156 150 static void __init mx35pdk_timer_init(void)
+2
arch/arm/mach-mx5/Kconfig
··· 6 6 select MXC_TZIC 7 7 select ARCH_MXC_IOMUX_V3 8 8 select ARCH_MXC_AUDMUX_V2 9 + select ARCH_HAS_CPUFREQ 9 10 10 11 comment "MX5 platforms:" 11 12 ··· 14 13 bool "Support MX51 BABBAGE platforms" 15 14 select IMX_HAVE_PLATFORM_IMX_I2C 16 15 select IMX_HAVE_PLATFORM_IMX_UART 16 + select IMX_HAVE_PLATFORM_ESDHC 17 17 help 18 18 Include support for MX51 Babbage platform, also known as MX51EVK in 19 19 u-boot. This includes specific configurations for the board and its
+1
arch/arm/mach-mx5/Makefile
··· 5 5 # Object file lists. 6 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 9 obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o 9 10 obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o 10 11 obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o
+48 -1
arch/arm/mach-mx5/board-mx51_babbage.c
··· 1 1 /* 2 - * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. 2 + * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved. 3 3 * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com> 4 4 * 5 5 * The code contained herein is licensed under the GNU General Public ··· 18 18 #include <linux/io.h> 19 19 #include <linux/fsl_devices.h> 20 20 #include <linux/fec.h> 21 + #include <linux/gpio_keys.h> 22 + #include <linux/input.h> 21 23 22 24 #include <mach/common.h> 23 25 #include <mach/hardware.h> ··· 34 32 35 33 #include "devices-imx51.h" 36 34 #include "devices.h" 35 + #include "cpu_op-mx51.h" 37 36 38 37 #define BABBAGE_USB_HUB_RESET (0*32 + 7) /* GPIO_1_7 */ 39 38 #define BABBAGE_USBH1_STP (0*32 + 27) /* GPIO_1_27 */ 40 39 #define BABBAGE_PHY_RESET (1*32 + 5) /* GPIO_2_5 */ 41 40 #define BABBAGE_FEC_PHY_RESET (1*32 + 14) /* GPIO_2_14 */ 41 + #define BABBAGE_POWER_KEY (1*32 + 21) /* GPIO_2_21 */ 42 42 43 43 /* USB_CTRL_1 */ 44 44 #define MX51_USB_CTRL_1_OFFSET 0x10 ··· 49 45 #define MX51_USB_PLLDIV_12_MHZ 0x00 50 46 #define MX51_USB_PLL_DIV_19_2_MHZ 0x01 51 47 #define MX51_USB_PLL_DIV_24_MHZ 0x02 48 + 49 + static struct gpio_keys_button babbage_buttons[] = { 50 + { 51 + .gpio = BABBAGE_POWER_KEY, 52 + .code = BTN_0, 53 + .desc = "PWR", 54 + .active_low = 1, 55 + .wakeup = 1, 56 + }, 57 + }; 58 + 59 + static const struct gpio_keys_platform_data imx_button_data __initconst = { 60 + .buttons = babbage_buttons, 61 + .nbuttons = ARRAY_SIZE(babbage_buttons), 62 + }; 52 63 53 64 static struct pad_desc mx51babbage_pads[] = { 54 65 /* UART1 */ ··· 131 112 132 113 /* FEC PHY reset line */ 133 114 MX51_PAD_EIM_A20__GPIO_2_14, 115 + 116 + /* SD 1 */ 117 + MX51_PAD_SD1_CMD__SD1_CMD, 118 + MX51_PAD_SD1_CLK__SD1_CLK, 119 + MX51_PAD_SD1_DATA0__SD1_DATA0, 120 + MX51_PAD_SD1_DATA1__SD1_DATA1, 121 + MX51_PAD_SD1_DATA2__SD1_DATA2, 122 + MX51_PAD_SD1_DATA3__SD1_DATA3, 123 + 124 + /* SD 2 */ 125 + MX51_PAD_SD2_CMD__SD2_CMD, 126 + MX51_PAD_SD2_CLK__SD2_CLK, 127 + MX51_PAD_SD2_DATA0__SD2_DATA0, 128 + MX51_PAD_SD2_DATA1__SD2_DATA1, 129 + MX51_PAD_SD2_DATA2__SD2_DATA2, 130 + MX51_PAD_SD2_DATA3__SD2_DATA3, 134 131 }; 135 132 136 133 /* Serial ports */ ··· 316 281 static void __init mxc_board_init(void) 317 282 { 318 283 struct pad_desc usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP; 284 + struct pad_desc power_key = MX51_PAD_EIM_A27__GPIO_2_21; 319 285 286 + #if defined(CONFIG_CPU_FREQ_IMX) 287 + get_cpu_op = mx51_get_cpu_op; 288 + #endif 320 289 mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads, 321 290 ARRAY_SIZE(mx51babbage_pads)); 322 291 mxc_init_imx_uart(); 323 292 babbage_fec_reset(); 324 293 imx51_add_fec(NULL); 294 + 295 + /* Set the PAD settings for the pwr key. */ 296 + power_key.pad_ctrl = MX51_GPIO_PAD_CTRL_2; 297 + mxc_iomux_v3_setup_pad(&power_key); 298 + imx51_add_gpio_keys(&imx_button_data); 325 299 326 300 imx51_add_imx_i2c(0, &babbage_i2c_data); 327 301 imx51_add_imx_i2c(1, &babbage_i2c_data); ··· 348 304 /* setback USBH1_STP to be function */ 349 305 mxc_iomux_v3_setup_pad(&usbh1stp); 350 306 babbage_usbhub_reset(); 307 + 308 + imx51_add_esdhc(0, NULL); 309 + imx51_add_esdhc(1, NULL); 351 310 } 352 311 353 312 static void __init mx51_babbage_timer_init(void)
+20 -2
arch/arm/mach-mx5/clock-mx51.c
··· 362 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 367 u32 cacrr, div; 368 368 unsigned long parent_rate; ··· 372 372 div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1; 373 373 374 374 return parent_rate / div; 375 + } 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; 375 391 } 376 392 377 393 static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent) ··· 752 736 753 737 static struct clk cpu_clk = { 754 738 .parent = &pll1_sw_clk, 755 - .get_rate = clk_arm_get_rate, 739 + .get_rate = clk_cpu_get_rate, 740 + .set_rate = clk_cpu_set_rate, 756 741 }; 757 742 758 743 static struct clk ahb_clk = { ··· 1081 1064 _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk) 1082 1065 _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) 1083 1066 _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk) 1067 + _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk) 1084 1068 }; 1085 1069 1086 1070 static void clk_tree_init(void)
+29
arch/arm/mach-mx5/cpu_op-mx51.c
··· 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 + }
+14
arch/arm/mach-mx5/cpu_op-mx51.h
··· 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);
+2
arch/arm/mach-mx5/devices-imx51.h
··· 13 13 #define imx51_add_fec(pdata) \ 14 14 imx_add_fec(&imx51_fec_data, pdata) 15 15 16 + #define imx51_add_gpio_keys(pdata) imx_add_gpio_keys(pdata) 17 + 16 18 extern const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst; 17 19 #define imx51_add_imx_i2c(id, pdata) \ 18 20 imx_add_imx_i2c(&imx51_imx_i2c_data[id], pdata)
+13
arch/arm/mach-omap2/omap4-common.c
··· 44 44 } 45 45 46 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 54 static int __init omap_l2_cache_init(void) 48 55 { 49 56 /* ··· 76 69 l2x0_init(l2cache_base, 0x0e050000, 0xc0000fff); 77 70 else 78 71 l2x0_init(l2cache_base, 0x0e070000, 0xc0000fff); 72 + 73 + /* 74 + * Override default outer_cache.disable with a OMAP4 75 + * specific one 76 + */ 77 + outer_cache.disable = omap4_l2x0_disable; 79 78 80 79 return 0; 81 80 }
+7 -3
arch/arm/mach-s3c2410/include/mach/gpio.h
··· 22 22 23 23 #ifdef CONFIG_CPU_S3C244X 24 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 27 #else 26 28 #define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA) 27 29 #endif ··· 32 30 #include <mach/gpio-nrs.h> 33 31 #include <mach/gpio-fns.h> 34 32 35 - #ifdef CONFIG_CPU_S3C24XX 36 - #define S3C_GPIO_END (S3C2410_GPIO_BANKJ + 32) 33 + #ifdef CONFIG_CPU_S3C244X 34 + #define S3C_GPIO_END (S3C2410_GPJ(0) + 32) 35 + #elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416) 36 + #define S3C_GPIO_END (S3C2410_GPM(0) + 32) 37 37 #else 38 - #define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32) 38 + #define S3C_GPIO_END (S3C2410_GPH(0) + 32) 39 39 #endif
+2
arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
··· 118 118 #define S3C2443_SCLKCON_UARTCLK (1<<8) 119 119 #define S3C2443_SCLKCON_USBHOST (1<<1) 120 120 121 + #define S3C2443_PWRCFG_SLEEP (1<<15) 122 + 121 123 #include <asm/div64.h> 122 124 123 125 static inline unsigned int
+1 -1
arch/arm/mach-s3c2410/include/mach/vmalloc.h
··· 15 15 #ifndef __ASM_ARCH_VMALLOC_H 16 16 #define __ASM_ARCH_VMALLOC_H 17 17 18 - #define VMALLOC_END 0xE0000000UL 18 + #define VMALLOC_END 0xF6000000UL 19 19 20 20 #endif /* __ASM_ARCH_VMALLOC_H */
+2 -1
arch/arm/mach-s3c2412/s3c2412.c
··· 51 51 #include <plat/clock.h> 52 52 #include <plat/pm.h> 53 53 #include <plat/pll.h> 54 + #include <plat/nand-core.h> 54 55 55 56 #ifndef CONFIG_CPU_S3C2412_ONLY 56 57 void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; ··· 93 92 /* rename devices that are s3c2412/s3c2413 specific */ 94 93 s3c_device_sdi.name = "s3c2412-sdi"; 95 94 s3c_device_lcd.name = "s3c2412-lcd"; 96 - s3c_device_nand.name = "s3c2412-nand"; 95 + s3c_nand_setname("s3c2412-nand"); 97 96 98 97 /* alter IRQ of SDI controller */ 99 98
+6
arch/arm/mach-s3c2416/Kconfig
··· 25 25 help 26 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 33 menu "S3C2416 Machines" 29 34 30 35 config MACH_SMDK2416 ··· 38 33 select S3C_DEV_FB 39 34 select S3C_DEV_HSMMC 40 35 select S3C_DEV_HSMMC1 36 + select S3C2416_PM if PM 41 37 help 42 38 Say Y here if you are using an SMDK2416 43 39
+1 -1
arch/arm/mach-s3c2416/Makefile
··· 11 11 12 12 obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o 13 13 obj-$(CONFIG_CPU_S3C2416) += irq.o 14 - 14 + obj-$(CONFIG_S3C2416_PM) += pm.o 15 15 #obj-$(CONFIG_S3C2416_DMA) += dma.o 16 16 17 17 # Machine support
+2
arch/arm/mach-s3c2416/irq.c
··· 243 243 244 244 static struct sysdev_driver s3c2416_irq_driver = { 245 245 .add = s3c2416_irq_add, 246 + .suspend = s3c24xx_irq_suspend, 247 + .resume = s3c24xx_irq_resume, 246 248 }; 247 249 248 250 static int __init s3c2416_irq_init(void)
+84
arch/arm/mach-s3c2416/pm.c
··· 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);
+2 -1
arch/arm/mach-s3c2416/s3c2416.c
··· 56 56 57 57 #include <plat/iic-core.h> 58 58 #include <plat/fb-core.h> 59 + #include <plat/nand-core.h> 59 60 60 61 static struct map_desc s3c2416_iodesc[] __initdata = { 61 62 IODESC_ENT(WATCHDOG), ··· 101 100 { 102 101 s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no); 103 102 104 - s3c_device_nand.name = "s3c2416-nand"; 103 + s3c_nand_setname("s3c2412-nand"); 105 104 } 106 105 107 106 /* s3c2416_map_io
+2 -1
arch/arm/mach-s3c2440/s3c244x.c
··· 44 44 #include <plat/cpu.h> 45 45 #include <plat/pm.h> 46 46 #include <plat/pll.h> 47 + #include <plat/nand-core.h> 47 48 48 49 static struct map_desc s3c244x_iodesc[] __initdata = { 49 50 IODESC_ENT(CLKPWR), ··· 69 68 70 69 s3c_device_sdi.name = "s3c2440-sdi"; 71 70 s3c_device_i2c0.name = "s3c2440-i2c"; 72 - s3c_device_nand.name = "s3c2440-nand"; 71 + s3c_nand_setname("s3c2440-nand"); 73 72 s3c_device_ts.name = "s3c2440-ts"; 74 73 s3c_device_usbgadget.name = "s3c2440-usbgadget"; 75 74 }
+2 -1
arch/arm/mach-s3c2443/s3c2443.c
··· 36 36 #include <plat/devs.h> 37 37 #include <plat/cpu.h> 38 38 #include <plat/fb-core.h> 39 + #include <plat/nand-core.h> 39 40 40 41 static struct map_desc s3c2443_iodesc[] __initdata = { 41 42 IODESC_ENT(WATCHDOG), ··· 63 62 64 63 s3c24xx_reset_hook = s3c2443_hard_reset; 65 64 66 - s3c_device_nand.name = "s3c2412-nand"; 65 + s3c_nand_setname("s3c2412-nand"); 67 66 s3c_fb_setname("s3c2443-fb"); 68 67 69 68 /* change WDT IRQ number */
+1 -1
arch/arm/mach-s3c24a0/include/mach/vmalloc.h
··· 12 12 #ifndef __ASM_ARCH_VMALLOC_H 13 13 #define __ASM_ARCH_VMALLOC_H 14 14 15 - #define VMALLOC_END (0xe0000000UL) 15 + #define VMALLOC_END 0xF6000000UL 16 16 17 17 #endif /* __ASM_ARCH_VMALLOC_H */
+21
arch/arm/mach-s3c64xx/Kconfig
··· 98 98 help 99 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 116 config MACH_REAL6410 102 117 bool "REAL6410" 103 118 select CPU_S3C6410 104 119 select S3C_DEV_HSMMC 105 120 select S3C_DEV_HSMMC1 106 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 128 help 108 129 Machine support for the CoreWind REAL6410 109 130
+1
arch/arm/mach-s3c64xx/Makefile
··· 53 53 obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o 54 54 obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o 55 55 obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o 56 + obj-$(CONFIG_MACH_MINI6410) += mach-mini6410.o 56 57 obj-$(CONFIG_MACH_NCP) += mach-ncp.o 57 58 obj-$(CONFIG_MACH_HMT) += mach-hmt.o 58 59 obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o
+17 -46
arch/arm/mach-s3c64xx/dev-audio.c
··· 22 22 #include <plat/audio.h> 23 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 25 static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) 31 26 { 27 + unsigned int base; 28 + 32 29 switch (pdev->id) { 33 30 case 0: 34 - s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); 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); 31 + base = S3C64XX_GPD(0); 39 32 break; 40 33 case 1: 41 - s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK); 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); 34 + base = S3C64XX_GPE(0); 46 35 break; 47 36 default: 48 37 printk(KERN_DEBUG "Invalid I2S Controller number: %d\n", ··· 39 50 return -EINVAL; 40 51 } 41 52 53 + s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3)); 54 + 42 55 return 0; 43 56 } 44 57 45 58 static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev) 46 59 { 47 - s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_I2S_V40_DO0); 48 - s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_I2S_V40_DO1); 49 - s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_I2S_V40_DO2); 50 - s3c_gpio_cfgpin(S3C64XX_GPH(6), S3C64XX_GPH6_I2S_V40_BCLK); 51 - s3c_gpio_cfgpin(S3C64XX_GPH(7), S3C64XX_GPH7_I2S_V40_CDCLK); 52 - s3c_gpio_cfgpin(S3C64XX_GPH(8), S3C64XX_GPH8_I2S_V40_LRCLK); 53 - s3c_gpio_cfgpin(S3C64XX_GPH(9), S3C64XX_GPH9_I2S_V40_DI); 60 + s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5)); 61 + s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5)); 62 + s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5)); 63 + s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5)); 54 64 55 65 return 0; 56 66 } ··· 158 170 159 171 static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev) 160 172 { 173 + unsigned int base; 174 + 161 175 switch (pdev->id) { 162 176 case 0: 163 - s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_PCM0_SCLK); 164 - s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_PCM0_EXTCLK); 165 - s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_PCM0_FSYNC); 166 - s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_PCM0_SIN); 167 - s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_PCM0_SOUT); 177 + base = S3C64XX_GPD(0); 168 178 break; 169 179 case 1: 170 - s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_PCM1_SCLK); 171 - s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_PCM1_EXTCLK); 172 - s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_PCM1_FSYNC); 173 - s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_PCM1_SIN); 174 - s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_PCM1_SOUT); 180 + base = S3C64XX_GPE(0); 175 181 break; 176 182 default: 177 183 printk(KERN_DEBUG "Invalid PCM Controller number: %d\n", ··· 173 191 return -EINVAL; 174 192 } 175 193 194 + s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2)); 176 195 return 0; 177 196 } 178 197 ··· 247 264 248 265 static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev) 249 266 { 250 - s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_AC97_BITCLK); 251 - s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_AC97_nRESET); 252 - s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_AC97_SYNC); 253 - s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_AC97_SDI); 254 - s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_AC97_SDO); 255 - 256 - return 0; 267 + return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4)); 257 268 } 258 269 259 270 static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev) 260 271 { 261 - s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_AC97_BITCLK); 262 - s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_AC97_nRESET); 263 - s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_AC97_SYNC); 264 - s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_AC97_SDI); 265 - s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_AC97_SDO); 266 - 267 - return 0; 272 + return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4)); 268 273 } 269 274 270 275 static struct resource s3c64xx_ac97_resource[] = {
+2 -6
arch/arm/mach-s3c64xx/gpiolib.c
··· 195 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 198 static struct s3c_gpio_chip gpio_2bit[] = { 204 199 { 205 200 .base = S3C64XX_GPF_BASE, ··· 222 227 }, 223 228 }, { 224 229 .base = S3C64XX_GPN_BASE, 230 + .irq_base = IRQ_EINT(0), 225 231 .config = &gpio_2bit_cfg_eint10, 226 232 .chip = { 227 233 .base = S3C64XX_GPN(0), 228 234 .ngpio = S3C64XX_GPIO_N_NR, 229 235 .label = "GPN", 230 - .to_irq = s3c64xx_gpio2int_gpn, 236 + .to_irq = samsung_gpiolib_to_irq, 231 237 }, 232 238 }, { 233 239 .base = S3C64XX_GPO_BASE,
+1 -1
arch/arm/mach-s3c64xx/include/mach/vmalloc.h
··· 15 15 #ifndef __ASM_ARCH_VMALLOC_H 16 16 #define __ASM_ARCH_VMALLOC_H 17 17 18 - #define VMALLOC_END 0xE0000000UL 18 + #define VMALLOC_END 0xF6000000UL 19 19 20 20 #endif /* __ASM_ARCH_VMALLOC_H */
+357
arch/arm/mach-s3c64xx/mach-mini6410.c
··· 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
+194 -6
arch/arm/mach-s3c64xx/mach-real6410.c
··· 12 12 * 13 13 */ 14 14 15 - #include <linux/kernel.h> 16 - #include <linux/types.h> 17 - #include <linux/interrupt.h> 18 - #include <linux/list.h> 19 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> 20 21 #include <linux/dm9000.h> 21 - #include <linux/serial_core.h> 22 + #include <linux/mtd/mtd.h> 23 + #include <linux/mtd/partitions.h> 22 24 #include <linux/platform_device.h> 25 + #include <linux/serial_core.h> 26 + #include <linux/types.h> 27 + 23 28 #include <asm/mach-types.h> 24 29 #include <asm/mach/arch.h> 25 30 #include <asm/mach/map.h> 31 + 26 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 36 #include <mach/regs-srom.h> 37 + #include <mach/s3c6410.h> 38 + 39 + #include <plat/adc.h> 29 40 #include <plat/cpu.h> 30 41 #include <plat/devs.h> 42 + #include <plat/fb.h> 43 + #include <plat/nand.h> 31 44 #include <plat/regs-serial.h> 45 + #include <plat/ts.h> 46 + 47 + #include <video/platform_lcd.h> 32 48 33 49 #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK) 34 50 #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) ··· 115 99 }, 116 100 }; 117 101 102 + static struct s3c_fb_pd_win real6410_fb_win[] = { 103 + { 104 + .win_mode = { /* 4.3" 480x272 */ 105 + .left_margin = 3, 106 + .right_margin = 2, 107 + .upper_margin = 1, 108 + .lower_margin = 1, 109 + .hsync_len = 40, 110 + .vsync_len = 1, 111 + .xres = 480, 112 + .yres = 272, 113 + }, 114 + .max_bpp = 32, 115 + .default_bpp = 16, 116 + }, { 117 + .win_mode = { /* 7.0" 800x480 */ 118 + .left_margin = 8, 119 + .right_margin = 13, 120 + .upper_margin = 7, 121 + .lower_margin = 5, 122 + .hsync_len = 3, 123 + .vsync_len = 1, 124 + .xres = 800, 125 + .yres = 480, 126 + }, 127 + .max_bpp = 32, 128 + .default_bpp = 16, 129 + }, 130 + }; 131 + 132 + static struct s3c_fb_platdata real6410_lcd_pdata __initdata = { 133 + .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, 134 + .win[0] = &real6410_fb_win[0], 135 + .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, 136 + .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, 137 + }; 138 + 139 + static struct mtd_partition real6410_nand_part[] = { 140 + [0] = { 141 + .name = "uboot", 142 + .size = SZ_1M, 143 + .offset = 0, 144 + }, 145 + [1] = { 146 + .name = "kernel", 147 + .size = SZ_2M, 148 + .offset = SZ_1M, 149 + }, 150 + [2] = { 151 + .name = "rootfs", 152 + .size = MTDPART_SIZ_FULL, 153 + .offset = SZ_1M + SZ_2M, 154 + }, 155 + }; 156 + 157 + static struct s3c2410_nand_set real6410_nand_sets[] = { 158 + [0] = { 159 + .name = "nand", 160 + .nr_chips = 1, 161 + .nr_partitions = ARRAY_SIZE(real6410_nand_part), 162 + .partitions = real6410_nand_part, 163 + }, 164 + }; 165 + 166 + static struct s3c2410_platform_nand real6410_nand_info = { 167 + .tacls = 25, 168 + .twrph0 = 55, 169 + .twrph1 = 40, 170 + .nr_sets = ARRAY_SIZE(real6410_nand_sets), 171 + .sets = real6410_nand_sets, 172 + }; 173 + 118 174 static struct platform_device *real6410_devices[] __initdata = { 119 175 &real6410_device_eth, 120 176 &s3c_device_hsmmc0, 121 177 &s3c_device_hsmmc1, 178 + &s3c_device_fb, 179 + &s3c_device_nand, 180 + &s3c_device_adc, 181 + &s3c_device_ts, 182 + &s3c_device_ohci, 183 + }; 184 + 185 + static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = { 186 + .delay = 10000, 187 + .presc = 49, 188 + .oversampling_shift = 2, 122 189 }; 123 190 124 191 static void __init real6410_map_io(void) 125 192 { 193 + u32 tmp; 194 + 126 195 s3c64xx_init_io(NULL, 0); 127 196 s3c24xx_init_clocks(12000000); 128 197 s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs)); 198 + 199 + /* set the LCD type */ 200 + tmp = __raw_readl(S3C64XX_SPCON); 201 + tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK; 202 + tmp |= S3C64XX_SPCON_LCD_SEL_RGB; 203 + __raw_writel(tmp, S3C64XX_SPCON); 204 + 205 + /* remove the LCD bypass */ 206 + tmp = __raw_readl(S3C64XX_MODEM_MIFPCON); 207 + tmp &= ~MIFPCON_LCD_BYPASS; 208 + __raw_writel(tmp, S3C64XX_MODEM_MIFPCON); 209 + } 210 + 211 + /* 212 + * real6410_features string 213 + * 214 + * 0-9 LCD configuration 215 + * 216 + */ 217 + static char real6410_features_str[12] __initdata = "0"; 218 + 219 + static int __init real6410_features_setup(char *str) 220 + { 221 + if (str) 222 + strlcpy(real6410_features_str, str, 223 + sizeof(real6410_features_str)); 224 + return 1; 225 + } 226 + 227 + __setup("real6410=", real6410_features_setup); 228 + 229 + #define FEATURE_SCREEN (1 << 0) 230 + 231 + struct real6410_features_t { 232 + int done; 233 + int lcd_index; 234 + }; 235 + 236 + static void real6410_parse_features( 237 + struct real6410_features_t *features, 238 + const char *features_str) 239 + { 240 + const char *fp = features_str; 241 + 242 + features->done = 0; 243 + features->lcd_index = 0; 244 + 245 + while (*fp) { 246 + char f = *fp++; 247 + 248 + switch (f) { 249 + case '0'...'9': /* tft screen */ 250 + if (features->done & FEATURE_SCREEN) { 251 + printk(KERN_INFO "REAL6410: '%c' ignored, " 252 + "screen type already set\n", f); 253 + } else { 254 + int li = f - '0'; 255 + if (li >= ARRAY_SIZE(real6410_fb_win)) 256 + printk(KERN_INFO "REAL6410: '%c' out " 257 + "of range LCD mode\n", f); 258 + else { 259 + features->lcd_index = li; 260 + } 261 + } 262 + features->done |= FEATURE_SCREEN; 263 + break; 264 + } 265 + } 129 266 } 130 267 131 268 static void __init real6410_machine_init(void) 132 269 { 133 270 u32 cs1; 271 + struct real6410_features_t features = { 0 }; 272 + 273 + printk(KERN_INFO "REAL6410: Option string real6410=%s\n", 274 + real6410_features_str); 275 + 276 + /* Parse the feature string */ 277 + real6410_parse_features(&features, real6410_features_str); 278 + 279 + real6410_lcd_pdata.win[0] = &real6410_fb_win[features.lcd_index]; 280 + 281 + printk(KERN_INFO "REAL6410: selected LCD display is %dx%d\n", 282 + real6410_lcd_pdata.win[0]->win_mode.xres, 283 + real6410_lcd_pdata.win[0]->win_mode.yres); 284 + 285 + s3c_fb_set_platdata(&real6410_lcd_pdata); 286 + s3c_nand_set_platdata(&real6410_nand_info); 287 + s3c24xx_ts_set_platdata(&s3c_ts_platform); 134 288 135 289 /* configure nCS1 width to 16 bits */ 136 290 ··· 321 135 (13 << S3C64XX_SROM_BCX__TACC__SHIFT) | 322 136 (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) | 323 137 (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1); 138 + 139 + gpio_request(S3C64XX_GPF(15), "LCD power"); 324 140 325 141 platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices)); 326 142 }
+2 -11
arch/arm/mach-s3c64xx/setup-fb-24bpp.c
··· 23 23 24 24 extern void s3c64xx_fb_gpio_setup_24bpp(void) 25 25 { 26 - unsigned int gpio; 27 - 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 - } 26 + s3c_gpio_cfgrange_nopull(S3C64XX_GPI(0), 16, S3C_GPIO_SFN(2)); 27 + s3c_gpio_cfgrange_nopull(S3C64XX_GPJ(0), 12, S3C_GPIO_SFN(2)); 37 28 }
+4 -7
arch/arm/mach-s3c64xx/setup-ide.c
··· 17 17 #include <mach/map.h> 18 18 #include <mach/regs-clock.h> 19 19 #include <plat/gpio-cfg.h> 20 + #include <plat/ata.h> 20 21 21 22 void s3c64xx_ide_setup_gpio(void) 22 23 { 23 24 u32 reg; 24 - u32 gpio = 0; 25 25 26 26 reg = readl(S3C_MEM_SYS_CFG) & (~0x3f); 27 27 ··· 32 32 s3c_gpio_cfgpin(S3C64XX_GPB(4), S3C_GPIO_SFN(4)); 33 33 34 34 /* Set XhiDATA[15:0] pins as CF Data[15:0] */ 35 - for (gpio = S3C64XX_GPK(0); gpio <= S3C64XX_GPK(15); gpio++) 36 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(5)); 35 + s3c_gpio_cfgpin_range(S3C64XX_GPK(0), 16, S3C_GPIO_SFN(5)); 37 36 38 37 /* Set XhiADDR[2:0] pins as CF ADDR[2:0] */ 39 - for (gpio = S3C64XX_GPL(0); gpio <= S3C64XX_GPL(2); gpio++) 40 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6)); 38 + s3c_gpio_cfgpin_range(S3C64XX_GPL(0), 3, S3C_GPIO_SFN(6)); 41 39 42 40 /* Set Xhi ctrl pins as CF ctrl pins(IORDY, IOWR, IORD, CE[0:1]) */ 43 41 s3c_gpio_cfgpin(S3C64XX_GPM(5), S3C_GPIO_SFN(1)); 44 - for (gpio = S3C64XX_GPM(0); gpio <= S3C64XX_GPM(4); gpio++) 45 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6)); 42 + s3c_gpio_cfgpin_range(S3C64XX_GPM(0), 5, S3C_GPIO_SFN(6)); 46 43 }
+3 -13
arch/arm/mach-s3c64xx/setup-keypad.c
··· 12 12 13 13 #include <linux/gpio.h> 14 14 #include <plat/gpio-cfg.h> 15 + #include <plat/keypad.h> 15 16 16 17 void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) 17 18 { 18 - unsigned int gpio; 19 - unsigned int end; 20 - 21 19 /* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */ 22 - end = S3C64XX_GPK(8 + rows); 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 - } 20 + s3c_gpio_cfgrange_nopull(S3C64XX_GPK(8), 8 + rows, S3C_GPIO_SFN(3)); 27 21 28 22 /* Set all the necessary GPL pins to special-function 3: KP_COL[x] */ 29 - end = S3C64XX_GPL(0 + cols); 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 - } 23 + s3c_gpio_cfgrange_nopull(S3C64XX_GPL(0), cols, S3C_GPIO_SFN(3)); 34 24 }
+8 -33
arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
··· 24 24 void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) 25 25 { 26 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); 31 - 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 - } 28 + /* Set all the necessary GPG pins to special-function 2 */ 29 + s3c_gpio_cfgrange_nopull(S3C64XX_GPG(0), 2 + width, S3C_GPIO_SFN(2)); 37 30 38 31 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 39 32 s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); ··· 37 44 void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) 38 45 { 39 46 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 40 - unsigned int gpio; 41 - unsigned int end; 42 47 43 - end = S3C64XX_GPH(2 + width); 44 - 45 - /* Set all the necessary GPG pins to special-function 0 */ 46 - for (gpio = S3C64XX_GPH(0); gpio < end; gpio++) { 47 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 48 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 49 - } 48 + /* Set all the necessary GPH pins to special-function 2 */ 49 + s3c_gpio_cfgrange_nopull(S3C64XX_GPH(0), 2 + width, S3C_GPIO_SFN(2)); 50 50 51 51 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 52 52 s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); ··· 49 63 50 64 void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) 51 65 { 52 - unsigned int gpio; 53 - unsigned int end; 66 + /* Set all the necessary GPH pins to special-function 3 */ 67 + s3c_gpio_cfgrange_nopull(S3C64XX_GPH(6), width, S3C_GPIO_SFN(3)); 54 68 55 - end = S3C64XX_GPH(6 + width); 56 - 57 - /* Set all the necessary GPH pins to special-function 1 */ 58 - for (gpio = S3C64XX_GPH(6); gpio < end; gpio++) { 59 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3)); 60 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 61 - } 62 - 63 - /* Set all the necessary GPC pins to special-function 1 */ 64 - for (gpio = S3C64XX_GPC(4); gpio < S3C64XX_GPC(6); gpio++) { 65 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3)); 66 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 67 - } 69 + /* Set all the necessary GPC pins to special-function 3 */ 70 + s3c_gpio_cfgrange_nopull(S3C64XX_GPC(4), 2, S3C_GPIO_SFN(3)); 68 71 }
-1
arch/arm/mach-s5p6442/Kconfig
··· 11 11 12 12 config CPU_S5P6442 13 13 bool 14 - select PLAT_S5P 15 14 select S3C_PL330_DMA 16 15 help 17 16 Enable S5P6442 CPU support
+28
arch/arm/mach-s5p6442/clock.c
··· 192 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 200 int s5p6442_clk_ip3_ctrl(struct clk *clk, int enable) 196 201 { 197 202 return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); ··· 340 335 clk_pclkd1.rate = pclkd1; 341 336 } 342 337 338 + static struct clk init_clocks_disable[] = { 339 + { 340 + .name = "pdma", 341 + .id = -1, 342 + .parent = &clk_pclkd1, 343 + .enable = s5p6442_clk_ip0_ctrl, 344 + .ctrlbit = (1 << 3), 345 + }, 346 + }; 347 + 343 348 static struct clk init_clocks[] = { 344 349 { 345 350 .name = "systimer", ··· 408 393 409 394 void __init s5p6442_register_clocks(void) 410 395 { 396 + struct clk *clkptr; 397 + int i, ret; 398 + 411 399 s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); 412 400 413 401 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 414 402 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 403 + 404 + clkptr = init_clocks_disable; 405 + for (i = 0; i < ARRAY_SIZE(init_clocks_disable); i++, clkptr++) { 406 + ret = s3c24xx_register_clock(clkptr); 407 + if (ret < 0) { 408 + printk(KERN_ERR "Fail to register clock %s (%d)\n", 409 + clkptr->name, ret); 410 + } else 411 + (clkptr->enable)(clkptr, 0); 412 + } 415 413 416 414 s3c_pwmclk_init(); 417 415 }
+10 -20
arch/arm/mach-s5p6442/dev-audio.c
··· 21 21 22 22 static int s5p6442_cfg_i2s(struct platform_device *pdev) 23 23 { 24 + unsigned int base; 25 + 24 26 /* configure GPIO for i2s port */ 25 27 switch (pdev->id) { 26 28 case 1: 27 - s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(2)); 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)); 29 + base = S5P6442_GPC1(0); 32 30 break; 33 31 34 32 case -1: 35 - s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(2)); 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)); 33 + base = S5P6442_GPC0(0); 40 34 break; 41 35 42 36 default: ··· 38 44 return -EINVAL; 39 45 } 40 46 47 + s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2)); 41 48 return 0; 42 49 } 43 50 ··· 106 111 107 112 static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev) 108 113 { 114 + unsigned int base; 115 + 109 116 switch (pdev->id) { 110 117 case 0: 111 - s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(3)); 112 - s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(3)); 113 - s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(3)); 114 - s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(3)); 115 - s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(3)); 118 + base = S5P6442_GPC0(0); 116 119 break; 117 120 118 121 case 1: 119 - s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(3)); 120 - s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(3)); 121 - s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(3)); 122 - s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(3)); 123 - s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(3)); 122 + base = S5P6442_GPC1(0); 124 123 break; 125 124 126 125 default: ··· 122 133 return -EINVAL; 123 134 } 124 135 136 + s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3)); 125 137 return 0; 126 138 } 127 139
+2 -4
arch/arm/mach-s5p6442/dev-spi.c
··· 38 38 switch (pdev->id) { 39 39 case 0: 40 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 41 s3c_gpio_setpull(S5P6442_GPB(0), S3C_GPIO_PULL_UP); 44 - s3c_gpio_setpull(S5P6442_GPB(2), S3C_GPIO_PULL_UP); 45 - s3c_gpio_setpull(S5P6442_GPB(3), S3C_GPIO_PULL_UP); 42 + s3c_gpio_cfgall_range(S5P6442_GPB(2), 2, 43 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 46 44 break; 47 45 48 46 default:
+1 -1
arch/arm/mach-s5p6442/dma.c
··· 82 82 83 83 static struct platform_device s5p6442_device_pdma = { 84 84 .name = "s3c-pl330", 85 - .id = 1, 85 + .id = -1, 86 86 .num_resources = ARRAY_SIZE(s5p6442_pdma_resource), 87 87 .resource = s5p6442_pdma_resource, 88 88 .dev = {
+1
arch/arm/mach-s5p6442/include/mach/regs-clock.h
··· 46 46 #define S5P_CLK_DIV5 S5P_CLKREG(0x314) 47 47 #define S5P_CLK_DIV6 S5P_CLKREG(0x318) 48 48 49 + #define S5P_CLKGATE_IP0 S5P_CLKREG(0x460) 49 50 #define S5P_CLKGATE_IP3 S5P_CLKREG(0x46C) 50 51 51 52 /* CLK_OUT */
+1 -1
arch/arm/mach-s5p6442/include/mach/vmalloc.h
··· 12 12 #ifndef __ASM_ARCH_VMALLOC_H 13 13 #define __ASM_ARCH_VMALLOC_H 14 14 15 - #define VMALLOC_END 0xE0000000UL 15 + #define VMALLOC_END 0xF6000000UL 16 16 17 17 #endif /* __ASM_ARCH_VMALLOC_H */
-2
arch/arm/mach-s5p64x0/Kconfig
··· 9 9 10 10 config CPU_S5P6440 11 11 bool 12 - select PLAT_S5P 13 12 select S3C_PL330_DMA 14 13 help 15 14 Enable S5P6440 CPU support 16 15 17 16 config CPU_S5P6450 18 17 bool 19 - select PLAT_S5P 20 18 select S3C_PL330_DMA 21 19 help 22 20 Enable S5P6450 CPU support
+11 -8
arch/arm/mach-s5p64x0/clock-s5p6440.c
··· 79 79 __raw_writel(epll_con, S5P64X0_EPLL_CON); 80 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 85 clk->rate = rate; 83 86 84 87 return 0; 85 88 } 86 89 87 90 static struct clk_ops s5p6440_epll_ops = { 88 - .get_rate = s5p64x0_epll_get_rate, 91 + .get_rate = s5p_epll_get_rate, 89 92 .set_rate = s5p6440_epll_set_rate, 90 93 }; 91 94 ··· 152 149 .parent = &clk_hclk.clk, 153 150 .enable = s5p64x0_hclk0_ctrl, 154 151 .ctrlbit = (1 << 8), 152 + }, { 153 + .name = "pdma", 154 + .id = -1, 155 + .parent = &clk_hclk_low.clk, 156 + .enable = s5p64x0_hclk0_ctrl, 157 + .ctrlbit = (1 << 12), 155 158 }, { 156 159 .name = "hsmmc", 157 160 .id = 0, ··· 339 330 .parent = &clk_hclk.clk, 340 331 .enable = s5p64x0_hclk0_ctrl, 341 332 .ctrlbit = (1 << 21), 342 - }, { 343 - .name = "dma", 344 - .id = -1, 345 - .parent = &clk_hclk_low.clk, 346 - .enable = s5p64x0_hclk0_ctrl, 347 - .ctrlbit = (1 << 12), 348 333 }, { 349 334 .name = "uart", 350 335 .id = 0, ··· 551 548 552 549 /* Set S5P6440 functions for clk_fout_epll */ 553 550 554 - clk_fout_epll.enable = s5p64x0_epll_enable; 551 + clk_fout_epll.enable = s5p_epll_enable; 555 552 clk_fout_epll.ops = &s5p6440_epll_ops; 556 553 557 554 clk_48m.enable = s5p64x0_clk48m_ctrl;
+11 -8
arch/arm/mach-s5p64x0/clock-s5p6450.c
··· 80 80 __raw_writel(epll_con, S5P64X0_EPLL_CON); 81 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 86 clk->rate = rate; 84 87 85 88 return 0; 86 89 } 87 90 88 91 static struct clk_ops s5p6450_epll_ops = { 89 - .get_rate = s5p64x0_epll_get_rate, 92 + .get_rate = s5p_epll_get_rate, 90 93 .set_rate = s5p6450_epll_set_rate, 91 94 }; 92 95 ··· 189 186 .enable = s5p64x0_hclk0_ctrl, 190 187 .ctrlbit = (1 << 3), 191 188 }, { 189 + .name = "pdma", 190 + .id = -1, 191 + .parent = &clk_hclk_low.clk, 192 + .enable = s5p64x0_hclk0_ctrl, 193 + .ctrlbit = (1 << 12), 194 + }, { 192 195 .name = "hsmmc", 193 196 .id = 0, 194 197 .parent = &clk_hclk_low.clk, ··· 291 282 .parent = &clk_hclk.clk, 292 283 .enable = s5p64x0_hclk0_ctrl, 293 284 .ctrlbit = (1 << 21), 294 - }, { 295 - .name = "dma", 296 - .id = -1, 297 - .parent = &clk_hclk_low.clk, 298 - .enable = s5p64x0_hclk0_ctrl, 299 - .ctrlbit = (1 << 12), 300 285 }, { 301 286 .name = "uart", 302 287 .id = 0, ··· 584 581 585 582 /* Set S5P6450 functions for clk_fout_epll */ 586 583 587 - clk_fout_epll.enable = s5p64x0_epll_enable; 584 + clk_fout_epll.enable = s5p_epll_enable; 588 585 clk_fout_epll.ops = &s5p6450_epll_ops; 589 586 590 587 clk_48m.enable = s5p64x0_clk48m_ctrl;
-18
arch/arm/mach-s5p64x0/clock.c
··· 73 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 76 unsigned long s5p64x0_armclk_get_rate(struct clk *clk) 95 77 { 96 78 unsigned long rate = clk_get_rate(clk->parent);
+7 -19
arch/arm/mach-s5p64x0/dev-audio.c
··· 24 24 /* configure GPIO for i2s port */ 25 25 switch (pdev->id) { 26 26 case -1: 27 - s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5)); 28 - s3c_gpio_cfgpin(S5P6440_GPR(5), 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)); 27 + s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5)); 28 + s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5)); 34 29 break; 35 30 36 31 default: ··· 42 47 switch (pdev->id) { 43 48 case -1: 44 49 s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5)); 45 - s3c_gpio_cfgpin(S5P6450_GPR(4), S3C_GPIO_SFN(5)); 46 - s3c_gpio_cfgpin(S5P6450_GPR(5), S3C_GPIO_SFN(5)); 47 - s3c_gpio_cfgpin(S5P6450_GPR(6), S3C_GPIO_SFN(5)); 48 - s3c_gpio_cfgpin(S5P6450_GPR(7), S3C_GPIO_SFN(5)); 49 - s3c_gpio_cfgpin(S5P6450_GPR(8), S3C_GPIO_SFN(5)); 50 - s3c_gpio_cfgpin(S5P6450_GPR(13), S3C_GPIO_SFN(5)); 51 - s3c_gpio_cfgpin(S5P6450_GPR(14), S3C_GPIO_SFN(5)); 50 + s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5)); 51 + s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5)); 52 + 52 53 break; 53 54 54 55 default: ··· 107 116 { 108 117 switch (pdev->id) { 109 118 case 0: 110 - s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2)); 111 - s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(2)); 112 - s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(2)); 113 - s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(2)); 114 - s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(2)); 119 + s3c_gpio_cfgpin_range(S5P6440_GPR(6), 3, S3C_GPIO_SFN(2)); 120 + s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(2)); 115 121 break; 116 122 117 123 default:
+14 -24
arch/arm/mach-s5p64x0/dev-spi.c
··· 39 39 */ 40 40 static int s5p6440_spi_cfg_gpio(struct platform_device *pdev) 41 41 { 42 + unsigned int base; 43 + 42 44 switch (pdev->id) { 43 45 case 0: 44 - s3c_gpio_cfgpin(S5P6440_GPC(0), S3C_GPIO_SFN(2)); 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); 46 + base = S5P6440_GPC(0); 50 47 break; 51 48 52 49 case 1: 53 - s3c_gpio_cfgpin(S5P6440_GPC(4), S3C_GPIO_SFN(2)); 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); 50 + base = S5P6440_GPC(4); 59 51 break; 60 52 61 53 default: 62 54 dev_err(&pdev->dev, "Invalid SPI Controller number!"); 63 55 return -EINVAL; 64 56 } 57 + 58 + s3c_gpio_cfgall_range(base, 3, 59 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 65 60 66 61 return 0; 67 62 } 68 63 69 64 static int s5p6450_spi_cfg_gpio(struct platform_device *pdev) 70 65 { 66 + unsigned int base; 67 + 71 68 switch (pdev->id) { 72 69 case 0: 73 - s3c_gpio_cfgpin(S5P6450_GPC(0), S3C_GPIO_SFN(2)); 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); 70 + base = S5P6450_GPC(0); 79 71 break; 80 72 81 73 case 1: 82 - s3c_gpio_cfgpin(S5P6450_GPC(4), S3C_GPIO_SFN(2)); 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); 74 + base = S5P6450_GPC(4); 88 75 break; 89 76 90 77 default: 91 78 dev_err(&pdev->dev, "Invalid SPI Controller number!"); 92 79 return -EINVAL; 93 80 } 81 + 82 + s3c_gpio_cfgall_range(base, 3, 83 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 94 84 95 85 return 0; 96 86 }
+1 -1
arch/arm/mach-s5p64x0/dma.c
··· 122 122 123 123 static struct platform_device s5p64x0_device_pdma = { 124 124 .name = "s3c-pl330", 125 - .id = 0, 125 + .id = -1, 126 126 .num_resources = ARRAY_SIZE(s5p64x0_pdma_resource), 127 127 .resource = s5p64x0_pdma_resource, 128 128 .dev = {
+2
arch/arm/mach-s5p64x0/include/mach/regs-clock.h
··· 60 60 #define ARM_DIV_RATIO_SHIFT 0 61 61 #define ARM_DIV_MASK (0xF << ARM_DIV_RATIO_SHIFT) 62 62 63 + #define S5P_EPLL_CON S5P64X0_EPLL_CON 64 + 63 65 #endif /* __ASM_ARCH_REGS_CLOCK_H */
+1 -1
arch/arm/mach-s5p64x0/include/mach/vmalloc.h
··· 15 15 #ifndef __ASM_ARCH_VMALLOC_H 16 16 #define __ASM_ARCH_VMALLOC_H 17 17 18 - #define VMALLOC_END 0xE0000000UL 18 + #define VMALLOC_END 0xF6000000UL 19 19 20 20 #endif /* __ASM_ARCH_VMALLOC_H */
+4 -8
arch/arm/mach-s5p64x0/setup-i2c0.c
··· 25 25 26 26 void s5p6440_i2c0_cfg_gpio(struct platform_device *dev) 27 27 { 28 - s3c_gpio_cfgpin(S5P6440_GPB(5), S3C_GPIO_SFN(2)); 29 - s3c_gpio_setpull(S5P6440_GPB(5), 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); 28 + s3c_gpio_cfgall_range(S5P6440_GPB(5), 2, 29 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 32 30 } 33 31 34 32 void s5p6450_i2c0_cfg_gpio(struct platform_device *dev) 35 33 { 36 - s3c_gpio_cfgpin(S5P6450_GPB(5), S3C_GPIO_SFN(2)); 37 - s3c_gpio_setpull(S5P6450_GPB(5), 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); 34 + s3c_gpio_cfgall_range(S5P6450_GPB(5), 2, 35 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 40 36 } 41 37 42 38 void s3c_i2c0_cfg_gpio(struct platform_device *dev) { }
+4 -8
arch/arm/mach-s5p64x0/setup-i2c1.c
··· 25 25 26 26 void s5p6440_i2c1_cfg_gpio(struct platform_device *dev) 27 27 { 28 - s3c_gpio_cfgpin(S5P6440_GPR(9), S3C_GPIO_SFN(6)); 29 - s3c_gpio_setpull(S5P6440_GPR(9), 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); 28 + s3c_gpio_cfgall_range(S5P6440_GPR(9), 2, 29 + S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP); 32 30 } 33 31 34 32 void s5p6450_i2c1_cfg_gpio(struct platform_device *dev) 35 33 { 36 - s3c_gpio_cfgpin(S5P6450_GPR(9), S3C_GPIO_SFN(6)); 37 - s3c_gpio_setpull(S5P6450_GPR(9), 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); 34 + s3c_gpio_cfgall_range(S5P6450_GPR(9), 2, 35 + S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP); 40 36 } 41 37 42 38 void s3c_i2c1_cfg_gpio(struct platform_device *dev) { }
-1
arch/arm/mach-s5pc100/Kconfig
··· 9 9 10 10 config CPU_S5PC100 11 11 bool 12 - select PLAT_S5P 13 12 select S5P_EXT_INT 14 13 select S3C_PL330_DMA 15 14 help
+1 -1
arch/arm/mach-s5pc100/Makefile
··· 11 11 12 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 15 obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o 16 16 obj-$(CONFIG_CPU_S5PC100) += dma.o 17 17
+112 -62
arch/arm/mach-s5pc100/clock.c
··· 273 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 276 static u32 epll_div[][4] = { 295 277 { 32750000, 131, 3, 4 }, 296 278 { 32768000, 131, 3, 4 }, ··· 323 341 324 342 __raw_writel(epll_con, S5P_EPLL_CON); 325 343 344 + printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n", 345 + clk->rate, rate); 346 + 326 347 clk->rate = rate; 327 348 328 349 return 0; 329 350 } 330 351 331 352 static struct clk_ops s5pc100_epll_ops = { 332 - .get_rate = s5pc100_epll_get_rate, 353 + .get_rate = s5p_epll_get_rate, 333 354 .set_rate = s5pc100_epll_set_rate, 334 355 }; 335 356 ··· 676 691 }, { 677 692 .name = "iis", 678 693 .id = 0, 679 - .parent = &clk_div_d1_bus.clk, 694 + .parent = &clk_div_pclkd1.clk, 680 695 .enable = s5pc100_d1_5_ctrl, 681 696 .ctrlbit = (1 << 0), 682 697 }, { 683 698 .name = "iis", 684 699 .id = 1, 685 - .parent = &clk_div_d1_bus.clk, 700 + .parent = &clk_div_pclkd1.clk, 686 701 .enable = s5pc100_d1_5_ctrl, 687 702 .ctrlbit = (1 << 1), 688 703 }, { 689 704 .name = "iis", 690 705 .id = 2, 691 - .parent = &clk_div_d1_bus.clk, 706 + .parent = &clk_div_pclkd1.clk, 692 707 .enable = s5pc100_d1_5_ctrl, 693 708 .ctrlbit = (1 << 2), 694 709 }, { 695 710 .name = "ac97", 696 711 .id = -1, 697 - .parent = &clk_div_d1_bus.clk, 712 + .parent = &clk_div_pclkd1.clk, 698 713 .enable = s5pc100_d1_5_ctrl, 699 714 .ctrlbit = (1 << 3), 700 715 }, { 701 716 .name = "pcm", 702 717 .id = 0, 703 - .parent = &clk_div_d1_bus.clk, 718 + .parent = &clk_div_pclkd1.clk, 704 719 .enable = s5pc100_d1_5_ctrl, 705 720 .ctrlbit = (1 << 4), 706 721 }, { 707 722 .name = "pcm", 708 723 .id = 1, 709 - .parent = &clk_div_d1_bus.clk, 724 + .parent = &clk_div_pclkd1.clk, 710 725 .enable = s5pc100_d1_5_ctrl, 711 726 .ctrlbit = (1 << 5), 712 727 }, { 713 728 .name = "spdif", 714 729 .id = -1, 715 - .parent = &clk_div_d1_bus.clk, 730 + .parent = &clk_div_pclkd1.clk, 716 731 .enable = s5pc100_d1_5_ctrl, 717 732 .ctrlbit = (1 << 6), 718 733 }, { 719 734 .name = "adc", 720 735 .id = -1, 721 - .parent = &clk_div_d1_bus.clk, 736 + .parent = &clk_div_pclkd1.clk, 722 737 .enable = s5pc100_d1_5_ctrl, 723 738 .ctrlbit = (1 << 7), 724 739 }, { 725 740 .name = "keypad", 726 741 .id = -1, 727 - .parent = &clk_div_d1_bus.clk, 742 + .parent = &clk_div_pclkd1.clk, 728 743 .enable = s5pc100_d1_5_ctrl, 729 744 .ctrlbit = (1 << 8), 730 745 }, { ··· 833 848 .nr_sources = ARRAY_SIZE(clk_src_group3_list), 834 849 }; 835 850 851 + static struct clksrc_clk clk_sclk_audio0 = { 852 + .clk = { 853 + .name = "sclk_audio", 854 + .id = 0, 855 + .ctrlbit = (1 << 8), 856 + .enable = s5pc100_sclk1_ctrl, 857 + }, 858 + .sources = &clk_src_group3, 859 + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 }, 860 + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 }, 861 + }; 862 + 836 863 static struct clk *clk_src_group4_list[] = { 837 864 [0] = &clk_mout_epll.clk, 838 865 [1] = &clk_div_mpll.clk, ··· 859 862 .nr_sources = ARRAY_SIZE(clk_src_group4_list), 860 863 }; 861 864 865 + static struct clksrc_clk clk_sclk_audio1 = { 866 + .clk = { 867 + .name = "sclk_audio", 868 + .id = 1, 869 + .ctrlbit = (1 << 9), 870 + .enable = s5pc100_sclk1_ctrl, 871 + }, 872 + .sources = &clk_src_group4, 873 + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 }, 874 + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, 875 + }; 876 + 862 877 static struct clk *clk_src_group5_list[] = { 863 878 [0] = &clk_mout_epll.clk, 864 879 [1] = &clk_div_mpll.clk, ··· 882 873 struct clksrc_sources clk_src_group5 = { 883 874 .sources = clk_src_group5_list, 884 875 .nr_sources = ARRAY_SIZE(clk_src_group5_list), 876 + }; 877 + 878 + static struct clksrc_clk clk_sclk_audio2 = { 879 + .clk = { 880 + .name = "sclk_audio", 881 + .id = 2, 882 + .ctrlbit = (1 << 10), 883 + .enable = s5pc100_sclk1_ctrl, 884 + }, 885 + .sources = &clk_src_group5, 886 + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 }, 887 + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 }, 885 888 }; 886 889 887 890 static struct clk *clk_src_group6_list[] = { ··· 965 944 .nr_sources = ARRAY_SIZE(clk_src_pwi_list), 966 945 }; 967 946 947 + static struct clk *clk_sclk_spdif_list[] = { 948 + [0] = &clk_sclk_audio0.clk, 949 + [1] = &clk_sclk_audio1.clk, 950 + [2] = &clk_sclk_audio2.clk, 951 + }; 952 + 953 + struct clksrc_sources clk_src_sclk_spdif = { 954 + .sources = clk_sclk_spdif_list, 955 + .nr_sources = ARRAY_SIZE(clk_sclk_spdif_list), 956 + }; 957 + 958 + static int s5pc100_spdif_set_rate(struct clk *clk, unsigned long rate) 959 + { 960 + struct clk *pclk; 961 + int ret; 962 + 963 + pclk = clk_get_parent(clk); 964 + if (IS_ERR(pclk)) 965 + return -EINVAL; 966 + 967 + ret = pclk->ops->set_rate(pclk, rate); 968 + clk_put(pclk); 969 + 970 + return ret; 971 + } 972 + 973 + static unsigned long s5pc100_spdif_get_rate(struct clk *clk) 974 + { 975 + struct clk *pclk; 976 + int rate; 977 + 978 + pclk = clk_get_parent(clk); 979 + if (IS_ERR(pclk)) 980 + return -EINVAL; 981 + 982 + rate = pclk->ops->get_rate(clk); 983 + clk_put(pclk); 984 + 985 + return rate; 986 + } 987 + 988 + static struct clk_ops s5pc100_sclk_spdif_ops = { 989 + .set_rate = s5pc100_spdif_set_rate, 990 + .get_rate = s5pc100_spdif_get_rate, 991 + }; 992 + 993 + static struct clksrc_clk clk_sclk_spdif = { 994 + .clk = { 995 + .name = "sclk_spdif", 996 + .id = -1, 997 + .ctrlbit = (1 << 11), 998 + .enable = s5pc100_sclk1_ctrl, 999 + .ops = &s5pc100_sclk_spdif_ops, 1000 + }, 1001 + .sources = &clk_src_sclk_spdif, 1002 + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 24, .size = 2 }, 1003 + }; 1004 + 968 1005 static struct clksrc_clk clksrcs[] = { 969 1006 { 970 1007 .clk = { ··· 1078 999 }, 1079 1000 .sources = &clk_src_group6, 1080 1001 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 }, 1081 - }, { 1082 - .clk = { 1083 - .name = "sclk_audio", 1084 - .id = 0, 1085 - .ctrlbit = (1 << 8), 1086 - .enable = s5pc100_sclk1_ctrl, 1087 - 1088 - }, 1089 - .sources = &clk_src_group3, 1090 - .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 }, 1091 - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 }, 1092 - }, { 1093 - .clk = { 1094 - .name = "sclk_audio", 1095 - .id = 1, 1096 - .ctrlbit = (1 << 9), 1097 - .enable = s5pc100_sclk1_ctrl, 1098 - 1099 - }, 1100 - .sources = &clk_src_group4, 1101 - .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 }, 1102 - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, 1103 - }, { 1104 - .clk = { 1105 - .name = "sclk_audio", 1106 - .id = 2, 1107 - .ctrlbit = (1 << 10), 1108 - .enable = s5pc100_sclk1_ctrl, 1109 - 1110 - }, 1111 - .sources = &clk_src_group5, 1112 - .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 }, 1113 - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 }, 1114 1002 }, { 1115 1003 .clk = { 1116 1004 .name = "sclk_lcd", ··· 1225 1179 &clk_div_pclkd1, 1226 1180 &clk_div_cam, 1227 1181 &clk_div_hdmi, 1182 + &clk_sclk_audio0, 1183 + &clk_sclk_audio1, 1184 + &clk_sclk_audio2, 1185 + &clk_sclk_spdif, 1228 1186 }; 1229 1187 1230 1188 void __init_or_cpufreq s5pc100_setup_clocks(void) ··· 1246 1196 unsigned int ptr; 1247 1197 1248 1198 /* Set S5PC100 functions for clk_fout_epll */ 1249 - clk_fout_epll.enable = s5pc100_epll_enable; 1199 + clk_fout_epll.enable = s5p_epll_enable; 1250 1200 clk_fout_epll.ops = &s5pc100_epll_ops; 1251 1201 1252 1202 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+59 -27
arch/arm/mach-s5pc100/dev-audio.c
··· 24 24 /* configure GPIO for i2s port */ 25 25 switch (pdev->id) { 26 26 case 1: 27 - s3c_gpio_cfgpin(S5PC100_GPC(0), 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)); 27 + s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2)); 32 28 break; 33 29 34 30 case 2: 35 - s3c_gpio_cfgpin(S5PC100_GPG3(0), 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)); 31 + s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4)); 40 32 break; 41 33 42 34 case -1: /* Dedicated pins */ ··· 136 144 { 137 145 switch (pdev->id) { 138 146 case 0: 139 - s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(5)); 140 - s3c_gpio_cfgpin(S5PC100_GPG3(1), S3C_GPIO_SFN(5)); 141 - s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(5)); 142 - s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(5)); 143 - s3c_gpio_cfgpin(S5PC100_GPG3(4), S3C_GPIO_SFN(5)); 147 + s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(5)); 144 148 break; 145 149 146 150 case 1: 147 - s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(3)); 148 - s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(3)); 149 - s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(3)); 150 - s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(3)); 151 - s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(3)); 151 + s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(3)); 152 152 break; 153 153 154 154 default: ··· 215 231 216 232 static int s5pc100_ac97_cfg_gpio(struct platform_device *pdev) 217 233 { 218 - s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(4)); 219 - s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(4)); 220 - s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(4)); 221 - s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(4)); 222 - s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(4)); 223 - 224 - return 0; 234 + return s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(4)); 225 235 } 226 236 227 237 static struct resource s5pc100_ac97_resource[] = { ··· 263 285 .coherent_dma_mask = DMA_BIT_MASK(32), 264 286 }, 265 287 }; 288 + 289 + /* S/PDIF Controller platform_device */ 290 + static int s5pc100_spdif_cfg_gpd(struct platform_device *pdev) 291 + { 292 + s3c_gpio_cfgpin_range(S5PC100_GPD(5), 2, S3C_GPIO_SFN(3)); 293 + 294 + return 0; 295 + } 296 + 297 + static int s5pc100_spdif_cfg_gpg3(struct platform_device *pdev) 298 + { 299 + s3c_gpio_cfgpin_range(S5PC100_GPG3(5), 2, S3C_GPIO_SFN(3)); 300 + 301 + return 0; 302 + } 303 + 304 + static struct resource s5pc100_spdif_resource[] = { 305 + [0] = { 306 + .start = S5PC100_PA_SPDIF, 307 + .end = S5PC100_PA_SPDIF + 0x100 - 1, 308 + .flags = IORESOURCE_MEM, 309 + }, 310 + [1] = { 311 + .start = DMACH_SPDIF, 312 + .end = DMACH_SPDIF, 313 + .flags = IORESOURCE_DMA, 314 + }, 315 + }; 316 + 317 + static struct s3c_audio_pdata s5p_spdif_pdata = { 318 + .cfg_gpio = s5pc100_spdif_cfg_gpd, 319 + }; 320 + 321 + static u64 s5pc100_spdif_dmamask = DMA_BIT_MASK(32); 322 + 323 + struct platform_device s5pc100_device_spdif = { 324 + .name = "samsung-spdif", 325 + .id = -1, 326 + .num_resources = ARRAY_SIZE(s5pc100_spdif_resource), 327 + .resource = s5pc100_spdif_resource, 328 + .dev = { 329 + .platform_data = &s5p_spdif_pdata, 330 + .dma_mask = &s5pc100_spdif_dmamask, 331 + .coherent_dma_mask = DMA_BIT_MASK(32), 332 + }, 333 + }; 334 + 335 + void __init s5pc100_spdif_setup_gpio(int gpio) 336 + { 337 + if (gpio == S5PC100_SPDIF_GPD) 338 + s5p_spdif_pdata.cfg_gpio = s5pc100_spdif_cfg_gpd; 339 + else 340 + s5p_spdif_pdata.cfg_gpio = s5pc100_spdif_cfg_gpg3; 341 + }
+6 -16
arch/arm/mach-s5pc100/dev-spi.c
··· 38 38 { 39 39 switch (pdev->id) { 40 40 case 0: 41 - s3c_gpio_cfgpin(S5PC100_GPB(0), S3C_GPIO_SFN(2)); 42 - s3c_gpio_cfgpin(S5PC100_GPB(1), S3C_GPIO_SFN(2)); 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); 41 + s3c_gpio_cfgall_range(S5PC100_GPB(0), 3, 42 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 47 43 break; 48 44 49 45 case 1: 50 - s3c_gpio_cfgpin(S5PC100_GPB(4), S3C_GPIO_SFN(2)); 51 - s3c_gpio_cfgpin(S5PC100_GPB(5), S3C_GPIO_SFN(2)); 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); 46 + s3c_gpio_cfgall_range(S5PC100_GPB(4), 3, 47 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 56 48 break; 57 49 58 50 case 2: 59 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 52 s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP); 63 - s3c_gpio_setpull(S5PC100_GPG3(2), S3C_GPIO_PULL_UP); 64 - s3c_gpio_setpull(S5PC100_GPG3(3), S3C_GPIO_PULL_UP); 53 + s3c_gpio_cfgall_range(S5PC100_GPB(2), 2, 54 + S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP); 65 55 break; 66 56 67 57 default:
+2 -2
arch/arm/mach-s5pc100/dma.c
··· 81 81 82 82 static struct platform_device s5pc100_device_pdma0 = { 83 83 .name = "s3c-pl330", 84 - .id = 1, 84 + .id = 0, 85 85 .num_resources = ARRAY_SIZE(s5pc100_pdma0_resource), 86 86 .resource = s5pc100_pdma0_resource, 87 87 .dev = { ··· 143 143 144 144 static struct platform_device s5pc100_device_pdma1 = { 145 145 .name = "s3c-pl330", 146 - .id = 2, 146 + .id = 1, 147 147 .num_resources = ARRAY_SIZE(s5pc100_pdma1_resource), 148 148 .resource = s5pc100_pdma1_resource, 149 149 .dev = {
+73 -145
arch/arm/mach-s5pc100/gpiolib.c
··· 1 - /* 2 - * arch/arm/plat-s5pc100/gpiolib.c 1 + /* linux/arch/arm/mach-s5pc100/gpiolib.c 2 + * 3 + * Copyright (c) 2010 Samsung Electronics Co., Ltd. 4 + * http://www.samsung.com 3 5 * 4 6 * Copyright 2009 Samsung Electronics Co 5 7 * Kyungmin Park <kyungmin.park@samsung.com> ··· 63 61 * L3 8 4Bit None 64 62 */ 65 63 66 - static int s5pc100_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) 67 - { 68 - return S3C_IRQ_GPIO(chip->base + offset); 69 - } 70 - 71 - static int s5pc100_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset) 72 - { 73 - int base; 74 - 75 - base = chip->base - S5PC100_GPH0(0); 76 - if (base == 0) 77 - return IRQ_EINT(offset); 78 - base = chip->base - S5PC100_GPH1(0); 79 - if (base == 0) 80 - return IRQ_EINT(8 + offset); 81 - base = chip->base - S5PC100_GPH2(0); 82 - if (base == 0) 83 - return IRQ_EINT(16 + offset); 84 - base = chip->base - S5PC100_GPH3(0); 85 - if (base == 0) 86 - return IRQ_EINT(24 + offset); 87 - return -EINVAL; 88 - } 89 - 90 64 static struct s3c_gpio_cfg gpio_cfg = { 91 65 .set_config = s3c_gpio_setcfg_s3c64xx_4bit, 92 66 .set_pull = s3c_gpio_setpull_updown, ··· 82 104 .get_pull = s3c_gpio_getpull_updown, 83 105 }; 84 106 107 + /* 108 + * GPIO bank's base address given the index of the bank in the 109 + * list of all gpio banks. 110 + */ 111 + #define S5PC100_BANK_BASE(bank_nr) (S5P_VA_GPIO + ((bank_nr) * 0x20)) 112 + 113 + /* 114 + * Following are the gpio banks in S5PC100. 115 + * 116 + * The 'config' member when left to NULL, is initialized to the default 117 + * structure gpio_cfg in the init function below. 118 + * 119 + * The 'base' member is also initialized in the init function below. 120 + * Note: The initialization of 'base' member of s3c_gpio_chip structure 121 + * uses the above macro and depends on the banks being listed in order here. 122 + */ 85 123 static struct s3c_gpio_chip s5pc100_gpio_chips[] = { 86 124 { 87 - .base = S5PC100_GPA0_BASE, 88 - .config = &gpio_cfg, 89 125 .chip = { 90 126 .base = S5PC100_GPA0(0), 91 127 .ngpio = S5PC100_GPIO_A0_NR, 92 128 .label = "GPA0", 93 129 }, 94 130 }, { 95 - .base = S5PC100_GPA1_BASE, 96 - .config = &gpio_cfg, 97 131 .chip = { 98 132 .base = S5PC100_GPA1(0), 99 133 .ngpio = S5PC100_GPIO_A1_NR, 100 134 .label = "GPA1", 101 135 }, 102 136 }, { 103 - .base = S5PC100_GPB_BASE, 104 - .config = &gpio_cfg, 105 137 .chip = { 106 138 .base = S5PC100_GPB(0), 107 139 .ngpio = S5PC100_GPIO_B_NR, 108 140 .label = "GPB", 109 141 }, 110 142 }, { 111 - .base = S5PC100_GPC_BASE, 112 - .config = &gpio_cfg, 113 143 .chip = { 114 144 .base = S5PC100_GPC(0), 115 145 .ngpio = S5PC100_GPIO_C_NR, 116 146 .label = "GPC", 117 147 }, 118 148 }, { 119 - .base = S5PC100_GPD_BASE, 120 - .config = &gpio_cfg, 121 149 .chip = { 122 150 .base = S5PC100_GPD(0), 123 151 .ngpio = S5PC100_GPIO_D_NR, 124 152 .label = "GPD", 125 153 }, 126 154 }, { 127 - .base = S5PC100_GPE0_BASE, 128 - .config = &gpio_cfg, 129 155 .chip = { 130 156 .base = S5PC100_GPE0(0), 131 157 .ngpio = S5PC100_GPIO_E0_NR, 132 158 .label = "GPE0", 133 159 }, 134 160 }, { 135 - .base = S5PC100_GPE1_BASE, 136 - .config = &gpio_cfg, 137 161 .chip = { 138 162 .base = S5PC100_GPE1(0), 139 163 .ngpio = S5PC100_GPIO_E1_NR, 140 164 .label = "GPE1", 141 165 }, 142 166 }, { 143 - .base = S5PC100_GPF0_BASE, 144 - .config = &gpio_cfg, 145 167 .chip = { 146 168 .base = S5PC100_GPF0(0), 147 169 .ngpio = S5PC100_GPIO_F0_NR, 148 170 .label = "GPF0", 149 171 }, 150 172 }, { 151 - .base = S5PC100_GPF1_BASE, 152 - .config = &gpio_cfg, 153 173 .chip = { 154 174 .base = S5PC100_GPF1(0), 155 175 .ngpio = S5PC100_GPIO_F1_NR, 156 176 .label = "GPF1", 157 177 }, 158 178 }, { 159 - .base = S5PC100_GPF2_BASE, 160 - .config = &gpio_cfg, 161 179 .chip = { 162 180 .base = S5PC100_GPF2(0), 163 181 .ngpio = S5PC100_GPIO_F2_NR, 164 182 .label = "GPF2", 165 183 }, 166 184 }, { 167 - .base = S5PC100_GPF3_BASE, 168 - .config = &gpio_cfg, 169 185 .chip = { 170 186 .base = S5PC100_GPF3(0), 171 187 .ngpio = S5PC100_GPIO_F3_NR, 172 188 .label = "GPF3", 173 189 }, 174 190 }, { 175 - .base = S5PC100_GPG0_BASE, 176 - .config = &gpio_cfg, 177 191 .chip = { 178 192 .base = S5PC100_GPG0(0), 179 193 .ngpio = S5PC100_GPIO_G0_NR, 180 194 .label = "GPG0", 181 195 }, 182 196 }, { 183 - .base = S5PC100_GPG1_BASE, 184 - .config = &gpio_cfg, 185 197 .chip = { 186 198 .base = S5PC100_GPG1(0), 187 199 .ngpio = S5PC100_GPIO_G1_NR, 188 200 .label = "GPG1", 189 201 }, 190 202 }, { 191 - .base = S5PC100_GPG2_BASE, 192 - .config = &gpio_cfg, 193 203 .chip = { 194 204 .base = S5PC100_GPG2(0), 195 205 .ngpio = S5PC100_GPIO_G2_NR, 196 206 .label = "GPG2", 197 207 }, 198 208 }, { 199 - .base = S5PC100_GPG3_BASE, 200 - .config = &gpio_cfg, 201 209 .chip = { 202 210 .base = S5PC100_GPG3(0), 203 211 .ngpio = S5PC100_GPIO_G3_NR, 204 212 .label = "GPG3", 205 213 }, 206 214 }, { 207 - .base = S5PC100_GPH0_BASE, 208 - .config = &gpio_cfg_eint, 209 - .chip = { 210 - .base = S5PC100_GPH0(0), 211 - .ngpio = S5PC100_GPIO_H0_NR, 212 - .label = "GPH0", 213 - }, 214 - }, { 215 - .base = S5PC100_GPH1_BASE, 216 - .config = &gpio_cfg_eint, 217 - .chip = { 218 - .base = S5PC100_GPH1(0), 219 - .ngpio = S5PC100_GPIO_H1_NR, 220 - .label = "GPH1", 221 - }, 222 - }, { 223 - .base = S5PC100_GPH2_BASE, 224 - .config = &gpio_cfg_eint, 225 - .chip = { 226 - .base = S5PC100_GPH2(0), 227 - .ngpio = S5PC100_GPIO_H2_NR, 228 - .label = "GPH2", 229 - }, 230 - }, { 231 - .base = S5PC100_GPH3_BASE, 232 - .config = &gpio_cfg_eint, 233 - .chip = { 234 - .base = S5PC100_GPH3(0), 235 - .ngpio = S5PC100_GPIO_H3_NR, 236 - .label = "GPH3", 237 - }, 238 - }, { 239 - .base = S5PC100_GPI_BASE, 240 - .config = &gpio_cfg, 241 215 .chip = { 242 216 .base = S5PC100_GPI(0), 243 217 .ngpio = S5PC100_GPIO_I_NR, 244 218 .label = "GPI", 245 219 }, 246 220 }, { 247 - .base = S5PC100_GPJ0_BASE, 248 - .config = &gpio_cfg, 249 221 .chip = { 250 222 .base = S5PC100_GPJ0(0), 251 223 .ngpio = S5PC100_GPIO_J0_NR, 252 224 .label = "GPJ0", 253 225 }, 254 226 }, { 255 - .base = S5PC100_GPJ1_BASE, 256 - .config = &gpio_cfg, 257 227 .chip = { 258 228 .base = S5PC100_GPJ1(0), 259 229 .ngpio = S5PC100_GPIO_J1_NR, 260 230 .label = "GPJ1", 261 231 }, 262 232 }, { 263 - .base = S5PC100_GPJ2_BASE, 264 - .config = &gpio_cfg, 265 233 .chip = { 266 234 .base = S5PC100_GPJ2(0), 267 235 .ngpio = S5PC100_GPIO_J2_NR, 268 236 .label = "GPJ2", 269 237 }, 270 238 }, { 271 - .base = S5PC100_GPJ3_BASE, 272 - .config = &gpio_cfg, 273 239 .chip = { 274 240 .base = S5PC100_GPJ3(0), 275 241 .ngpio = S5PC100_GPIO_J3_NR, 276 242 .label = "GPJ3", 277 243 }, 278 244 }, { 279 - .base = S5PC100_GPJ4_BASE, 280 - .config = &gpio_cfg, 281 245 .chip = { 282 246 .base = S5PC100_GPJ4(0), 283 247 .ngpio = S5PC100_GPIO_J4_NR, 284 248 .label = "GPJ4", 285 249 }, 286 250 }, { 287 - .base = S5PC100_GPK0_BASE, 288 251 .config = &gpio_cfg_noint, 289 252 .chip = { 290 253 .base = S5PC100_GPK0(0), ··· 233 314 .label = "GPK0", 234 315 }, 235 316 }, { 236 - .base = S5PC100_GPK1_BASE, 237 317 .config = &gpio_cfg_noint, 238 318 .chip = { 239 319 .base = S5PC100_GPK1(0), ··· 240 322 .label = "GPK1", 241 323 }, 242 324 }, { 243 - .base = S5PC100_GPK2_BASE, 244 325 .config = &gpio_cfg_noint, 245 326 .chip = { 246 327 .base = S5PC100_GPK2(0), ··· 247 330 .label = "GPK2", 248 331 }, 249 332 }, { 250 - .base = S5PC100_GPK3_BASE, 251 333 .config = &gpio_cfg_noint, 252 334 .chip = { 253 335 .base = S5PC100_GPK3(0), ··· 254 338 .label = "GPK3", 255 339 }, 256 340 }, { 257 - .base = S5PC100_GPL0_BASE, 258 341 .config = &gpio_cfg_noint, 259 342 .chip = { 260 343 .base = S5PC100_GPL0(0), ··· 261 346 .label = "GPL0", 262 347 }, 263 348 }, { 264 - .base = S5PC100_GPL1_BASE, 265 349 .config = &gpio_cfg_noint, 266 350 .chip = { 267 351 .base = S5PC100_GPL1(0), ··· 268 354 .label = "GPL1", 269 355 }, 270 356 }, { 271 - .base = S5PC100_GPL2_BASE, 272 357 .config = &gpio_cfg_noint, 273 358 .chip = { 274 359 .base = S5PC100_GPL2(0), ··· 275 362 .label = "GPL2", 276 363 }, 277 364 }, { 278 - .base = S5PC100_GPL3_BASE, 279 365 .config = &gpio_cfg_noint, 280 366 .chip = { 281 367 .base = S5PC100_GPL3(0), ··· 282 370 .label = "GPL3", 283 371 }, 284 372 }, { 285 - .base = S5PC100_GPL4_BASE, 286 373 .config = &gpio_cfg_noint, 287 374 .chip = { 288 375 .base = S5PC100_GPL4(0), 289 376 .ngpio = S5PC100_GPIO_L4_NR, 290 377 .label = "GPL4", 291 378 }, 379 + }, { 380 + .base = (S5P_VA_GPIO + 0xC00), 381 + .config = &gpio_cfg_eint, 382 + .irq_base = IRQ_EINT(0), 383 + .chip = { 384 + .base = S5PC100_GPH0(0), 385 + .ngpio = S5PC100_GPIO_H0_NR, 386 + .label = "GPH0", 387 + .to_irq = samsung_gpiolib_to_irq, 388 + }, 389 + }, { 390 + .base = (S5P_VA_GPIO + 0xC20), 391 + .config = &gpio_cfg_eint, 392 + .irq_base = IRQ_EINT(8), 393 + .chip = { 394 + .base = S5PC100_GPH1(0), 395 + .ngpio = S5PC100_GPIO_H1_NR, 396 + .label = "GPH1", 397 + .to_irq = samsung_gpiolib_to_irq, 398 + }, 399 + }, { 400 + .base = (S5P_VA_GPIO + 0xC40), 401 + .config = &gpio_cfg_eint, 402 + .irq_base = IRQ_EINT(16), 403 + .chip = { 404 + .base = S5PC100_GPH2(0), 405 + .ngpio = S5PC100_GPIO_H2_NR, 406 + .label = "GPH2", 407 + .to_irq = samsung_gpiolib_to_irq, 408 + }, 409 + }, { 410 + .base = (S5P_VA_GPIO + 0xC60), 411 + .config = &gpio_cfg_eint, 412 + .irq_base = IRQ_EINT(24), 413 + .chip = { 414 + .base = S5PC100_GPH3(0), 415 + .ngpio = S5PC100_GPIO_H3_NR, 416 + .label = "GPH3", 417 + .to_irq = samsung_gpiolib_to_irq, 418 + }, 292 419 }, 293 420 }; 294 421 295 - /* FIXME move from irq-gpio.c */ 296 - extern struct irq_chip s5pc100_gpioint; 297 - extern void s5pc100_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc); 298 - 299 - static __init void s5pc100_gpiolib_link(struct s3c_gpio_chip *chip) 300 - { 301 - /* Interrupt */ 302 - if (chip->config == &gpio_cfg) { 303 - int i, irq; 304 - 305 - chip->chip.to_irq = s5pc100_gpiolib_to_irq; 306 - 307 - for (i = 0; i < chip->chip.ngpio; i++) { 308 - irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i; 309 - set_irq_chip(irq, &s5pc100_gpioint); 310 - set_irq_data(irq, &chip->chip); 311 - set_irq_handler(irq, handle_level_irq); 312 - set_irq_flags(irq, IRQF_VALID); 313 - } 314 - } else if (chip->config == &gpio_cfg_eint) { 315 - chip->chip.to_irq = s5pc100_gpiolib_to_eint; 316 - } 317 - } 318 - 319 422 static __init int s5pc100_gpiolib_init(void) 320 423 { 321 - struct s3c_gpio_chip *chip; 322 - int nr_chips; 424 + struct s3c_gpio_chip *chip = s5pc100_gpio_chips; 425 + int nr_chips = ARRAY_SIZE(s5pc100_gpio_chips); 426 + int gpioint_group = 0; 427 + int i; 323 428 324 - chip = s5pc100_gpio_chips; 325 - nr_chips = ARRAY_SIZE(s5pc100_gpio_chips); 429 + for (i = 0; i < nr_chips; i++, chip++) { 430 + if (chip->config == NULL) { 431 + chip->config = &gpio_cfg; 432 + chip->group = gpioint_group++; 433 + } 434 + if (chip->base == NULL) 435 + chip->base = S5PC100_BANK_BASE(i); 436 + } 326 437 327 - for (; nr_chips > 0; nr_chips--, chip++) 328 - s5pc100_gpiolib_link(chip); 329 - 330 - samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, 331 - ARRAY_SIZE(s5pc100_gpio_chips)); 332 - 333 - /* Interrupt */ 334 - set_irq_chained_handler(IRQ_GPIOINT, s5pc100_irq_gpioint_handler); 438 + samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips); 335 439 336 440 return 0; 337 441 }
-7
arch/arm/mach-s5pc100/include/mach/gpio.h
··· 146 146 /* define the number of gpios we need to the one after the MP04() range */ 147 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 149 #include <asm-generic/gpio.h> 157 150 158 151 #endif /* __ASM_ARCH_GPIO_H */
+7 -6
arch/arm/mach-s5pc100/include/mach/irqs.h
··· 48 48 #define IRQ_SPI1 S5P_IRQ_VIC1(16) 49 49 #define IRQ_SPI2 S5P_IRQ_VIC1(17) 50 50 #define IRQ_IRDA S5P_IRQ_VIC1(18) 51 - #define IRQ_CAN0 S5P_IRQ_VIC1(19) 52 - #define IRQ_CAN1 S5P_IRQ_VIC1(20) 51 + #define IRQ_IIC2 S5P_IRQ_VIC1(19) 52 + #define IRQ_IIC3 S5P_IRQ_VIC1(20) 53 53 #define IRQ_HSIRX S5P_IRQ_VIC1(21) 54 54 #define IRQ_HSITX S5P_IRQ_VIC1(22) 55 55 #define IRQ_UHOST S5P_IRQ_VIC1(23) ··· 100 100 #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) 101 101 #define S5P_EINT_BASE2 (IRQ_VIC_END + 1) 102 102 103 - #define S3C_IRQ_GPIO_BASE (IRQ_EINT(31) + 1) 104 - #define S3C_IRQ_GPIO(x) (S3C_IRQ_GPIO_BASE + (x)) 103 + /* GPIO interrupt */ 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 - #define NR_IRQS (S3C_IRQ_GPIO(320) + 1) 107 + /* Set the default NR_IRQS */ 108 + #define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1) 108 109 109 110 /* Compatibility */ 110 111 #define IRQ_LCD_FIFO IRQ_LCD0
+2
arch/arm/mach-s5pc100/include/mach/map.h
··· 110 110 #define S5PC100_PA_PCM0 0xF2400000 111 111 #define S5PC100_PA_PCM1 0xF2500000 112 112 113 + #define S5PC100_PA_SPDIF 0xF2600000 114 + 113 115 #define S5PC100_PA_TSADC (0xF3000000) 114 116 115 117 /* KEYPAD */
+6 -43
arch/arm/mach-s5pc100/include/mach/regs-gpio.h
··· 11 11 12 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 14 #define S5PC100EINT30CON (S5P_VA_GPIO + 0xE00) 52 15 #define S5P_EINT_CON(x) (S5PC100EINT30CON + ((x) * 0x4)) 53 16 ··· 27 64 28 65 #define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) 29 66 30 - /* values for S5P_EXTINT0 */ 31 - #define S5P_EXTINT_LOWLEV (0x00) 32 - #define S5P_EXTINT_HILEV (0x01) 33 - #define S5P_EXTINT_FALLEDGE (0x02) 34 - #define S5P_EXTINT_RISEEDGE (0x03) 35 - #define S5P_EXTINT_BOTHEDGE (0x04) 67 + #define EINT_MODE S3C_GPIO_SFN(0x2) 68 + 69 + #define EINT_GPIO_0(x) S5PC100_GPH0(x) 70 + #define EINT_GPIO_1(x) S5PC100_GPH1(x) 71 + #define EINT_GPIO_2(x) S5PC100_GPH2(x) 72 + #define EINT_GPIO_3(x) S5PC100_GPH3(x) 36 73 37 74 #endif /* __ASM_MACH_S5PC100_REGS_GPIO_H */ 38 75
+1 -1
arch/arm/mach-s5pc100/include/mach/vmalloc.h
··· 12 12 #ifndef __ASM_ARCH_VMALLOC_H 13 13 #define __ASM_ARCH_VMALLOC_H 14 14 15 - #define VMALLOC_END (0xe0000000UL) 15 + #define VMALLOC_END 0xF6000000UL 16 16 17 17 #endif /* __ASM_ARCH_VMALLOC_H */
-266
arch/arm/mach-s5pc100/irq-gpio.c
··· 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 - }
+4
arch/arm/mach-s5pc100/mach-smdkc100.c
··· 47 47 #include <plat/adc.h> 48 48 #include <plat/keypad.h> 49 49 #include <plat/ts.h> 50 + #include <plat/audio.h> 50 51 51 52 /* Following are default values for UCON, ULCON and UFCON UART registers */ 52 53 #define SMDKC100_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ ··· 197 196 &s5p_device_fimc0, 198 197 &s5p_device_fimc1, 199 198 &s5p_device_fimc2, 199 + &s5pc100_device_spdif, 200 200 }; 201 201 202 202 static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = { ··· 227 225 s3c_ide_set_platdata(&smdkc100_ide_pdata); 228 226 229 227 samsung_keypad_set_platdata(&smdkc100_keypad_data); 228 + 229 + s5pc100_spdif_setup_gpio(S5PC100_SPDIF_GPD); 230 230 231 231 /* LCD init */ 232 232 gpio_request(S5PC100_GPD(0), "GPD");
+9 -21
arch/arm/mach-s5pc100/setup-fb-24bpp.c
··· 22 22 23 23 #define DISR_OFFSET 0x7008 24 24 25 + static void s5pc100_fb_setgpios(unsigned int base, unsigned int nr) 26 + { 27 + s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2)); 28 + } 29 + 25 30 void s5pc100_fb_gpio_setup_24bpp(void) 26 31 { 27 - unsigned int gpio = 0; 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 - 44 - for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) { 45 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 46 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 47 - } 32 + s5pc100_fb_setgpios(S5PC100_GPF0(0), 8); 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 }
+2 -4
arch/arm/mach-s5pc100/setup-i2c0.c
··· 23 23 24 24 void s3c_i2c0_cfg_gpio(struct platform_device *dev) 25 25 { 26 - s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2)); 27 - s3c_gpio_setpull(S5PC100_GPD(3), 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); 26 + s3c_gpio_cfgall_range(S5PC100_GPD(3), 2, 27 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 30 28 }
+2 -4
arch/arm/mach-s5pc100/setup-i2c1.c
··· 23 23 24 24 void s3c_i2c1_cfg_gpio(struct platform_device *dev) 25 25 { 26 - s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2)); 27 - s3c_gpio_setpull(S5PC100_GPD(5), 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); 26 + s3c_gpio_cfgall_range(S5PC100_GPD(5), 2, 27 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 30 28 }
+14 -27
arch/arm/mach-s5pc100/setup-ide.c
··· 17 17 #include <mach/regs-clock.h> 18 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 28 void s5pc100_ide_setup_gpio(void) 21 29 { 22 30 u32 reg; 23 - u32 gpio = 0; 24 31 25 32 /* Independent CF interface, CF chip select configuration */ 26 33 reg = readl(S5PC100_MEM_SYS_CFG) & (~0x3f); 27 34 writel(reg | MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S5PC100_MEM_SYS_CFG); 28 35 29 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++) { 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 - } 37 + s5pc100_ide_cfg_gpios(S5PC100_GPJ0(0), 8); 35 38 36 39 /*CF_Data[0 - 7] */ 37 - for (gpio = S5PC100_GPJ2(0); gpio <= S5PC100_GPJ2(7); gpio++) { 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 - } 40 + s5pc100_ide_cfg_gpios(S5PC100_GPJ2(0), 8); 42 41 43 42 /* CF_Data[8 - 15] */ 44 - for (gpio = S5PC100_GPJ3(0); gpio <= S5PC100_GPJ3(7); gpio++) { 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 - } 43 + s5pc100_ide_cfg_gpios(S5PC100_GPJ3(0), 8); 49 44 50 45 /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */ 51 - for (gpio = S5PC100_GPJ4(0); gpio <= S5PC100_GPJ4(3); gpio++) { 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 - } 46 + s5pc100_ide_cfg_gpios(S5PC100_GPJ4(0), 4); 56 47 57 48 /* EBI_OE, EBI_WE */ 58 - for (gpio = S5PC100_GPK0(6); gpio <= S5PC100_GPK0(7); gpio++) 59 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0)); 49 + s3c_gpio_cfgpin_range(S5PC100_GPK0(6), 2, S3C_GPIO_SFN(0)); 60 50 61 51 /* CF_OE, CF_WE */ 62 - for (gpio = S5PC100_GPK1(6); gpio <= S5PC100_GPK1(7); gpio++) { 63 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 64 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 65 - } 52 + s3c_gpio_cfgrange_nopull(S5PC100_GPK1(6), 8, S3C_GPIO_SFN(2)); 66 53 67 54 /* CF_CD */ 68 55 s3c_gpio_cfgpin(S5PC100_GPK3(5), S3C_GPIO_SFN(2));
+2 -13
arch/arm/mach-s5pc100/setup-keypad.c
··· 15 15 16 16 void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) 17 17 { 18 - unsigned int gpio; 19 - unsigned int end; 20 - 21 18 /* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */ 22 - end = S5PC100_GPH3(rows); 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 - } 19 + s3c_gpio_cfgrange_nopull(S5PC100_GPH3(0), rows, S3C_GPIO_SFN(3)); 27 20 28 21 /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */ 29 - end = S5PC100_GPH2(cols); 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 - } 22 + s3c_gpio_cfgrange_nopull(S5PC100_GPH2(0), cols, S3C_GPIO_SFN(3)); 34 23 }
+5 -30
arch/arm/mach-s5pc100/setup-sdhci-gpio.c
··· 25 25 void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) 26 26 { 27 27 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 28 - unsigned int gpio; 29 - unsigned int end; 30 28 unsigned int num; 31 29 32 30 num = width; ··· 32 34 if (width == 8) 33 35 num = width - 2; 34 36 35 - end = S5PC100_GPG0(2 + num); 36 - 37 37 /* Set all the necessary GPG0/GPG1 pins to special-function 0 */ 38 - for (gpio = S5PC100_GPG0(0); gpio < end; gpio++) { 39 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 40 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 41 - } 38 + s3c_gpio_cfgrange_nopull(S5PC100_GPG0(0), 2 + num, S3C_GPIO_SFN(2)); 42 39 43 - if (width == 8) { 44 - for (gpio = S5PC100_GPG1(0); gpio <= S5PC100_GPG1(1); gpio++) { 45 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 46 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 47 - } 48 - } 40 + if (width == 8) 41 + s3c_gpio_cfgrange_nopull(S5PC100_GPG1(0), 2, S3C_GPIO_SFN(2)); 49 42 50 43 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 51 44 s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP); ··· 47 58 void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) 48 59 { 49 60 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 50 - unsigned int gpio; 51 - unsigned int end; 52 - 53 - end = S5PC100_GPG2(2 + width); 54 61 55 62 /* Set all the necessary GPG2 pins to special-function 2 */ 56 - for (gpio = S5PC100_GPG2(0); gpio < end; gpio++) { 57 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 58 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 59 - } 63 + s3c_gpio_cfgrange_nopull(S5PC100_GPG2(0), 2 + width, S3C_GPIO_SFN(2)); 60 64 61 65 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 62 66 s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP); ··· 60 78 void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) 61 79 { 62 80 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 63 - unsigned int gpio; 64 - unsigned int end; 65 - 66 - end = S5PC100_GPG3(2 + width); 67 81 68 82 /* Set all the necessary GPG3 pins to special-function 2 */ 69 - for (gpio = S5PC100_GPG3(0); gpio < end; gpio++) { 70 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 71 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 72 - } 83 + s3c_gpio_cfgrange_nopull(S5PC100_GPG3(0), 2 + width, S3C_GPIO_SFN(2)); 73 84 74 85 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 75 86 s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
+32 -5
arch/arm/mach-s5pv210/Kconfig
··· 11 11 12 12 config CPU_S5PV210 13 13 bool 14 - select PLAT_S5P 15 14 select S3C_PL330_DMA 16 15 select S5P_EXT_INT 16 + select S5PV210_PM if PM 17 17 help 18 18 Enable S5PV210 CPU support 19 19 ··· 58 58 config MACH_AQUILA 59 59 bool "Aquila" 60 60 select CPU_S5PV210 61 - select ARCH_SPARSEMEM_ENABLE 62 61 select S3C_DEV_FB 63 62 select S5P_DEV_FIMC0 64 63 select S5P_DEV_FIMC1 ··· 74 75 config MACH_GONI 75 76 bool "GONI" 76 77 select CPU_S5PV210 77 - select ARCH_SPARSEMEM_ENABLE 78 + select S5P_GPIO_INT 78 79 select S3C_DEV_FB 79 80 select S5P_DEV_FIMC0 80 81 select S5P_DEV_FIMC1 ··· 82 83 select S3C_DEV_HSMMC 83 84 select S3C_DEV_HSMMC1 84 85 select S3C_DEV_HSMMC2 86 + select S3C_DEV_I2C1 87 + select S3C_DEV_I2C2 88 + select S3C_DEV_USB_HSOTG 85 89 select S5P_DEV_ONENAND 90 + select SAMSUNG_DEV_KEYPAD 86 91 select S5PV210_SETUP_FB_24BPP 92 + select S5PV210_SETUP_I2C1 93 + select S5PV210_SETUP_I2C2 94 + select S5PV210_SETUP_KEYPAD 87 95 select S5PV210_SETUP_SDHCI 88 96 help 89 97 Machine support for Samsung GONI board ··· 99 93 config MACH_SMDKC110 100 94 bool "SMDKC110" 101 95 select CPU_S5PV210 102 - select ARCH_SPARSEMEM_ENABLE 103 96 select S3C_DEV_I2C1 104 97 select S3C_DEV_I2C2 105 98 select S3C_DEV_RTC ··· 118 113 config MACH_SMDKV210 119 114 bool "SMDKV210" 120 115 select CPU_S5PV210 121 - select ARCH_SPARSEMEM_ENABLE 122 116 select S3C_DEV_HSMMC 123 117 select S3C_DEV_HSMMC1 124 118 select S3C_DEV_HSMMC2 ··· 138 134 help 139 135 Machine support for Samsung SMDKV210 140 136 137 + config MACH_TORBRECK 138 + bool "Torbreck" 139 + select CPU_S5PV210 140 + select ARCH_SPARSEMEM_ENABLE 141 + select S3C_DEV_HSMMC 142 + select S3C_DEV_HSMMC1 143 + select S3C_DEV_HSMMC2 144 + select S3C_DEV_HSMMC3 145 + select S3C_DEV_I2C1 146 + select S3C_DEV_I2C2 147 + select S3C_DEV_RTC 148 + select S3C_DEV_WDT 149 + select S5PV210_SETUP_I2C1 150 + select S5PV210_SETUP_I2C2 151 + select S5PV210_SETUP_SDHCI 152 + help 153 + Machine support for aESOP Torbreck 154 + 141 155 endmenu 156 + 157 + config S5PV210_PM 158 + bool 159 + help 160 + Power Management code common to S5PV210 142 161 143 162 endif
+3
arch/arm/mach-s5pv210/Makefile
··· 14 14 15 15 obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o 16 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 20 # machine support 19 21 ··· 23 21 obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o 24 22 obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o 25 23 obj-$(CONFIG_MACH_GONI) += mach-goni.o 24 + obj-$(CONFIG_MACH_TORBRECK) += mach-torbreck.o 26 25 27 26 # device support 28 27
+195 -12
arch/arm/mach-s5pv210/clock.c
··· 31 31 #include <plat/clock-clksrc.h> 32 32 #include <plat/s5pv210.h> 33 33 34 + static unsigned long xtal; 35 + 34 36 static struct clksrc_clk clk_mout_apll = { 35 37 .clk = { 36 38 .name = "mout_apll", ··· 261 259 .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 }, 262 260 }; 263 261 262 + static struct clk *clkset_moutdmc0src_list[] = { 263 + [0] = &clk_sclk_a2m.clk, 264 + [1] = &clk_mout_mpll.clk, 265 + [2] = NULL, 266 + [3] = NULL, 267 + }; 268 + 269 + static struct clksrc_sources clkset_moutdmc0src = { 270 + .sources = clkset_moutdmc0src_list, 271 + .nr_sources = ARRAY_SIZE(clkset_moutdmc0src_list), 272 + }; 273 + 274 + static struct clksrc_clk clk_mout_dmc0 = { 275 + .clk = { 276 + .name = "mout_dmc0", 277 + .id = -1, 278 + }, 279 + .sources = &clkset_moutdmc0src, 280 + .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 }, 281 + }; 282 + 283 + static struct clksrc_clk clk_sclk_dmc0 = { 284 + .clk = { 285 + .name = "sclk_dmc0", 286 + .id = -1, 287 + .parent = &clk_mout_dmc0.clk, 288 + }, 289 + .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 }, 290 + }; 291 + 264 292 static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk) 265 293 { 266 294 return clk_get_rate(clk->parent) / 2; ··· 300 268 .get_rate = s5pv210_clk_imem_get_rate, 301 269 }; 302 270 271 + static unsigned long s5pv210_clk_fout_apll_get_rate(struct clk *clk) 272 + { 273 + return s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508); 274 + } 275 + 276 + static struct clk_ops clk_fout_apll_ops = { 277 + .get_rate = s5pv210_clk_fout_apll_get_rate, 278 + }; 279 + 303 280 static struct clk init_clocks_disable[] = { 304 281 { 282 + .name = "pdma", 283 + .id = 0, 284 + .parent = &clk_hclk_psys.clk, 285 + .enable = s5pv210_clk_ip0_ctrl, 286 + .ctrlbit = (1 << 3), 287 + }, { 288 + .name = "pdma", 289 + .id = 1, 290 + .parent = &clk_hclk_psys.clk, 291 + .enable = s5pv210_clk_ip0_ctrl, 292 + .ctrlbit = (1 << 4), 293 + }, { 305 294 .name = "rot", 306 295 .id = -1, 307 296 .parent = &clk_hclk_dsys.clk, ··· 484 431 .parent = &clk_p, 485 432 .enable = s5pv210_clk_ip3_ctrl, 486 433 .ctrlbit = (1 << 6), 434 + }, { 435 + .name = "spdif", 436 + .id = -1, 437 + .parent = &clk_p, 438 + .enable = s5pv210_clk_ip3_ctrl, 439 + .ctrlbit = (1 << 0), 487 440 }, 488 441 }; 489 442 ··· 719 660 .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list), 720 661 }; 721 662 663 + static int s5pv210_spdif_set_rate(struct clk *clk, unsigned long rate) 664 + { 665 + struct clk *pclk; 666 + int ret; 667 + 668 + pclk = clk_get_parent(clk); 669 + if (IS_ERR(pclk)) 670 + return -EINVAL; 671 + 672 + ret = pclk->ops->set_rate(pclk, rate); 673 + clk_put(pclk); 674 + 675 + return ret; 676 + } 677 + 678 + static unsigned long s5pv210_spdif_get_rate(struct clk *clk) 679 + { 680 + struct clk *pclk; 681 + int rate; 682 + 683 + pclk = clk_get_parent(clk); 684 + if (IS_ERR(pclk)) 685 + return -EINVAL; 686 + 687 + rate = pclk->ops->get_rate(clk); 688 + clk_put(pclk); 689 + 690 + return rate; 691 + } 692 + 693 + static struct clk_ops s5pv210_sclk_spdif_ops = { 694 + .set_rate = s5pv210_spdif_set_rate, 695 + .get_rate = s5pv210_spdif_get_rate, 696 + }; 697 + 698 + static struct clksrc_clk clk_sclk_spdif = { 699 + .clk = { 700 + .name = "sclk_spdif", 701 + .id = -1, 702 + .enable = s5pv210_clk_mask0_ctrl, 703 + .ctrlbit = (1 << 27), 704 + .ops = &s5pv210_sclk_spdif_ops, 705 + }, 706 + .sources = &clkset_sclk_spdif, 707 + .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 }, 708 + }; 709 + 722 710 static struct clk *clkset_group2_list[] = { 723 711 [0] = &clk_ext_xtal_mux, 724 712 [1] = &clk_xusbxti, ··· 849 743 }, 850 744 .sources = &clkset_sclk_mixer, 851 745 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 }, 852 - }, { 853 - .clk = { 854 - .name = "sclk_spdif", 855 - .id = -1, 856 - .enable = s5pv210_clk_mask0_ctrl, 857 - .ctrlbit = (1 << 27), 858 - }, 859 - .sources = &clkset_sclk_spdif, 860 - .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 }, 861 746 }, { 862 747 .clk = { 863 748 .name = "sclk_fimc", ··· 1050 953 &clk_sclk_dac, 1051 954 &clk_sclk_pixel, 1052 955 &clk_sclk_hdmi, 956 + &clk_mout_dmc0, 957 + &clk_sclk_dmc0, 958 + &clk_sclk_audio0, 959 + &clk_sclk_audio1, 960 + &clk_sclk_audio2, 961 + &clk_sclk_spdif, 962 + }; 963 + 964 + static u32 epll_div[][6] = { 965 + { 48000000, 0, 48, 3, 3, 0 }, 966 + { 96000000, 0, 48, 3, 2, 0 }, 967 + { 144000000, 1, 72, 3, 2, 0 }, 968 + { 192000000, 0, 48, 3, 1, 0 }, 969 + { 288000000, 1, 72, 3, 1, 0 }, 970 + { 32750000, 1, 65, 3, 4, 35127 }, 971 + { 32768000, 1, 65, 3, 4, 35127 }, 972 + { 45158400, 0, 45, 3, 3, 10355 }, 973 + { 45000000, 0, 45, 3, 3, 10355 }, 974 + { 45158000, 0, 45, 3, 3, 10355 }, 975 + { 49125000, 0, 49, 3, 3, 9961 }, 976 + { 49152000, 0, 49, 3, 3, 9961 }, 977 + { 67737600, 1, 67, 3, 3, 48366 }, 978 + { 67738000, 1, 67, 3, 3, 48366 }, 979 + { 73800000, 1, 73, 3, 3, 47710 }, 980 + { 73728000, 1, 73, 3, 3, 47710 }, 981 + { 36000000, 1, 32, 3, 4, 0 }, 982 + { 60000000, 1, 60, 3, 3, 0 }, 983 + { 72000000, 1, 72, 3, 3, 0 }, 984 + { 80000000, 1, 80, 3, 3, 0 }, 985 + { 84000000, 0, 42, 3, 2, 0 }, 986 + { 50000000, 0, 50, 3, 3, 0 }, 987 + }; 988 + 989 + static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate) 990 + { 991 + unsigned int epll_con, epll_con_k; 992 + unsigned int i; 993 + 994 + /* Return if nothing changed */ 995 + if (clk->rate == rate) 996 + return 0; 997 + 998 + epll_con = __raw_readl(S5P_EPLL_CON); 999 + epll_con_k = __raw_readl(S5P_EPLL_CON1); 1000 + 1001 + epll_con_k &= ~PLL46XX_KDIV_MASK; 1002 + epll_con &= ~(1 << 27 | 1003 + PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | 1004 + PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | 1005 + PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT); 1006 + 1007 + for (i = 0; i < ARRAY_SIZE(epll_div); i++) { 1008 + if (epll_div[i][0] == rate) { 1009 + epll_con_k |= epll_div[i][5] << 0; 1010 + epll_con |= (epll_div[i][1] << 27 | 1011 + epll_div[i][2] << PLL46XX_MDIV_SHIFT | 1012 + epll_div[i][3] << PLL46XX_PDIV_SHIFT | 1013 + epll_div[i][4] << PLL46XX_SDIV_SHIFT); 1014 + break; 1015 + } 1016 + } 1017 + 1018 + if (i == ARRAY_SIZE(epll_div)) { 1019 + printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", 1020 + __func__); 1021 + return -EINVAL; 1022 + } 1023 + 1024 + __raw_writel(epll_con, S5P_EPLL_CON); 1025 + __raw_writel(epll_con_k, S5P_EPLL_CON1); 1026 + 1027 + printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n", 1028 + clk->rate, rate); 1029 + 1030 + clk->rate = rate; 1031 + 1032 + return 0; 1033 + } 1034 + 1035 + static struct clk_ops s5pv210_epll_ops = { 1036 + .set_rate = s5pv210_epll_set_rate, 1037 + .get_rate = s5p_epll_get_rate, 1053 1038 }; 1054 1039 1055 1040 void __init_or_cpufreq s5pv210_setup_clocks(void) 1056 1041 { 1057 1042 struct clk *xtal_clk; 1058 - unsigned long xtal; 1059 1043 unsigned long vpllsrc; 1060 1044 unsigned long armclk; 1061 1045 unsigned long hclk_msys; ··· 1151 973 unsigned long vpll; 1152 974 unsigned int ptr; 1153 975 u32 clkdiv0, clkdiv1; 976 + 977 + /* Set functions for clk_fout_epll */ 978 + clk_fout_epll.enable = s5p_epll_enable; 979 + clk_fout_epll.ops = &s5pv210_epll_ops; 1154 980 1155 981 printk(KERN_DEBUG "%s: registering clocks\n", __func__); 1156 982 ··· 1174 992 1175 993 apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508); 1176 994 mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); 1177 - epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500); 995 + epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON), 996 + __raw_readl(S5P_EPLL_CON1), pll_4600); 1178 997 vpllsrc = clk_get_rate(&clk_vpllsrc.clk); 1179 998 vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502); 1180 999 1181 - clk_fout_apll.rate = apll; 1000 + clk_fout_apll.ops = &clk_fout_apll_ops; 1182 1001 clk_fout_mpll.rate = mpll; 1183 1002 clk_fout_epll.rate = epll; 1184 1003 clk_fout_vpll.rate = vpll;
+15
arch/arm/mach-s5pv210/cpu.c
··· 85 85 .pfn = __phys_to_pfn(S5PV210_PA_SROMC), 86 86 .length = SZ_4K, 87 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
+484
arch/arm/mach-s5pv210/cpufreq.c
··· 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);
+47 -39
arch/arm/mach-s5pv210/dev-audio.c
··· 24 24 /* configure GPIO for i2s port */ 25 25 switch (pdev->id) { 26 26 case 1: 27 - s3c_gpio_cfgpin(S5PV210_GPC0(0), 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)); 27 + s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2)); 32 28 break; 33 29 34 30 case 2: 35 - s3c_gpio_cfgpin(S5PV210_GPC1(0), 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)); 31 + s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4)); 40 32 break; 41 33 42 34 case -1: 43 - s3c_gpio_cfgpin(S5PV210_GPI(0), 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)); 35 + s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2)); 50 36 break; 51 37 52 38 default: ··· 137 151 { 138 152 switch (pdev->id) { 139 153 case 0: 140 - s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(3)); 141 - s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(3)); 142 - s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(3)); 143 - s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(3)); 144 - s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(3)); 154 + s3c_gpio_cfgpin_range(S5PV210_GPI(0), 5, S3C_GPIO_SFN(3)); 145 155 break; 146 156 case 1: 147 - s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(3)); 148 - s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(3)); 149 - s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(3)); 150 - s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(3)); 151 - s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(3)); 157 + s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(3)); 152 158 break; 153 159 case 2: 154 - s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(2)); 155 - s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(2)); 156 - s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(2)); 157 - s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(2)); 158 - s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(2)); 160 + s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(2)); 159 161 break; 160 162 default: 161 163 printk(KERN_DEBUG "Invalid PCM Controller number!"); ··· 245 271 246 272 static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev) 247 273 { 248 - s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(4)); 249 - s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(4)); 250 - s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(4)); 251 - s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(4)); 252 - s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(4)); 253 - 254 - return 0; 274 + return s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(4)); 255 275 } 256 276 257 277 static struct resource s5pv210_ac97_resource[] = { ··· 290 322 .dev = { 291 323 .platform_data = &s3c_ac97_pdata, 292 324 .dma_mask = &s5pv210_ac97_dmamask, 325 + .coherent_dma_mask = DMA_BIT_MASK(32), 326 + }, 327 + }; 328 + 329 + /* S/PDIF Controller platform_device */ 330 + 331 + static int s5pv210_spdif_cfg_gpio(struct platform_device *pdev) 332 + { 333 + s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 2, S3C_GPIO_SFN(3)); 334 + 335 + return 0; 336 + } 337 + 338 + static struct resource s5pv210_spdif_resource[] = { 339 + [0] = { 340 + .start = S5PV210_PA_SPDIF, 341 + .end = S5PV210_PA_SPDIF + 0x100 - 1, 342 + .flags = IORESOURCE_MEM, 343 + }, 344 + [1] = { 345 + .start = DMACH_SPDIF, 346 + .end = DMACH_SPDIF, 347 + .flags = IORESOURCE_DMA, 348 + }, 349 + }; 350 + 351 + static struct s3c_audio_pdata samsung_spdif_pdata = { 352 + .cfg_gpio = s5pv210_spdif_cfg_gpio, 353 + }; 354 + 355 + static u64 s5pv210_spdif_dmamask = DMA_BIT_MASK(32); 356 + 357 + struct platform_device s5pv210_device_spdif = { 358 + .name = "samsung-spdif", 359 + .id = -1, 360 + .num_resources = ARRAY_SIZE(s5pv210_spdif_resource), 361 + .resource = s5pv210_spdif_resource, 362 + .dev = { 363 + .platform_data = &samsung_spdif_pdata, 364 + .dma_mask = &s5pv210_spdif_dmamask, 293 365 .coherent_dma_mask = DMA_BIT_MASK(32), 294 366 }, 295 367 };
+7 -12
arch/arm/mach-s5pv210/dev-spi.c
··· 35 35 */ 36 36 static int s5pv210_spi_cfg_gpio(struct platform_device *pdev) 37 37 { 38 + unsigned int base; 39 + 38 40 switch (pdev->id) { 39 41 case 0: 40 - s3c_gpio_cfgpin(S5PV210_GPB(0), S3C_GPIO_SFN(2)); 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); 42 + base = S5PV210_GPB(0); 46 43 break; 47 44 48 45 case 1: 49 - s3c_gpio_cfgpin(S5PV210_GPB(4), S3C_GPIO_SFN(2)); 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); 46 + base = S5PV210_GPB(4); 55 47 break; 56 48 57 49 default: 58 50 dev_err(&pdev->dev, "Invalid SPI Controller number!"); 59 51 return -EINVAL; 60 52 } 53 + 54 + s3c_gpio_cfgall_range(base, 3, 55 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 61 56 62 57 return 0; 63 58 }
+2 -2
arch/arm/mach-s5pv210/dma.c
··· 82 82 83 83 static struct platform_device s5pv210_device_pdma0 = { 84 84 .name = "s3c-pl330", 85 - .id = 1, 85 + .id = 0, 86 86 .num_resources = ARRAY_SIZE(s5pv210_pdma0_resource), 87 87 .resource = s5pv210_pdma0_resource, 88 88 .dev = { ··· 144 144 145 145 static struct platform_device s5pv210_device_pdma1 = { 146 146 .name = "s3c-pl330", 147 - .id = 2, 147 + .id = 1, 148 148 .num_resources = ARRAY_SIZE(s5pv210_pdma1_resource), 149 149 .resource = s5pv210_pdma1_resource, 150 150 .dev = {
+13 -1
arch/arm/mach-s5pv210/gpiolib.c
··· 150 150 .label = "GPG3", 151 151 }, 152 152 }, { 153 + .config = &gpio_cfg_noint, 153 154 .chip = { 154 155 .base = S5PV210_GPI(0), 155 156 .ngpio = S5PV210_GPIO_I_NR, ··· 224 223 }, { 225 224 .base = (S5P_VA_GPIO + 0xC00), 226 225 .config = &gpio_cfg_noint, 226 + .irq_base = IRQ_EINT(0), 227 227 .chip = { 228 228 .base = S5PV210_GPH0(0), 229 229 .ngpio = S5PV210_GPIO_H0_NR, 230 230 .label = "GPH0", 231 + .to_irq = samsung_gpiolib_to_irq, 231 232 }, 232 233 }, { 233 234 .base = (S5P_VA_GPIO + 0xC20), 234 235 .config = &gpio_cfg_noint, 236 + .irq_base = IRQ_EINT(8), 235 237 .chip = { 236 238 .base = S5PV210_GPH1(0), 237 239 .ngpio = S5PV210_GPIO_H1_NR, 238 240 .label = "GPH1", 241 + .to_irq = samsung_gpiolib_to_irq, 239 242 }, 240 243 }, { 241 244 .base = (S5P_VA_GPIO + 0xC40), 242 245 .config = &gpio_cfg_noint, 246 + .irq_base = IRQ_EINT(16), 243 247 .chip = { 244 248 .base = S5PV210_GPH2(0), 245 249 .ngpio = S5PV210_GPIO_H2_NR, 246 250 .label = "GPH2", 251 + .to_irq = samsung_gpiolib_to_irq, 247 252 }, 248 253 }, { 249 254 .base = (S5P_VA_GPIO + 0xC60), 250 255 .config = &gpio_cfg_noint, 256 + .irq_base = IRQ_EINT(24), 251 257 .chip = { 252 258 .base = S5PV210_GPH3(0), 253 259 .ngpio = S5PV210_GPIO_H3_NR, 254 260 .label = "GPH3", 261 + .to_irq = samsung_gpiolib_to_irq, 255 262 }, 256 263 }, 257 264 }; ··· 268 259 { 269 260 struct s3c_gpio_chip *chip = s5pv210_gpio_4bit; 270 261 int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit); 262 + int gpioint_group = 0; 271 263 int i = 0; 272 264 273 265 for (i = 0; i < nr_chips; i++, chip++) { 274 - if (chip->config == NULL) 266 + if (chip->config == NULL) { 275 267 chip->config = &gpio_cfg; 268 + chip->group = gpioint_group++; 269 + } 276 270 if (chip->base == NULL) 277 271 chip->base = S5PV210_BANK_BASE(i); 278 272 }
+8 -4
arch/arm/mach-s5pv210/include/mach/irqs.h
··· 55 55 #define IRQ_SPI1 S5P_IRQ_VIC1(16) 56 56 #define IRQ_SPI2 S5P_IRQ_VIC1(17) 57 57 #define IRQ_IRDA S5P_IRQ_VIC1(18) 58 - #define IRQ_CAN0 S5P_IRQ_VIC1(19) 59 - #define IRQ_CAN1 S5P_IRQ_VIC1(20) 58 + #define IRQ_IIC2 S5P_IRQ_VIC1(19) 59 + #define IRQ_IIC3 S5P_IRQ_VIC1(20) 60 60 #define IRQ_HSIRX S5P_IRQ_VIC1(21) 61 61 #define IRQ_HSITX S5P_IRQ_VIC1(22) 62 62 #define IRQ_UHOST S5P_IRQ_VIC1(23) ··· 109 109 110 110 #define IRQ_IPC S5P_IRQ_VIC3(0) 111 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 113 #define IRQ_CEC S5P_IRQ_VIC3(3) 114 114 #define IRQ_TSI S5P_IRQ_VIC3(4) 115 115 #define IRQ_MDNIE0 S5P_IRQ_VIC3(5) ··· 121 121 #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) 122 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 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 131 /* Compatibility */ 128 132 #define IRQ_LCD_FIFO IRQ_LCD0
+12
arch/arm/mach-s5pv210/include/mach/map.h
··· 57 57 58 58 #define S5P_SZ_UART SZ_256 59 59 60 + #define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) 61 + 60 62 #define S5PV210_PA_SROMC (0xE8000000) 61 63 62 64 #define S5PV210_PA_CFCON (0xE8200000) ··· 75 73 76 74 #define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000)) 77 75 76 + #define S5PV210_PA_HSOTG (0xEC000000) 77 + #define S5PV210_PA_HSPHY (0xEC100000) 78 + 78 79 #define S5PV210_PA_VIC0 (0xF2000000) 79 80 #define S5PV210_PA_VIC1 (0xF2100000) 80 81 #define S5PV210_PA_VIC2 (0xF2200000) ··· 85 80 86 81 #define S5PV210_PA_SDRAM (0x20000000) 87 82 #define S5P_PA_SDRAM S5PV210_PA_SDRAM 83 + 84 + /* S/PDIF */ 85 + #define S5PV210_PA_SPDIF 0xE1100000 88 86 89 87 /* I2S */ 90 88 #define S5PV210_PA_IIS0 0xEEE30000 ··· 104 96 105 97 #define S5PV210_PA_ADC (0xE1700000) 106 98 99 + #define S5PV210_PA_DMC0 (0xF0000000) 100 + #define S5PV210_PA_DMC1 (0xF1400000) 101 + 107 102 /* compatibiltiy defines. */ 108 103 #define S3C_PA_UART S5PV210_PA_UART 109 104 #define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0) ··· 119 108 #define S3C_PA_FB S5PV210_PA_FB 120 109 #define S3C_PA_RTC S5PV210_PA_RTC 121 110 #define S3C_PA_WDT S5PV210_PA_WATCHDOG 111 + #define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG 122 112 #define S5P_PA_FIMC0 S5PV210_PA_FIMC0 123 113 #define S5P_PA_FIMC1 S5PV210_PA_FIMC1 124 114 #define S5P_PA_FIMC2 S5PV210_PA_FIMC2
+43
arch/arm/mach-s5pv210/include/mach/pm-core.h
··· 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 + }
+36 -3
arch/arm/mach-s5pv210/include/mach/regs-clock.h
··· 25 25 #define S5P_APLL_CON S5P_CLKREG(0x100) 26 26 #define S5P_MPLL_CON S5P_CLKREG(0x108) 27 27 #define S5P_EPLL_CON S5P_CLKREG(0x110) 28 + #define S5P_EPLL_CON1 S5P_CLKREG(0x114) 28 29 #define S5P_VPLL_CON S5P_CLKREG(0x120) 29 30 30 31 #define S5P_CLK_SRC0 S5P_CLKREG(0x200) ··· 68 67 #define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488) 69 68 #define S5P_CLK_OUT S5P_CLKREG(0x500) 70 69 70 + /* DIV/MUX STATUS */ 71 + #define S5P_CLKDIV_STAT0 S5P_CLKREG(0x1000) 72 + #define S5P_CLKDIV_STAT1 S5P_CLKREG(0x1004) 73 + #define S5P_CLKMUX_STAT0 S5P_CLKREG(0x1100) 74 + #define S5P_CLKMUX_STAT1 S5P_CLKREG(0x1104) 75 + 71 76 /* CLKSRC0 */ 72 - #define S5P_CLKSRC0_MUX200_MASK (0x1<<16) 77 + #define S5P_CLKSRC0_MUX200_SHIFT (16) 78 + #define S5P_CLKSRC0_MUX200_MASK (0x1 << S5P_CLKSRC0_MUX200_SHIFT) 73 79 #define S5P_CLKSRC0_MUX166_MASK (0x1<<20) 74 80 #define S5P_CLKSRC0_MUX133_MASK (0x1<<24) 81 + 82 + /* CLKSRC2 */ 83 + #define S5P_CLKSRC2_G3D_SHIFT (0) 84 + #define S5P_CLKSRC2_G3D_MASK (0x3 << S5P_CLKSRC2_G3D_SHIFT) 85 + #define S5P_CLKSRC2_MFC_SHIFT (4) 86 + #define S5P_CLKSRC2_MFC_MASK (0x3 << S5P_CLKSRC2_MFC_SHIFT) 87 + 88 + /* CLKSRC6*/ 89 + #define S5P_CLKSRC6_ONEDRAM_SHIFT (24) 90 + #define S5P_CLKSRC6_ONEDRAM_MASK (0x3 << S5P_CLKSRC6_ONEDRAM_SHIFT) 75 91 76 92 /* CLKDIV0 */ 77 93 #define S5P_CLKDIV0_APLL_SHIFT (0) ··· 108 90 #define S5P_CLKDIV0_PCLK66_SHIFT (28) 109 91 #define S5P_CLKDIV0_PCLK66_MASK (0x7 << S5P_CLKDIV0_PCLK66_SHIFT) 110 92 93 + /* CLKDIV2 */ 94 + #define S5P_CLKDIV2_G3D_SHIFT (0) 95 + #define S5P_CLKDIV2_G3D_MASK (0xF << S5P_CLKDIV2_G3D_SHIFT) 96 + #define S5P_CLKDIV2_MFC_SHIFT (4) 97 + #define S5P_CLKDIV2_MFC_MASK (0xF << S5P_CLKDIV2_MFC_SHIFT) 98 + 99 + /* CLKDIV6 */ 100 + #define S5P_CLKDIV6_ONEDRAM_SHIFT (28) 101 + #define S5P_CLKDIV6_ONEDRAM_MASK (0xF << S5P_CLKDIV6_ONEDRAM_SHIFT) 102 + 111 103 #define S5P_SWRESET S5P_CLKREG(0x2000) 104 + 105 + #define S5P_ARM_MCS_CON S5P_CLKREG(0x6100) 112 106 113 107 /* Registers related to power management */ 114 108 #define S5P_PWR_CFG S5P_CLKREG(0xC000) 115 109 #define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004) 116 - #define S5P_WAKEUP_MASK S5P_CLKREG(0xC008) 110 + #define S5P_WAKEUP_MASK S5P_CLKREG(0xC008) 117 111 #define S5P_PWR_MODE S5P_CLKREG(0xC00C) 118 112 #define S5P_NORMAL_CFG S5P_CLKREG(0xC010) 119 113 #define S5P_IDLE_CFG S5P_CLKREG(0xC020) ··· 189 159 #define S5P_SLEEP_CFG_USBOSC_EN (1 << 1) 190 160 191 161 /* OTHERS Resgister */ 162 + #define S5P_OTHERS_RET_IO (1 << 31) 163 + #define S5P_OTHERS_RET_CF (1 << 30) 164 + #define S5P_OTHERS_RET_MMC (1 << 29) 165 + #define S5P_OTHERS_RET_UART (1 << 28) 192 166 #define S5P_OTHERS_USB_SIG_MASK (1 << 16) 193 - #define S5P_OTHERS_MIPI_DPHY_EN (1 << 28) 194 167 195 168 /* MIPI */ 196 169 #define S5P_MIPI_DPHY_EN (3)
-7
arch/arm/mach-s5pv210/include/mach/regs-gpio.h
··· 31 31 32 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 34 #define EINT_MODE S3C_GPIO_SFN(0xf) 42 35 43 36 #define EINT_GPIO_0(x) S5PV210_GPH0(x)
+19
arch/arm/mach-s5pv210/include/mach/regs-sys.h
··· 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
+1 -1
arch/arm/mach-s5pv210/include/mach/vmalloc.h
··· 17 17 #ifndef __ASM_ARCH_VMALLOC_H 18 18 #define __ASM_ARCH_VMALLOC_H __FILE__ 19 19 20 - #define VMALLOC_END (0xE0000000UL) 20 + #define VMALLOC_END 0xF6000000UL 21 21 22 22 #endif /* __ASM_ARCH_VMALLOC_H */
+169
arch/arm/mach-s5pv210/mach-aquila.c
··· 16 16 #include <linux/i2c.h> 17 17 #include <linux/i2c-gpio.h> 18 18 #include <linux/mfd/max8998.h> 19 + #include <linux/mfd/wm8994/pdata.h> 20 + #include <linux/regulator/fixed.h> 19 21 #include <linux/gpio_keys.h> 20 22 #include <linux/input.h> 21 23 #include <linux/gpio.h> ··· 381 379 }; 382 380 #endif 383 381 382 + static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = { 383 + { 384 + .dev_name = "5-001a", 385 + .supply = "DBVDD", 386 + }, { 387 + .dev_name = "5-001a", 388 + .supply = "AVDD2", 389 + }, { 390 + .dev_name = "5-001a", 391 + .supply = "CPVDD", 392 + }, 393 + }; 394 + 395 + static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = { 396 + { 397 + .dev_name = "5-001a", 398 + .supply = "SPKVDD1", 399 + }, { 400 + .dev_name = "5-001a", 401 + .supply = "SPKVDD2", 402 + }, 403 + }; 404 + 405 + static struct regulator_init_data wm8994_fixed_voltage0_init_data = { 406 + .constraints = { 407 + .always_on = 1, 408 + }, 409 + .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies), 410 + .consumer_supplies = wm8994_fixed_voltage0_supplies, 411 + }; 412 + 413 + static struct regulator_init_data wm8994_fixed_voltage1_init_data = { 414 + .constraints = { 415 + .always_on = 1, 416 + }, 417 + .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies), 418 + .consumer_supplies = wm8994_fixed_voltage1_supplies, 419 + }; 420 + 421 + static struct fixed_voltage_config wm8994_fixed_voltage0_config = { 422 + .supply_name = "VCC_1.8V_PDA", 423 + .microvolts = 1800000, 424 + .gpio = -EINVAL, 425 + .init_data = &wm8994_fixed_voltage0_init_data, 426 + }; 427 + 428 + static struct fixed_voltage_config wm8994_fixed_voltage1_config = { 429 + .supply_name = "V_BAT", 430 + .microvolts = 3700000, 431 + .gpio = -EINVAL, 432 + .init_data = &wm8994_fixed_voltage1_init_data, 433 + }; 434 + 435 + static struct platform_device wm8994_fixed_voltage0 = { 436 + .name = "reg-fixed-voltage", 437 + .id = 0, 438 + .dev = { 439 + .platform_data = &wm8994_fixed_voltage0_config, 440 + }, 441 + }; 442 + 443 + static struct platform_device wm8994_fixed_voltage1 = { 444 + .name = "reg-fixed-voltage", 445 + .id = 1, 446 + .dev = { 447 + .platform_data = &wm8994_fixed_voltage1_config, 448 + }, 449 + }; 450 + 451 + static struct regulator_consumer_supply wm8994_avdd1_supply = { 452 + .dev_name = "5-001a", 453 + .supply = "AVDD1", 454 + }; 455 + 456 + static struct regulator_consumer_supply wm8994_dcvdd_supply = { 457 + .dev_name = "5-001a", 458 + .supply = "DCVDD", 459 + }; 460 + 461 + static struct regulator_init_data wm8994_ldo1_data = { 462 + .constraints = { 463 + .name = "AVDD1_3.0V", 464 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 465 + }, 466 + .num_consumer_supplies = 1, 467 + .consumer_supplies = &wm8994_avdd1_supply, 468 + }; 469 + 470 + static struct regulator_init_data wm8994_ldo2_data = { 471 + .constraints = { 472 + .name = "DCVDD_1.0V", 473 + }, 474 + .num_consumer_supplies = 1, 475 + .consumer_supplies = &wm8994_dcvdd_supply, 476 + }; 477 + 478 + static struct wm8994_pdata wm8994_platform_data = { 479 + /* configure gpio1 function: 0x0001(Logic level input/output) */ 480 + .gpio_defaults[0] = 0x0001, 481 + /* configure gpio3/4/5/7 function for AIF2 voice */ 482 + .gpio_defaults[2] = 0x8100, 483 + .gpio_defaults[3] = 0x8100, 484 + .gpio_defaults[4] = 0x8100, 485 + .gpio_defaults[6] = 0x0100, 486 + /* configure gpio8/9/10/11 function for AIF3 BT */ 487 + .gpio_defaults[7] = 0x8100, 488 + .gpio_defaults[8] = 0x0100, 489 + .gpio_defaults[9] = 0x0100, 490 + .gpio_defaults[10] = 0x0100, 491 + .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */ 492 + .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, 493 + }; 494 + 384 495 /* GPIO I2C PMIC */ 385 496 #define AP_I2C_GPIO_PMIC_BUS_4 4 386 497 static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = { ··· 517 402 .platform_data = &aquila_max8998_pdata, 518 403 }, 519 404 #endif 405 + }; 406 + 407 + /* GPIO I2C AP 1.8V */ 408 + #define AP_I2C_GPIO_BUS_5 5 409 + static struct i2c_gpio_platform_data aquila_i2c_gpio5_data = { 410 + .sda_pin = S5PV210_MP05(3), /* XM0ADDR_11 */ 411 + .scl_pin = S5PV210_MP05(2), /* XM0ADDR_10 */ 412 + }; 413 + 414 + static struct platform_device aquila_i2c_gpio5 = { 415 + .name = "i2c-gpio", 416 + .id = AP_I2C_GPIO_BUS_5, 417 + .dev = { 418 + .platform_data = &aquila_i2c_gpio5_data, 419 + }, 420 + }; 421 + 422 + static struct i2c_board_info i2c_gpio5_devs[] __initdata = { 423 + { 424 + /* CS/ADDR = low 0x34 (FYI: high = 0x36) */ 425 + I2C_BOARD_INFO("wm8994", 0x1a), 426 + .platform_data = &wm8994_platform_data, 427 + }, 520 428 }; 521 429 522 430 /* PMIC Power button */ ··· 613 475 614 476 static struct platform_device *aquila_devices[] __initdata = { 615 477 &aquila_i2c_gpio_pmic, 478 + &aquila_i2c_gpio5, 616 479 &aquila_device_gpiokeys, 617 480 &s3c_device_fb, 618 481 &s5p_device_onenand, ··· 623 484 &s5p_device_fimc0, 624 485 &s5p_device_fimc1, 625 486 &s5p_device_fimc2, 487 + &s5pv210_device_iis0, 488 + &wm8994_fixed_voltage0, 489 + &wm8994_fixed_voltage1, 626 490 }; 491 + 492 + static void __init aquila_sound_init(void) 493 + { 494 + unsigned int gpio; 495 + 496 + /* CODEC_XTAL_EN 497 + * 498 + * The Aquila board have a oscillator which provide main clock 499 + * to WM8994 codec. The oscillator provide 24MHz clock to WM8994 500 + * clock. Set gpio setting of "CODEC_XTAL_EN" to enable a oscillator. 501 + * */ 502 + gpio = S5PV210_GPH3(2); /* XEINT_26 */ 503 + gpio_request(gpio, "CODEC_XTAL_EN"); 504 + s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT); 505 + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 506 + 507 + /* Ths main clock of WM8994 codec uses the output of CLKOUT pin. 508 + * The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS) 509 + * because it needs 24MHz clock to operate WM8994 codec. 510 + */ 511 + __raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS); 512 + } 627 513 628 514 static void __init aquila_map_io(void) 629 515 { ··· 669 505 s3c_fimc_setname(0, "s5p-fimc"); 670 506 s3c_fimc_setname(1, "s5p-fimc"); 671 507 s3c_fimc_setname(2, "s5p-fimc"); 508 + 509 + /* SOUND */ 510 + aquila_sound_init(); 511 + i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs, 512 + ARRAY_SIZE(i2c_gpio5_devs)); 672 513 673 514 /* FB */ 674 515 s3c_fb_set_platdata(&aquila_lcd_pdata);
+375 -6
arch/arm/mach-s5pv210/mach-goni.c
··· 15 15 #include <linux/fb.h> 16 16 #include <linux/i2c.h> 17 17 #include <linux/i2c-gpio.h> 18 + #include <linux/i2c/qt602240_ts.h> 18 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 25 #include <linux/gpio_keys.h> 20 26 #include <linux/input.h> 21 27 #include <linux/gpio.h> ··· 41 35 #include <plat/devs.h> 42 36 #include <plat/cpu.h> 43 37 #include <plat/fb.h> 38 + #include <plat/iic.h> 39 + #include <plat/keypad.h> 44 40 #include <plat/sdhci.h> 41 + #include <plat/clock.h> 45 42 46 43 /* Following are default values for UCON, ULCON and UFCON UART registers */ 47 44 #define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ ··· 96 87 /* Frame Buffer */ 97 88 static struct s3c_fb_pd_win goni_fb_win0 = { 98 89 .win_mode = { 99 - .pixclock = 1000000000000ULL / ((16+16+2+480)*(28+3+2+800)*55), 100 90 .left_margin = 16, 101 91 .right_margin = 16, 102 - .upper_margin = 3, 92 + .upper_margin = 2, 103 93 .lower_margin = 28, 104 94 .hsync_len = 2, 105 - .vsync_len = 2, 95 + .vsync_len = 1, 106 96 .xres = 480, 107 97 .yres = 800, 108 98 .refresh = 55, ··· 119 111 .setup_gpio = s5pv210_fb_gpio_setup_24bpp, 120 112 }; 121 113 114 + static int lcd_power_on(struct lcd_device *ld, int enable) 115 + { 116 + return 1; 117 + } 118 + 119 + static int reset_lcd(struct lcd_device *ld) 120 + { 121 + static unsigned int first = 1; 122 + int reset_gpio = -1; 123 + 124 + reset_gpio = S5PV210_MP05(5); 125 + 126 + if (first) { 127 + gpio_request(reset_gpio, "MLCD_RST"); 128 + first = 0; 129 + } 130 + 131 + gpio_direction_output(reset_gpio, 1); 132 + return 1; 133 + } 134 + 135 + static struct lcd_platform_data goni_lcd_platform_data = { 136 + .reset = reset_lcd, 137 + .power_on = lcd_power_on, 138 + .lcd_enabled = 0, 139 + .reset_delay = 120, /* 120ms */ 140 + .power_on_delay = 25, /* 25ms */ 141 + .power_off_delay = 200, /* 200ms */ 142 + }; 143 + 144 + #define LCD_BUS_NUM 3 145 + static struct spi_board_info spi_board_info[] __initdata = { 146 + { 147 + .modalias = "s6e63m0", 148 + .platform_data = &goni_lcd_platform_data, 149 + .max_speed_hz = 1200000, 150 + .bus_num = LCD_BUS_NUM, 151 + .chip_select = 0, 152 + .mode = SPI_MODE_3, 153 + .controller_data = (void *)S5PV210_MP01(1), /* DISPLAY_CS */ 154 + }, 155 + }; 156 + 157 + static struct spi_gpio_platform_data lcd_spi_gpio_data = { 158 + .sck = S5PV210_MP04(1), /* DISPLAY_CLK */ 159 + .mosi = S5PV210_MP04(3), /* DISPLAY_SI */ 160 + .miso = SPI_GPIO_NO_MISO, 161 + .num_chipselect = 1, 162 + }; 163 + 164 + static struct platform_device goni_spi_gpio = { 165 + .name = "spi_gpio", 166 + .id = LCD_BUS_NUM, 167 + .dev = { 168 + .parent = &s3c_device_fb.dev, 169 + .platform_data = &lcd_spi_gpio_data, 170 + }, 171 + }; 172 + 173 + /* KEYPAD */ 174 + static uint32_t keymap[] __initdata = { 175 + /* KEY(row, col, keycode) */ 176 + KEY(0, 1, KEY_MENU), /* Send */ 177 + KEY(0, 2, KEY_BACK), /* End */ 178 + KEY(1, 1, KEY_CONFIG), /* Half shot */ 179 + KEY(1, 2, KEY_VOLUMEUP), 180 + KEY(2, 1, KEY_CAMERA), /* Full shot */ 181 + KEY(2, 2, KEY_VOLUMEDOWN), 182 + }; 183 + 184 + static struct matrix_keymap_data keymap_data __initdata = { 185 + .keymap = keymap, 186 + .keymap_size = ARRAY_SIZE(keymap), 187 + }; 188 + 189 + static struct samsung_keypad_platdata keypad_data __initdata = { 190 + .keymap_data = &keymap_data, 191 + .rows = 3, 192 + .cols = 3, 193 + }; 194 + 195 + /* Radio */ 196 + static struct i2c_board_info i2c1_devs[] __initdata = { 197 + { 198 + I2C_BOARD_INFO("si470x", 0x10), 199 + }, 200 + }; 201 + 202 + static void __init goni_radio_init(void) 203 + { 204 + int gpio; 205 + 206 + gpio = S5PV210_GPJ2(4); /* XMSMDATA_4 */ 207 + gpio_request(gpio, "FM_INT"); 208 + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); 209 + i2c1_devs[0].irq = gpio_to_irq(gpio); 210 + 211 + gpio = S5PV210_GPJ2(5); /* XMSMDATA_5 */ 212 + gpio_request(gpio, "FM_RST"); 213 + gpio_direction_output(gpio, 1); 214 + } 215 + 216 + /* TSP */ 217 + static struct qt602240_platform_data qt602240_platform_data = { 218 + .x_line = 17, 219 + .y_line = 11, 220 + .x_size = 800, 221 + .y_size = 480, 222 + .blen = 0x21, 223 + .threshold = 0x28, 224 + .voltage = 2800000, /* 2.8V */ 225 + .orient = QT602240_DIAGONAL, 226 + }; 227 + 228 + static struct s3c2410_platform_i2c i2c2_data __initdata = { 229 + .flags = 0, 230 + .bus_num = 2, 231 + .slave_addr = 0x10, 232 + .frequency = 400 * 1000, 233 + .sda_delay = 100, 234 + }; 235 + 236 + static struct i2c_board_info i2c2_devs[] __initdata = { 237 + { 238 + I2C_BOARD_INFO("qt602240_ts", 0x4a), 239 + .platform_data = &qt602240_platform_data, 240 + }, 241 + }; 242 + 243 + static void __init goni_tsp_init(void) 244 + { 245 + int gpio; 246 + 247 + gpio = S5PV210_GPJ1(3); /* XMSMADDR_11 */ 248 + gpio_request(gpio, "TSP_LDO_ON"); 249 + gpio_direction_output(gpio, 1); 250 + gpio_export(gpio, 0); 251 + 252 + gpio = S5PV210_GPJ0(5); /* XMSMADDR_5 */ 253 + gpio_request(gpio, "TSP_INT"); 254 + 255 + s5p_register_gpio_interrupt(gpio); 256 + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf)); 257 + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); 258 + i2c2_devs[0].irq = gpio_to_irq(gpio); 259 + } 260 + 122 261 /* MAX8998 regulators */ 123 262 #if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE) 263 + 264 + static struct regulator_consumer_supply goni_ldo5_consumers[] = { 265 + REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"), 266 + }; 124 267 125 268 static struct regulator_init_data goni_ldo2_data = { 126 269 .constraints = { ··· 312 153 .max_uV = 2800000, 313 154 .apply_uV = 1, 314 155 }, 156 + .num_consumer_supplies = ARRAY_SIZE(goni_ldo5_consumers), 157 + .consumer_supplies = goni_ldo5_consumers, 315 158 }; 316 159 317 160 static struct regulator_init_data goni_ldo6_data = { ··· 521 360 }; 522 361 #endif 523 362 363 + static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = { 364 + { 365 + .dev_name = "5-001a", 366 + .supply = "DBVDD", 367 + }, { 368 + .dev_name = "5-001a", 369 + .supply = "AVDD2", 370 + }, { 371 + .dev_name = "5-001a", 372 + .supply = "CPVDD", 373 + }, 374 + }; 375 + 376 + static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = { 377 + { 378 + .dev_name = "5-001a", 379 + .supply = "SPKVDD1", 380 + }, { 381 + .dev_name = "5-001a", 382 + .supply = "SPKVDD2", 383 + }, 384 + }; 385 + 386 + static struct regulator_init_data wm8994_fixed_voltage0_init_data = { 387 + .constraints = { 388 + .always_on = 1, 389 + }, 390 + .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies), 391 + .consumer_supplies = wm8994_fixed_voltage0_supplies, 392 + }; 393 + 394 + static struct regulator_init_data wm8994_fixed_voltage1_init_data = { 395 + .constraints = { 396 + .always_on = 1, 397 + }, 398 + .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies), 399 + .consumer_supplies = wm8994_fixed_voltage1_supplies, 400 + }; 401 + 402 + static struct fixed_voltage_config wm8994_fixed_voltage0_config = { 403 + .supply_name = "VCC_1.8V_PDA", 404 + .microvolts = 1800000, 405 + .gpio = -EINVAL, 406 + .init_data = &wm8994_fixed_voltage0_init_data, 407 + }; 408 + 409 + static struct fixed_voltage_config wm8994_fixed_voltage1_config = { 410 + .supply_name = "V_BAT", 411 + .microvolts = 3700000, 412 + .gpio = -EINVAL, 413 + .init_data = &wm8994_fixed_voltage1_init_data, 414 + }; 415 + 416 + static struct platform_device wm8994_fixed_voltage0 = { 417 + .name = "reg-fixed-voltage", 418 + .id = 0, 419 + .dev = { 420 + .platform_data = &wm8994_fixed_voltage0_config, 421 + }, 422 + }; 423 + 424 + static struct platform_device wm8994_fixed_voltage1 = { 425 + .name = "reg-fixed-voltage", 426 + .id = 1, 427 + .dev = { 428 + .platform_data = &wm8994_fixed_voltage1_config, 429 + }, 430 + }; 431 + 432 + static struct regulator_consumer_supply wm8994_avdd1_supply = { 433 + .dev_name = "5-001a", 434 + .supply = "AVDD1", 435 + }; 436 + 437 + static struct regulator_consumer_supply wm8994_dcvdd_supply = { 438 + .dev_name = "5-001a", 439 + .supply = "DCVDD", 440 + }; 441 + 442 + static struct regulator_init_data wm8994_ldo1_data = { 443 + .constraints = { 444 + .name = "AVDD1_3.0V", 445 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 446 + }, 447 + .num_consumer_supplies = 1, 448 + .consumer_supplies = &wm8994_avdd1_supply, 449 + }; 450 + 451 + static struct regulator_init_data wm8994_ldo2_data = { 452 + .constraints = { 453 + .name = "DCVDD_1.0V", 454 + }, 455 + .num_consumer_supplies = 1, 456 + .consumer_supplies = &wm8994_dcvdd_supply, 457 + }; 458 + 459 + static struct wm8994_pdata wm8994_platform_data = { 460 + /* configure gpio1 function: 0x0001(Logic level input/output) */ 461 + .gpio_defaults[0] = 0x0001, 462 + /* configure gpio3/4/5/7 function for AIF2 voice */ 463 + .gpio_defaults[2] = 0x8100, 464 + .gpio_defaults[3] = 0x8100, 465 + .gpio_defaults[4] = 0x8100, 466 + .gpio_defaults[6] = 0x0100, 467 + /* configure gpio8/9/10/11 function for AIF3 BT */ 468 + .gpio_defaults[7] = 0x8100, 469 + .gpio_defaults[8] = 0x0100, 470 + .gpio_defaults[9] = 0x0100, 471 + .gpio_defaults[10] = 0x0100, 472 + .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */ 473 + .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, 474 + }; 475 + 524 476 /* GPIO I2C PMIC */ 525 477 #define AP_I2C_GPIO_PMIC_BUS_4 4 526 478 static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = { ··· 657 383 .platform_data = &goni_max8998_pdata, 658 384 }, 659 385 #endif 386 + }; 387 + 388 + /* GPIO I2C AP 1.8V */ 389 + #define AP_I2C_GPIO_BUS_5 5 390 + static struct i2c_gpio_platform_data goni_i2c_gpio5_data = { 391 + .sda_pin = S5PV210_MP05(3), /* XM0ADDR_11 */ 392 + .scl_pin = S5PV210_MP05(2), /* XM0ADDR_10 */ 393 + }; 394 + 395 + static struct platform_device goni_i2c_gpio5 = { 396 + .name = "i2c-gpio", 397 + .id = AP_I2C_GPIO_BUS_5, 398 + .dev = { 399 + .platform_data = &goni_i2c_gpio5_data, 400 + }, 401 + }; 402 + 403 + static struct i2c_board_info i2c_gpio5_devs[] __initdata = { 404 + { 405 + /* CS/ADDR = low 0x34 (FYI: high = 0x36) */ 406 + I2C_BOARD_INFO("wm8994", 0x1a), 407 + .platform_data = &wm8994_platform_data, 408 + }, 660 409 }; 661 410 662 411 /* PMIC Power button */ ··· 741 444 .ext_cd_gpio_invert = 1, 742 445 }; 743 446 447 + static struct regulator_consumer_supply mmc2_supplies[] = { 448 + REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"), 449 + }; 450 + 451 + static struct regulator_init_data mmc2_fixed_voltage_init_data = { 452 + .constraints = { 453 + .name = "V_TF_2.8V", 454 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 455 + }, 456 + .num_consumer_supplies = ARRAY_SIZE(mmc2_supplies), 457 + .consumer_supplies = mmc2_supplies, 458 + }; 459 + 460 + static struct fixed_voltage_config mmc2_fixed_voltage_config = { 461 + .supply_name = "EXT_FLASH_EN", 462 + .microvolts = 2800000, 463 + .gpio = GONI_EXT_FLASH_EN, 464 + .enable_high = true, 465 + .init_data = &mmc2_fixed_voltage_init_data, 466 + }; 467 + 468 + static struct platform_device mmc2_fixed_voltage = { 469 + .name = "reg-fixed-voltage", 470 + .id = 2, 471 + .dev = { 472 + .platform_data = &mmc2_fixed_voltage_config, 473 + }, 474 + }; 475 + 744 476 static void goni_setup_sdhci(void) 745 477 { 746 - gpio_request(GONI_EXT_FLASH_EN, "FLASH_EN"); 747 - gpio_direction_output(GONI_EXT_FLASH_EN, 1); 748 - 749 478 s3c_sdhci0_set_platdata(&goni_hsmmc0_data); 750 479 s3c_sdhci1_set_platdata(&goni_hsmmc1_data); 751 480 s3c_sdhci2_set_platdata(&goni_hsmmc2_data); ··· 780 457 static struct platform_device *goni_devices[] __initdata = { 781 458 &s3c_device_fb, 782 459 &s5p_device_onenand, 460 + &goni_spi_gpio, 783 461 &goni_i2c_gpio_pmic, 462 + &goni_i2c_gpio5, 463 + &mmc2_fixed_voltage, 784 464 &goni_device_gpiokeys, 785 465 &s5p_device_fimc0, 786 466 &s5p_device_fimc1, ··· 791 465 &s3c_device_hsmmc0, 792 466 &s3c_device_hsmmc1, 793 467 &s3c_device_hsmmc2, 468 + &s5pv210_device_iis0, 469 + &s3c_device_usb_hsotg, 470 + &samsung_device_keypad, 471 + &s3c_device_i2c1, 472 + &s3c_device_i2c2, 473 + &wm8994_fixed_voltage0, 474 + &wm8994_fixed_voltage1, 794 475 }; 476 + 477 + static void __init goni_sound_init(void) 478 + { 479 + /* Ths main clock of WM8994 codec uses the output of CLKOUT pin. 480 + * The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS) 481 + * because it needs 24MHz clock to operate WM8994 codec. 482 + */ 483 + __raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS); 484 + } 795 485 796 486 static void __init goni_map_io(void) 797 487 { ··· 818 476 819 477 static void __init goni_machine_init(void) 820 478 { 479 + /* Radio: call before I2C 1 registeration */ 480 + goni_radio_init(); 481 + 482 + /* I2C1 */ 483 + s3c_i2c1_set_platdata(NULL); 484 + i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); 485 + 486 + /* TSP: call before I2C 2 registeration */ 487 + goni_tsp_init(); 488 + 489 + /* I2C2 */ 490 + s3c_i2c2_set_platdata(&i2c2_data); 491 + i2c_register_board_info(2, i2c2_devs, ARRAY_SIZE(i2c2_devs)); 492 + 821 493 /* PMIC */ 822 494 goni_pmic_init(); 823 495 i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs, ··· 839 483 /* SDHCI */ 840 484 goni_setup_sdhci(); 841 485 486 + /* SOUND */ 487 + goni_sound_init(); 488 + i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs, 489 + ARRAY_SIZE(i2c_gpio5_devs)); 490 + 842 491 /* FB */ 843 492 s3c_fb_set_platdata(&goni_lcd_pdata); 493 + 494 + /* SPI */ 495 + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); 496 + 497 + /* KEYPAD */ 498 + samsung_keypad_set_platdata(&keypad_data); 499 + 500 + clk_xusbxti.rate = 24000000; 844 501 845 502 platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices)); 846 503 }
+4
arch/arm/mach-s5pv210/mach-smdkc110.c
··· 28 28 #include <plat/cpu.h> 29 29 #include <plat/ata.h> 30 30 #include <plat/iic.h> 31 + #include <plat/pm.h> 31 32 32 33 /* Following are default values for UCON, ULCON and UFCON UART registers */ 33 34 #define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ ··· 82 81 static struct platform_device *smdkc110_devices[] __initdata = { 83 82 &s5pv210_device_iis0, 84 83 &s5pv210_device_ac97, 84 + &s5pv210_device_spdif, 85 85 &s3c_device_cfcon, 86 86 &s3c_device_i2c0, 87 87 &s3c_device_i2c1, ··· 112 110 113 111 static void __init smdkc110_machine_init(void) 114 112 { 113 + s3c_pm_init(); 114 + 115 115 s3c_i2c0_set_platdata(NULL); 116 116 s3c_i2c1_set_platdata(NULL); 117 117 s3c_i2c2_set_platdata(NULL);
+4
arch/arm/mach-s5pv210/mach-smdkv210.c
··· 31 31 #include <plat/ata.h> 32 32 #include <plat/iic.h> 33 33 #include <plat/keypad.h> 34 + #include <plat/pm.h> 34 35 35 36 /* Following are default values for UCON, ULCON and UFCON UART registers */ 36 37 #define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ ··· 104 103 static struct platform_device *smdkv210_devices[] __initdata = { 105 104 &s5pv210_device_iis0, 106 105 &s5pv210_device_ac97, 106 + &s5pv210_device_spdif, 107 107 &s3c_device_adc, 108 108 &s3c_device_cfcon, 109 109 &s3c_device_hsmmc0, ··· 147 145 148 146 static void __init smdkv210_machine_init(void) 149 147 { 148 + s3c_pm_init(); 149 + 150 150 samsung_keypad_set_platdata(&smdkv210_keypad_data); 151 151 s3c24xx_ts_set_platdata(&s3c_ts_platform); 152 152
+131
arch/arm/mach-s5pv210/mach-torbreck.c
··· 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
+166
arch/arm/mach-s5pv210/pm.c
··· 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);
+13 -25
arch/arm/mach-s5pv210/setup-fb-24bpp.c
··· 21 21 #include <mach/regs-clock.h> 22 22 #include <plat/gpio-cfg.h> 23 23 24 + static void s5pv210_fb_cfg_gpios(unsigned int base, unsigned int nr) 25 + { 26 + s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2)); 27 + 28 + for (; nr > 0; nr--, base++) 29 + s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4); 30 + } 31 + 32 + 24 33 void s5pv210_fb_gpio_setup_24bpp(void) 25 34 { 26 - unsigned int gpio = 0; 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 - 34 - for (gpio = S5PV210_GPF1(0); gpio <= S5PV210_GPF1(7); gpio++) { 35 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 36 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 37 - s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); 38 - } 39 - 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 - 46 - for (gpio = S5PV210_GPF3(0); gpio <= S5PV210_GPF3(3); gpio++) { 47 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 48 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 49 - s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); 50 - } 35 + s5pv210_fb_cfg_gpios(S5PV210_GPF0(0), 8); 36 + s5pv210_fb_cfg_gpios(S5PV210_GPF1(0), 8); 37 + s5pv210_fb_cfg_gpios(S5PV210_GPF2(0), 8); 38 + s5pv210_fb_cfg_gpios(S5PV210_GPF3(0), 4); 51 39 52 40 /* Set DISPLAY_CONTROL register for Display path selection. 53 41 *
+2 -4
arch/arm/mach-s5pv210/setup-i2c0.c
··· 23 23 24 24 void s3c_i2c0_cfg_gpio(struct platform_device *dev) 25 25 { 26 - s3c_gpio_cfgpin(S5PV210_GPD1(0), S3C_GPIO_SFN(2)); 27 - s3c_gpio_setpull(S5PV210_GPD1(0), 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); 26 + s3c_gpio_cfgall_range(S5PV210_GPD1(0), 2, 27 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 30 28 }
+2 -4
arch/arm/mach-s5pv210/setup-i2c1.c
··· 23 23 24 24 void s3c_i2c1_cfg_gpio(struct platform_device *dev) 25 25 { 26 - s3c_gpio_cfgpin(S5PV210_GPD1(2), S3C_GPIO_SFN(2)); 27 - s3c_gpio_setpull(S5PV210_GPD1(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); 26 + s3c_gpio_cfgall_range(S5PV210_GPD1(2), 2, 27 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 30 28 }
+2 -4
arch/arm/mach-s5pv210/setup-i2c2.c
··· 23 23 24 24 void s3c_i2c2_cfg_gpio(struct platform_device *dev) 25 25 { 26 - s3c_gpio_cfgpin(S5PV210_GPD1(4), S3C_GPIO_SFN(2)); 27 - s3c_gpio_setpull(S5PV210_GPD1(4), 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); 26 + s3c_gpio_cfgall_range(S5PV210_GPD1(4), 2, 27 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 30 28 }
+16 -27
arch/arm/mach-s5pv210/setup-ide.c
··· 15 15 16 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 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 */ 29 + s5pv210_ide_cfg_gpios(S5PV210_GPJ0(0), 8); 21 30 22 - for (gpio = S5PV210_GPJ0(0); gpio <= S5PV210_GPJ0(7); gpio++) { 23 - /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, 24 - CF_DMACK */ 25 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4)); 26 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 27 - s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); 28 - } 31 + /* CF_Data[0 - 7] */ 32 + s5pv210_ide_cfg_gpios(S5PV210_GPJ2(0), 8); 29 33 30 - for (gpio = S5PV210_GPJ2(0); gpio <= S5PV210_GPJ2(7); gpio++) { 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 - } 34 + /* CF_Data[8 - 15] */ 35 + s5pv210_ide_cfg_gpios(S5PV210_GPJ3(0), 8); 36 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 - } 37 + /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */ 38 + s5pv210_ide_cfg_gpios(S5PV210_GPJ4(0), 4); 50 39 }
+2 -12
arch/arm/mach-s5pv210/setup-keypad.c
··· 16 16 17 17 void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) 18 18 { 19 - unsigned int gpio, end; 20 - 21 19 /* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */ 22 - end = S5PV210_GPH3(rows); 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 - } 20 + s3c_gpio_cfgrange_nopull(S5PV210_GPH3(0), rows, S3C_GPIO_SFN(3)); 27 21 28 22 /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */ 29 - end = S5PV210_GPH2(cols); 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 - } 23 + s3c_gpio_cfgrange_nopull(S5PV210_GPH2(0), cols, S3C_GPIO_SFN(3)); 34 24 }
+12 -45
arch/arm/mach-s5pv210/setup-sdhci-gpio.c
··· 26 26 void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) 27 27 { 28 28 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 29 - unsigned int gpio; 30 29 31 30 /* Set all the necessary GPG0/GPG1 pins to special-function 2 */ 32 - for (gpio = S5PV210_GPG0(0); gpio < S5PV210_GPG0(2); gpio++) { 33 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 34 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 35 - } 31 + s3c_gpio_cfgrange_nopull(S5PV210_GPG0(0), 2, S3C_GPIO_SFN(2)); 32 + 36 33 switch (width) { 37 34 case 8: 38 35 /* GPG1[3:6] special-funtion 3 */ 39 - for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) { 40 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3)); 41 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 42 - } 36 + s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(3)); 43 37 case 4: 44 38 /* GPG0[3:6] special-funtion 2 */ 45 - for (gpio = S5PV210_GPG0(3); gpio <= S5PV210_GPG0(6); gpio++) { 46 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 47 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 48 - } 39 + s3c_gpio_cfgrange_nopull(S5PV210_GPG0(3), 4, S3C_GPIO_SFN(2)); 49 40 default: 50 41 break; 51 42 } ··· 50 59 void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) 51 60 { 52 61 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 53 - unsigned int gpio; 54 62 55 63 /* Set all the necessary GPG1[0:1] pins to special-function 2 */ 56 - for (gpio = S5PV210_GPG1(0); gpio < S5PV210_GPG1(2); gpio++) { 57 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 58 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 59 - } 64 + s3c_gpio_cfgrange_nopull(S5PV210_GPG1(0), 2, S3C_GPIO_SFN(2)); 60 65 61 66 /* Data pin GPG1[3:6] to special-function 2 */ 62 - for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) { 63 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 64 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 65 - } 67 + s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(2)); 66 68 67 69 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 68 70 s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP); ··· 66 82 void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) 67 83 { 68 84 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 69 - unsigned int gpio; 70 85 71 86 /* Set all the necessary GPG2[0:1] pins to special-function 2 */ 72 - for (gpio = S5PV210_GPG2(0); gpio < S5PV210_GPG2(2); gpio++) { 73 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 74 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 75 - } 87 + s3c_gpio_cfgrange_nopull(S5PV210_GPG2(0), 2, S3C_GPIO_SFN(2)); 76 88 77 89 switch (width) { 78 90 case 8: 79 91 /* Data pin GPG3[3:6] to special-function 3 */ 80 - for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) { 81 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3)); 82 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 83 - } 92 + s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(3)); 84 93 case 4: 85 94 /* Data pin GPG2[3:6] to special-function 2 */ 86 - for (gpio = S5PV210_GPG2(3); gpio <= S5PV210_GPG2(6); gpio++) { 87 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 88 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 89 - } 95 + s3c_gpio_cfgrange_nopull(S5PV210_GPG2(3), 4, S3C_GPIO_SFN(2)); 90 96 default: 91 97 break; 92 98 } ··· 90 116 void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width) 91 117 { 92 118 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; 93 - unsigned int gpio; 94 119 95 - /* Set all the necessary GPG3[0:2] pins to special-function 2 */ 96 - for (gpio = S5PV210_GPG3(0); gpio < S5PV210_GPG3(2); gpio++) { 97 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 98 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 99 - } 120 + /* Set all the necessary GPG3[0:1] pins to special-function 2 */ 121 + s3c_gpio_cfgrange_nopull(S5PV210_GPG3(0), 2, S3C_GPIO_SFN(2)); 100 122 101 123 /* Data pin GPG3[3:6] to special-function 2 */ 102 - for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) { 103 - s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); 104 - s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 105 - } 124 + s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(2)); 106 125 107 126 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { 108 127 s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP);
+170
arch/arm/mach-s5pv210/sleep.S
··· 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
+89 -6
arch/arm/mach-s5pv310/Kconfig
··· 11 11 12 12 config CPU_S5PV310 13 13 bool 14 - select PLAT_S5P 15 14 help 16 15 Enable S5PV310 CPU support 17 16 ··· 24 25 help 25 26 Common setup code for i2c bus 2. 26 27 28 + config S5PV310_SETUP_I2C3 29 + bool 30 + help 31 + Common setup code for i2c bus 3. 32 + 33 + config S5PV310_SETUP_I2C4 34 + bool 35 + help 36 + Common setup code for i2c bus 4. 37 + 38 + config S5PV310_SETUP_I2C5 39 + bool 40 + help 41 + Common setup code for i2c bus 5. 42 + 43 + config S5PV310_SETUP_I2C6 44 + bool 45 + help 46 + Common setup code for i2c bus 6. 47 + 48 + config S5PV310_SETUP_I2C7 49 + bool 50 + help 51 + Common setup code for i2c bus 7. 52 + 53 + config S5PV310_SETUP_SDHCI 54 + bool 55 + select S5PV310_SETUP_SDHCI_GPIO 56 + help 57 + Internal helper functions for S5PV310 based SDHCI systems. 58 + 59 + config S5PV310_SETUP_SDHCI_GPIO 60 + bool 61 + help 62 + Common setup code for SDHCI gpio. 63 + 27 64 # machine support 28 65 29 - config MACH_SMDKV310 30 - bool "SMDKV310" 66 + menu "S5PC210 Machines" 67 + 68 + config MACH_SMDKC210 69 + bool "SMDKC210" 31 70 select CPU_S5PV310 32 - select ARCH_SPARSEMEM_ENABLE 71 + select S3C_DEV_RTC 72 + select S3C_DEV_WDT 73 + select S3C_DEV_HSMMC 74 + select S3C_DEV_HSMMC1 75 + select S3C_DEV_HSMMC2 76 + select S3C_DEV_HSMMC3 77 + select S5PV310_SETUP_SDHCI 33 78 help 34 - Machine support for Samsung SMDKV310 79 + Machine support for Samsung SMDKC210 80 + S5PC210(MCP) is one of package option of S5PV310 35 81 36 82 config MACH_UNIVERSAL_C210 37 83 bool "Mobile UNIVERSAL_C210 Board" 38 84 select CPU_S5PV310 39 - select ARCH_SPARSEMEM_ENABLE 85 + select S5P_DEV_ONENAND 86 + select S3C_DEV_I2C1 87 + select S5PV310_SETUP_I2C1 40 88 help 41 89 Machine support for Samsung Mobile Universal S5PC210 Reference 42 90 Board. S5PC210(MCP) is one of package option of S5PV310 91 + 92 + endmenu 93 + 94 + menu "S5PV310 Machines" 95 + 96 + config MACH_SMDKV310 97 + bool "SMDKV310" 98 + select CPU_S5PV310 99 + select S3C_DEV_RTC 100 + select S3C_DEV_WDT 101 + select S3C_DEV_HSMMC 102 + select S3C_DEV_HSMMC1 103 + select S3C_DEV_HSMMC2 104 + select S3C_DEV_HSMMC3 105 + select S5PV310_SETUP_SDHCI 106 + help 107 + Machine support for Samsung SMDKV310 108 + 109 + endmenu 110 + 111 + comment "Configuration for HSMMC bus width" 112 + 113 + menu "Use 8-bit bus width" 114 + 115 + config S5PV310_SDHCI_CH0_8BIT 116 + bool "Channel 0 with 8-bit bus" 117 + help 118 + Support HSMMC Channel 0 8-bit bus. 119 + If selected, Channel 1 is disabled. 120 + 121 + config S5PV310_SDHCI_CH2_8BIT 122 + bool "Channel 2 with 8-bit bus" 123 + help 124 + Support HSMMC Channel 2 8-bit bus. 125 + If selected, Channel 3 is disabled. 126 + 127 + endmenu 43 128 44 129 endif
+9 -1
arch/arm/mach-s5pv310/Makefile
··· 13 13 # Core support for S5PV310 system 14 14 15 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 18 obj-$(CONFIG_SMP) += platsmp.o headsmp.o 19 19 obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o ··· 21 21 22 22 # machine support 23 23 24 + obj-$(CONFIG_MACH_SMDKC210) += mach-smdkc210.o 24 25 obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o 25 26 obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o 26 27 ··· 29 28 30 29 obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o 31 30 obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o 31 + obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o 32 + obj-$(CONFIG_S5PV310_SETUP_I2C4) += setup-i2c4.o 33 + obj-$(CONFIG_S5PV310_SETUP_I2C5) += setup-i2c5.o 34 + obj-$(CONFIG_S5PV310_SETUP_I2C6) += setup-i2c6.o 35 + obj-$(CONFIG_S5PV310_SETUP_I2C7) += setup-i2c7.o 36 + obj-$(CONFIG_S5PV310_SETUP_SDHCI) += setup-sdhci.o 37 + obj-$(CONFIG_S5PV310_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+567 -66
arch/arm/mach-s5pv310/clock.c
··· 30 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 74 static int s5pv310_clksrc_mask_peril0_ctrl(struct clk *clk, int enable) 34 75 { 35 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 109 static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable) 39 110 { 40 111 return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable); 112 + } 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); 41 117 } 42 118 43 119 /* Core list of CMU_CPU side */ ··· 155 79 }; 156 80 157 81 static struct clk *clkset_moutcore_list[] = { 158 - [0] = &clk_sclk_apll.clk, 82 + [0] = &clk_mout_apll.clk, 159 83 [1] = &clk_mout_mpll.clk, 160 84 }; 161 85 ··· 224 148 .parent = &clk_coreclk.clk, 225 149 }, 226 150 .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 }, 227 - }; 228 - 229 - static struct clksrc_clk clk_atclk = { 230 - .clk = { 231 - .name = "atclk", 232 - .id = -1, 233 - .parent = &clk_moutcore.clk, 234 - }, 235 - .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 16, .size = 3 }, 236 - }; 237 - 238 - static struct clksrc_clk clk_pclk_dbg = { 239 - .clk = { 240 - .name = "pclk_dbg", 241 - .id = -1, 242 - .parent = &clk_atclk.clk, 243 - }, 244 - .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 20, .size = 3 }, 245 151 }; 246 152 247 153 /* Core list of CMU_CORE side */ ··· 299 241 [1] = &clk_sclk_apll.clk, 300 242 }; 301 243 302 - static struct clksrc_sources clkset_aclk_200 = { 244 + static struct clksrc_sources clkset_aclk = { 303 245 .sources = clkset_aclk_top_list, 304 246 .nr_sources = ARRAY_SIZE(clkset_aclk_top_list), 305 247 }; ··· 309 251 .name = "aclk_200", 310 252 .id = -1, 311 253 }, 312 - .sources = &clkset_aclk_200, 254 + .sources = &clkset_aclk, 313 255 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 }, 314 256 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 }, 315 - }; 316 - 317 - static struct clksrc_sources clkset_aclk_100 = { 318 - .sources = clkset_aclk_top_list, 319 - .nr_sources = ARRAY_SIZE(clkset_aclk_top_list), 320 257 }; 321 258 322 259 static struct clksrc_clk clk_aclk_100 = { ··· 319 266 .name = "aclk_100", 320 267 .id = -1, 321 268 }, 322 - .sources = &clkset_aclk_100, 269 + .sources = &clkset_aclk, 323 270 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 }, 324 271 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 }, 325 - }; 326 - 327 - static struct clksrc_sources clkset_aclk_160 = { 328 - .sources = clkset_aclk_top_list, 329 - .nr_sources = ARRAY_SIZE(clkset_aclk_top_list), 330 272 }; 331 273 332 274 static struct clksrc_clk clk_aclk_160 = { ··· 329 281 .name = "aclk_160", 330 282 .id = -1, 331 283 }, 332 - .sources = &clkset_aclk_160, 284 + .sources = &clkset_aclk, 333 285 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 }, 334 286 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 }, 335 - }; 336 - 337 - static struct clksrc_sources clkset_aclk_133 = { 338 - .sources = clkset_aclk_top_list, 339 - .nr_sources = ARRAY_SIZE(clkset_aclk_top_list), 340 287 }; 341 288 342 289 static struct clksrc_clk clk_aclk_133 = { ··· 339 296 .name = "aclk_133", 340 297 .id = -1, 341 298 }, 342 - .sources = &clkset_aclk_133, 299 + .sources = &clkset_aclk, 343 300 .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 }, 344 301 .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 }, 345 302 }; ··· 358 315 .clk = { 359 316 .name = "vpll_src", 360 317 .id = -1, 318 + .enable = s5pv310_clksrc_mask_top_ctrl, 319 + .ctrlbit = (1 << 0), 361 320 }, 362 321 .sources = &clkset_vpllsrc, 363 322 .reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 }, ··· 391 346 .parent = &clk_aclk_100.clk, 392 347 .enable = s5pv310_clk_ip_peril_ctrl, 393 348 .ctrlbit = (1<<24), 394 - } 349 + }, { 350 + .name = "csis", 351 + .id = 0, 352 + .enable = s5pv310_clk_ip_cam_ctrl, 353 + .ctrlbit = (1 << 4), 354 + }, { 355 + .name = "csis", 356 + .id = 1, 357 + .enable = s5pv310_clk_ip_cam_ctrl, 358 + .ctrlbit = (1 << 5), 359 + }, { 360 + .name = "fimc", 361 + .id = 0, 362 + .enable = s5pv310_clk_ip_cam_ctrl, 363 + .ctrlbit = (1 << 0), 364 + }, { 365 + .name = "fimc", 366 + .id = 1, 367 + .enable = s5pv310_clk_ip_cam_ctrl, 368 + .ctrlbit = (1 << 1), 369 + }, { 370 + .name = "fimc", 371 + .id = 2, 372 + .enable = s5pv310_clk_ip_cam_ctrl, 373 + .ctrlbit = (1 << 2), 374 + }, { 375 + .name = "fimc", 376 + .id = 3, 377 + .enable = s5pv310_clk_ip_cam_ctrl, 378 + .ctrlbit = (1 << 3), 379 + }, { 380 + .name = "fimd", 381 + .id = 0, 382 + .enable = s5pv310_clk_ip_lcd0_ctrl, 383 + .ctrlbit = (1 << 0), 384 + }, { 385 + .name = "fimd", 386 + .id = 1, 387 + .enable = s5pv310_clk_ip_lcd1_ctrl, 388 + .ctrlbit = (1 << 0), 389 + }, { 390 + .name = "hsmmc", 391 + .id = 0, 392 + .parent = &clk_aclk_133.clk, 393 + .enable = s5pv310_clk_ip_fsys_ctrl, 394 + .ctrlbit = (1 << 5), 395 + }, { 396 + .name = "hsmmc", 397 + .id = 1, 398 + .parent = &clk_aclk_133.clk, 399 + .enable = s5pv310_clk_ip_fsys_ctrl, 400 + .ctrlbit = (1 << 6), 401 + }, { 402 + .name = "hsmmc", 403 + .id = 2, 404 + .parent = &clk_aclk_133.clk, 405 + .enable = s5pv310_clk_ip_fsys_ctrl, 406 + .ctrlbit = (1 << 7), 407 + }, { 408 + .name = "hsmmc", 409 + .id = 3, 410 + .parent = &clk_aclk_133.clk, 411 + .enable = s5pv310_clk_ip_fsys_ctrl, 412 + .ctrlbit = (1 << 8), 413 + }, { 414 + .name = "hsmmc", 415 + .id = 4, 416 + .parent = &clk_aclk_133.clk, 417 + .enable = s5pv310_clk_ip_fsys_ctrl, 418 + .ctrlbit = (1 << 9), 419 + }, { 420 + .name = "sata", 421 + .id = -1, 422 + .enable = s5pv310_clk_ip_fsys_ctrl, 423 + .ctrlbit = (1 << 10), 424 + }, { 425 + .name = "adc", 426 + .id = -1, 427 + .enable = s5pv310_clk_ip_peril_ctrl, 428 + .ctrlbit = (1 << 15), 429 + }, { 430 + .name = "rtc", 431 + .id = -1, 432 + .enable = s5pv310_clk_ip_perir_ctrl, 433 + .ctrlbit = (1 << 15), 434 + }, { 435 + .name = "watchdog", 436 + .id = -1, 437 + .enable = s5pv310_clk_ip_perir_ctrl, 438 + .ctrlbit = (1 << 14), 439 + }, { 440 + .name = "usbhost", 441 + .id = -1, 442 + .enable = s5pv310_clk_ip_fsys_ctrl , 443 + .ctrlbit = (1 << 12), 444 + }, { 445 + .name = "otg", 446 + .id = -1, 447 + .enable = s5pv310_clk_ip_fsys_ctrl, 448 + .ctrlbit = (1 << 13), 449 + }, { 450 + .name = "spi", 451 + .id = 0, 452 + .enable = s5pv310_clk_ip_peril_ctrl, 453 + .ctrlbit = (1 << 16), 454 + }, { 455 + .name = "spi", 456 + .id = 1, 457 + .enable = s5pv310_clk_ip_peril_ctrl, 458 + .ctrlbit = (1 << 17), 459 + }, { 460 + .name = "spi", 461 + .id = 2, 462 + .enable = s5pv310_clk_ip_peril_ctrl, 463 + .ctrlbit = (1 << 18), 464 + }, { 465 + .name = "fimg2d", 466 + .id = -1, 467 + .enable = s5pv310_clk_ip_image_ctrl, 468 + .ctrlbit = (1 << 0), 469 + }, { 470 + .name = "i2c", 471 + .id = 0, 472 + .parent = &clk_aclk_100.clk, 473 + .enable = s5pv310_clk_ip_peril_ctrl, 474 + .ctrlbit = (1 << 6), 475 + }, { 476 + .name = "i2c", 477 + .id = 1, 478 + .parent = &clk_aclk_100.clk, 479 + .enable = s5pv310_clk_ip_peril_ctrl, 480 + .ctrlbit = (1 << 7), 481 + }, { 482 + .name = "i2c", 483 + .id = 2, 484 + .parent = &clk_aclk_100.clk, 485 + .enable = s5pv310_clk_ip_peril_ctrl, 486 + .ctrlbit = (1 << 8), 487 + }, { 488 + .name = "i2c", 489 + .id = 3, 490 + .parent = &clk_aclk_100.clk, 491 + .enable = s5pv310_clk_ip_peril_ctrl, 492 + .ctrlbit = (1 << 9), 493 + }, { 494 + .name = "i2c", 495 + .id = 4, 496 + .parent = &clk_aclk_100.clk, 497 + .enable = s5pv310_clk_ip_peril_ctrl, 498 + .ctrlbit = (1 << 10), 499 + }, { 500 + .name = "i2c", 501 + .id = 5, 502 + .parent = &clk_aclk_100.clk, 503 + .enable = s5pv310_clk_ip_peril_ctrl, 504 + .ctrlbit = (1 << 11), 505 + }, { 506 + .name = "i2c", 507 + .id = 6, 508 + .parent = &clk_aclk_100.clk, 509 + .enable = s5pv310_clk_ip_peril_ctrl, 510 + .ctrlbit = (1 << 12), 511 + }, { 512 + .name = "i2c", 513 + .id = 7, 514 + .parent = &clk_aclk_100.clk, 515 + .enable = s5pv310_clk_ip_peril_ctrl, 516 + .ctrlbit = (1 << 13), 517 + }, 395 518 }; 396 519 397 520 static struct clk init_clocks[] = { ··· 600 387 [0] = &clk_ext_xtal_mux, 601 388 [1] = &clk_xusbxti, 602 389 [2] = &clk_sclk_hdmi27m, 390 + [3] = &clk_sclk_usbphy0, 391 + [4] = &clk_sclk_usbphy1, 392 + [5] = &clk_sclk_hdmiphy, 603 393 [6] = &clk_mout_mpll.clk, 604 394 [7] = &clk_mout_epll.clk, 605 395 [8] = &clk_sclk_vpll.clk, ··· 611 395 static struct clksrc_sources clkset_group = { 612 396 .sources = clkset_group_list, 613 397 .nr_sources = ARRAY_SIZE(clkset_group_list), 398 + }; 399 + 400 + static struct clk *clkset_mout_g2d0_list[] = { 401 + [0] = &clk_mout_mpll.clk, 402 + [1] = &clk_sclk_apll.clk, 403 + }; 404 + 405 + static struct clksrc_sources clkset_mout_g2d0 = { 406 + .sources = clkset_mout_g2d0_list, 407 + .nr_sources = ARRAY_SIZE(clkset_mout_g2d0_list), 408 + }; 409 + 410 + static struct clksrc_clk clk_mout_g2d0 = { 411 + .clk = { 412 + .name = "mout_g2d0", 413 + .id = -1, 414 + }, 415 + .sources = &clkset_mout_g2d0, 416 + .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 }, 417 + }; 418 + 419 + static struct clk *clkset_mout_g2d1_list[] = { 420 + [0] = &clk_mout_epll.clk, 421 + [1] = &clk_sclk_vpll.clk, 422 + }; 423 + 424 + static struct clksrc_sources clkset_mout_g2d1 = { 425 + .sources = clkset_mout_g2d1_list, 426 + .nr_sources = ARRAY_SIZE(clkset_mout_g2d1_list), 427 + }; 428 + 429 + static struct clksrc_clk clk_mout_g2d1 = { 430 + .clk = { 431 + .name = "mout_g2d1", 432 + .id = -1, 433 + }, 434 + .sources = &clkset_mout_g2d1, 435 + .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 }, 436 + }; 437 + 438 + static struct clk *clkset_mout_g2d_list[] = { 439 + [0] = &clk_mout_g2d0.clk, 440 + [1] = &clk_mout_g2d1.clk, 441 + }; 442 + 443 + static struct clksrc_sources clkset_mout_g2d = { 444 + .sources = clkset_mout_g2d_list, 445 + .nr_sources = ARRAY_SIZE(clkset_mout_g2d_list), 446 + }; 447 + 448 + static struct clksrc_clk clk_dout_mmc0 = { 449 + .clk = { 450 + .name = "dout_mmc0", 451 + .id = -1, 452 + }, 453 + .sources = &clkset_group, 454 + .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 }, 455 + .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 }, 456 + }; 457 + 458 + static struct clksrc_clk clk_dout_mmc1 = { 459 + .clk = { 460 + .name = "dout_mmc1", 461 + .id = -1, 462 + }, 463 + .sources = &clkset_group, 464 + .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 }, 465 + .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 }, 466 + }; 467 + 468 + static struct clksrc_clk clk_dout_mmc2 = { 469 + .clk = { 470 + .name = "dout_mmc2", 471 + .id = -1, 472 + }, 473 + .sources = &clkset_group, 474 + .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 }, 475 + .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 }, 476 + }; 477 + 478 + static struct clksrc_clk clk_dout_mmc3 = { 479 + .clk = { 480 + .name = "dout_mmc3", 481 + .id = -1, 482 + }, 483 + .sources = &clkset_group, 484 + .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 }, 485 + .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 }, 486 + }; 487 + 488 + static struct clksrc_clk clk_dout_mmc4 = { 489 + .clk = { 490 + .name = "dout_mmc4", 491 + .id = -1, 492 + }, 493 + .sources = &clkset_group, 494 + .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 }, 495 + .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 }, 614 496 }; 615 497 616 498 static struct clksrc_clk clksrcs[] = { ··· 762 448 .sources = &clkset_group, 763 449 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 }, 764 450 .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 }, 765 - }, 451 + }, { 452 + .clk = { 453 + .name = "sclk_csis", 454 + .id = 0, 455 + .enable = s5pv310_clksrc_mask_cam_ctrl, 456 + .ctrlbit = (1 << 24), 457 + }, 458 + .sources = &clkset_group, 459 + .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 }, 460 + .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 }, 461 + }, { 462 + .clk = { 463 + .name = "sclk_csis", 464 + .id = 1, 465 + .enable = s5pv310_clksrc_mask_cam_ctrl, 466 + .ctrlbit = (1 << 28), 467 + }, 468 + .sources = &clkset_group, 469 + .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 }, 470 + .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 }, 471 + }, { 472 + .clk = { 473 + .name = "sclk_cam", 474 + .id = 0, 475 + .enable = s5pv310_clksrc_mask_cam_ctrl, 476 + .ctrlbit = (1 << 16), 477 + }, 478 + .sources = &clkset_group, 479 + .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 }, 480 + .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 }, 481 + }, { 482 + .clk = { 483 + .name = "sclk_cam", 484 + .id = 1, 485 + .enable = s5pv310_clksrc_mask_cam_ctrl, 486 + .ctrlbit = (1 << 20), 487 + }, 488 + .sources = &clkset_group, 489 + .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 }, 490 + .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 }, 491 + }, { 492 + .clk = { 493 + .name = "sclk_fimc", 494 + .id = 0, 495 + .enable = s5pv310_clksrc_mask_cam_ctrl, 496 + .ctrlbit = (1 << 0), 497 + }, 498 + .sources = &clkset_group, 499 + .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 }, 500 + .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 }, 501 + }, { 502 + .clk = { 503 + .name = "sclk_fimc", 504 + .id = 1, 505 + .enable = s5pv310_clksrc_mask_cam_ctrl, 506 + .ctrlbit = (1 << 4), 507 + }, 508 + .sources = &clkset_group, 509 + .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 }, 510 + .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 }, 511 + }, { 512 + .clk = { 513 + .name = "sclk_fimc", 514 + .id = 2, 515 + .enable = s5pv310_clksrc_mask_cam_ctrl, 516 + .ctrlbit = (1 << 8), 517 + }, 518 + .sources = &clkset_group, 519 + .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 }, 520 + .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 }, 521 + }, { 522 + .clk = { 523 + .name = "sclk_fimc", 524 + .id = 3, 525 + .enable = s5pv310_clksrc_mask_cam_ctrl, 526 + .ctrlbit = (1 << 12), 527 + }, 528 + .sources = &clkset_group, 529 + .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 }, 530 + .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 }, 531 + }, { 532 + .clk = { 533 + .name = "sclk_fimd", 534 + .id = 0, 535 + .enable = s5pv310_clksrc_mask_lcd0_ctrl, 536 + .ctrlbit = (1 << 0), 537 + }, 538 + .sources = &clkset_group, 539 + .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 }, 540 + .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 }, 541 + }, { 542 + .clk = { 543 + .name = "sclk_fimd", 544 + .id = 1, 545 + .enable = s5pv310_clksrc_mask_lcd1_ctrl, 546 + .ctrlbit = (1 << 0), 547 + }, 548 + .sources = &clkset_group, 549 + .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 }, 550 + .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 }, 551 + }, { 552 + .clk = { 553 + .name = "sclk_sata", 554 + .id = -1, 555 + .enable = s5pv310_clksrc_mask_fsys_ctrl, 556 + .ctrlbit = (1 << 24), 557 + }, 558 + .sources = &clkset_mout_corebus, 559 + .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 }, 560 + .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 }, 561 + }, { 562 + .clk = { 563 + .name = "sclk_spi", 564 + .id = 0, 565 + .enable = s5pv310_clksrc_mask_peril1_ctrl, 566 + .ctrlbit = (1 << 16), 567 + }, 568 + .sources = &clkset_group, 569 + .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 }, 570 + .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 }, 571 + }, { 572 + .clk = { 573 + .name = "sclk_spi", 574 + .id = 1, 575 + .enable = s5pv310_clksrc_mask_peril1_ctrl, 576 + .ctrlbit = (1 << 20), 577 + }, 578 + .sources = &clkset_group, 579 + .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 }, 580 + .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 }, 581 + }, { 582 + .clk = { 583 + .name = "sclk_spi", 584 + .id = 2, 585 + .enable = s5pv310_clksrc_mask_peril1_ctrl, 586 + .ctrlbit = (1 << 24), 587 + }, 588 + .sources = &clkset_group, 589 + .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 }, 590 + .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 }, 591 + }, { 592 + .clk = { 593 + .name = "sclk_fimg2d", 594 + .id = -1, 595 + }, 596 + .sources = &clkset_mout_g2d, 597 + .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 }, 598 + .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 }, 599 + }, { 600 + .clk = { 601 + .name = "sclk_mmc", 602 + .id = 0, 603 + .parent = &clk_dout_mmc0.clk, 604 + .enable = s5pv310_clksrc_mask_fsys_ctrl, 605 + .ctrlbit = (1 << 0), 606 + }, 607 + .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 }, 608 + }, { 609 + .clk = { 610 + .name = "sclk_mmc", 611 + .id = 1, 612 + .parent = &clk_dout_mmc1.clk, 613 + .enable = s5pv310_clksrc_mask_fsys_ctrl, 614 + .ctrlbit = (1 << 4), 615 + }, 616 + .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 }, 617 + }, { 618 + .clk = { 619 + .name = "sclk_mmc", 620 + .id = 2, 621 + .parent = &clk_dout_mmc2.clk, 622 + .enable = s5pv310_clksrc_mask_fsys_ctrl, 623 + .ctrlbit = (1 << 8), 624 + }, 625 + .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 }, 626 + }, { 627 + .clk = { 628 + .name = "sclk_mmc", 629 + .id = 3, 630 + .parent = &clk_dout_mmc3.clk, 631 + .enable = s5pv310_clksrc_mask_fsys_ctrl, 632 + .ctrlbit = (1 << 12), 633 + }, 634 + .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 }, 635 + }, { 636 + .clk = { 637 + .name = "sclk_mmc", 638 + .id = 4, 639 + .parent = &clk_dout_mmc4.clk, 640 + .enable = s5pv310_clksrc_mask_fsys_ctrl, 641 + .ctrlbit = (1 << 16), 642 + }, 643 + .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 }, 644 + } 766 645 }; 767 646 768 647 /* Clock initialization code */ ··· 971 464 &clk_aclk_cores, 972 465 &clk_aclk_corem1, 973 466 &clk_periphclk, 974 - &clk_atclk, 975 - &clk_pclk_dbg, 976 467 &clk_mout_corebus, 977 468 &clk_sclk_dmc, 978 469 &clk_aclk_cored, ··· 983 478 &clk_aclk_100, 984 479 &clk_aclk_160, 985 480 &clk_aclk_133, 481 + &clk_dout_mmc0, 482 + &clk_dout_mmc1, 483 + &clk_dout_mmc2, 484 + &clk_dout_mmc3, 485 + &clk_dout_mmc4, 986 486 }; 987 487 988 488 void __init_or_cpufreq s5pv310_setup_clocks(void) ··· 1000 490 unsigned long vpllsrc; 1001 491 unsigned long xtal; 1002 492 unsigned long armclk; 1003 - unsigned long aclk_corem0; 1004 - unsigned long aclk_cores; 1005 - unsigned long aclk_corem1; 1006 - unsigned long periphclk; 1007 493 unsigned long sclk_dmc; 1008 - unsigned long aclk_cored; 1009 - unsigned long aclk_corep; 1010 - unsigned long aclk_acp; 1011 - unsigned long pclk_acp; 494 + unsigned long aclk_200; 495 + unsigned long aclk_100; 496 + unsigned long aclk_160; 497 + unsigned long aclk_133; 1012 498 unsigned int ptr; 1013 499 1014 500 printk(KERN_DEBUG "%s: registering clocks\n", __func__); ··· 1035 529 apll, mpll, epll, vpll); 1036 530 1037 531 armclk = clk_get_rate(&clk_armclk.clk); 1038 - aclk_corem0 = clk_get_rate(&clk_aclk_corem0.clk); 1039 - aclk_cores = clk_get_rate(&clk_aclk_cores.clk); 1040 - aclk_corem1 = clk_get_rate(&clk_aclk_corem1.clk); 1041 - periphclk = clk_get_rate(&clk_periphclk.clk); 1042 532 sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk); 1043 - aclk_cored = clk_get_rate(&clk_aclk_cored.clk); 1044 - aclk_corep = clk_get_rate(&clk_aclk_corep.clk); 1045 - aclk_acp = clk_get_rate(&clk_aclk_acp.clk); 1046 - pclk_acp = clk_get_rate(&clk_pclk_acp.clk); 1047 533 1048 - printk(KERN_INFO "S5PV310: ARMCLK=%ld, COREM0=%ld, CORES=%ld\n" 1049 - "COREM1=%ld, PERI=%ld, DMC=%ld, CORED=%ld\n" 1050 - "COREP=%ld, ACLK_ACP=%ld, PCLK_ACP=%ld", 1051 - armclk, aclk_corem0, aclk_cores, aclk_corem1, 1052 - periphclk, sclk_dmc, aclk_cored, aclk_corep, 1053 - aclk_acp, pclk_acp); 534 + aclk_200 = clk_get_rate(&clk_aclk_200.clk); 535 + aclk_100 = clk_get_rate(&clk_aclk_100.clk); 536 + aclk_160 = clk_get_rate(&clk_aclk_160.clk); 537 + aclk_133 = clk_get_rate(&clk_aclk_133.clk); 538 + 539 + printk(KERN_INFO "S5PV310: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n" 540 + "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n", 541 + armclk, sclk_dmc, aclk_200, 542 + aclk_100, aclk_160, aclk_133); 1054 543 1055 544 clk_f.rate = armclk; 1056 545 clk_h.rate = sclk_dmc; 1057 - clk_p.rate = periphclk; 546 + clk_p.rate = aclk_100; 1058 547 1059 548 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) 1060 549 s3c_set_clksrc(&clksrcs[ptr], true);
+46 -1
arch/arm/mach-s5pv310/cpu.c
··· 15 15 #include <asm/mach/irq.h> 16 16 17 17 #include <asm/proc-fns.h> 18 + #include <asm/hardware/cache-l2x0.h> 18 19 19 20 #include <plat/cpu.h> 20 21 #include <plat/clock.h> 21 22 #include <plat/s5pv310.h> 23 + #include <plat/sdhci.h> 22 24 23 25 #include <mach/regs-irq.h> 24 26 ··· 58 56 .length = SZ_4K, 59 57 .type = MT_DEVICE, 60 58 }, { 61 - .virtual = (unsigned long)S5P_VA_GPIO, 59 + .virtual = (unsigned long)S5P_VA_GPIO1, 62 60 .pfn = __phys_to_pfn(S5PV310_PA_GPIO1), 63 61 .length = SZ_4K, 62 + .type = MT_DEVICE, 63 + }, { 64 + .virtual = (unsigned long)S5P_VA_GPIO2, 65 + .pfn = __phys_to_pfn(S5PV310_PA_GPIO2), 66 + .length = SZ_4K, 67 + .type = MT_DEVICE, 68 + }, { 69 + .virtual = (unsigned long)S5P_VA_GPIO3, 70 + .pfn = __phys_to_pfn(S5PV310_PA_GPIO3), 71 + .length = SZ_256, 64 72 .type = MT_DEVICE, 65 73 }, { 66 74 .virtual = (unsigned long)S3C_VA_UART, 67 75 .pfn = __phys_to_pfn(S3C_PA_UART), 68 76 .length = SZ_512K, 77 + .type = MT_DEVICE, 78 + }, { 79 + .virtual = (unsigned long)S5P_VA_SROMC, 80 + .pfn = __phys_to_pfn(S5PV310_PA_SROMC), 81 + .length = SZ_4K, 69 82 .type = MT_DEVICE, 70 83 }, 71 84 }; ··· 100 83 void __init s5pv310_map_io(void) 101 84 { 102 85 iotable_init(s5pv310_iodesc, ARRAY_SIZE(s5pv310_iodesc)); 86 + 87 + /* initialize device information early */ 88 + s5pv310_default_sdhci0(); 89 + s5pv310_default_sdhci1(); 90 + s5pv310_default_sdhci2(); 91 + s5pv310_default_sdhci3(); 103 92 } 104 93 105 94 void __init s5pv310_init_clocks(int xtal) ··· 153 130 } 154 131 155 132 core_initcall(s5pv310_core_init); 133 + 134 + #ifdef CONFIG_CACHE_L2X0 135 + static int __init s5pv310_l2x0_cache_init(void) 136 + { 137 + /* TAG, Data Latency Control: 2cycle */ 138 + __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); 139 + __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); 140 + 141 + /* L2X0 Prefetch Control */ 142 + __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL); 143 + 144 + /* L2X0 Power Control */ 145 + __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, 146 + S5P_VA_L2CC + L2X0_POWER_CTRL); 147 + 148 + l2x0_init(S5P_VA_L2CC, 0x7C070001, 0xC200ffff); 149 + 150 + return 0; 151 + } 152 + 153 + early_initcall(s5pv310_l2x0_cache_init); 154 + #endif 156 155 157 156 int __init s5pv310_init(void) 158 157 {
+304
arch/arm/mach-s5pv310/gpiolib.c
··· 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);
+144
arch/arm/mach-s5pv310/hotplug.c
··· 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 + }
+40 -4
arch/arm/mach-s5pv310/include/mach/irqs.h
··· 3 3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 4 4 * http://www.samsung.com/ 5 5 * 6 - * S5PV210 - IRQ definitions 6 + * S5PV310 - IRQ definitions 7 7 * 8 8 * This program is free software; you can redistribute it and/or modify 9 9 * it under the terms of the GNU General Public License version 2 as ··· 60 60 #define IRQ_TIMER3_VIC COMBINER_IRQ(22, 3) 61 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 66 #define IRQ_UART0 COMBINER_IRQ(26, 0) 64 67 #define IRQ_UART1 COMBINER_IRQ(26, 1) 65 68 #define IRQ_UART2 COMBINER_IRQ(26, 2) ··· 70 67 #define IRQ_UART4 COMBINER_IRQ(26, 4) 71 68 72 69 #define IRQ_IIC COMBINER_IRQ(27, 0) 70 + #define IRQ_IIC1 COMBINER_IRQ(27, 1) 71 + #define IRQ_IIC2 COMBINER_IRQ(27, 2) 72 + #define IRQ_IIC3 COMBINER_IRQ(27, 3) 73 + #define IRQ_IIC4 COMBINER_IRQ(27, 4) 74 + #define IRQ_IIC5 COMBINER_IRQ(27, 5) 75 + #define IRQ_IIC6 COMBINER_IRQ(27, 6) 76 + #define IRQ_IIC7 COMBINER_IRQ(27, 7) 77 + 78 + #define IRQ_HSMMC0 COMBINER_IRQ(29, 0) 79 + #define IRQ_HSMMC1 COMBINER_IRQ(29, 1) 80 + #define IRQ_HSMMC2 COMBINER_IRQ(29, 2) 81 + #define IRQ_HSMMC3 COMBINER_IRQ(29, 3) 73 82 74 83 #define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0) 75 84 85 + #define IRQ_EINT4 COMBINER_IRQ(37, 0) 86 + #define IRQ_EINT5 COMBINER_IRQ(37, 1) 87 + #define IRQ_EINT6 COMBINER_IRQ(37, 2) 88 + #define IRQ_EINT7 COMBINER_IRQ(37, 3) 89 + #define IRQ_EINT8 COMBINER_IRQ(38, 0) 90 + 91 + #define IRQ_EINT9 COMBINER_IRQ(38, 1) 92 + #define IRQ_EINT10 COMBINER_IRQ(38, 2) 93 + #define IRQ_EINT11 COMBINER_IRQ(38, 3) 94 + #define IRQ_EINT12 COMBINER_IRQ(38, 4) 95 + #define IRQ_EINT13 COMBINER_IRQ(38, 5) 96 + #define IRQ_EINT14 COMBINER_IRQ(38, 6) 97 + #define IRQ_EINT15 COMBINER_IRQ(38, 7) 98 + 99 + #define IRQ_EINT16_31 COMBINER_IRQ(39, 0) 100 + 101 + #define MAX_COMBINER_NR 40 102 + 103 + #define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0) 104 + 105 + #define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE + 0) 106 + #define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE + 16) 107 + 76 108 /* Set the default NR_IRQS */ 77 109 78 - #define NR_IRQS COMBINER_IRQ(MAX_COMBINER_NR, 0) 79 - 80 - #define MAX_COMBINER_NR 39 110 + #define NR_IRQS (S5P_IRQ_EINT_BASE + 32) 81 111 82 112 #endif /* __ASM_ARCH_IRQS_H */
+16 -3
arch/arm/mach-s5pv310/include/mach/map.h
··· 25 25 26 26 #define S5PV310_PA_SYSRAM (0x02025000) 27 27 28 + #define S5PV310_PA_SROM_BANK(x) (0x04000000 + ((x) * 0x01000000)) 29 + 28 30 #define S5PC210_PA_ONENAND (0x0C000000) 29 31 #define S5P_PA_ONENAND S5PC210_PA_ONENAND 30 32 ··· 36 34 #define S5PV310_PA_CHIPID (0x10000000) 37 35 #define S5P_PA_CHIPID S5PV310_PA_CHIPID 38 36 39 - #define S5PV310_PA_SYSCON (0x10020000) 37 + #define S5PV310_PA_SYSCON (0x10010000) 40 38 #define S5P_PA_SYSCON S5PV310_PA_SYSCON 41 39 42 40 #define S5PV310_PA_CMU (0x10030000) 43 41 44 42 #define S5PV310_PA_WATCHDOG (0x10060000) 43 + #define S5PV310_PA_RTC (0x10070000) 45 44 46 45 #define S5PV310_PA_COMBINER (0x10448000) 47 46 ··· 58 55 59 56 #define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000)) 60 57 58 + #define S5PV310_PA_SROMC (0x12570000) 59 + 61 60 #define S5PV310_PA_UART (0x13800000) 62 61 63 62 #define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET)) ··· 71 66 72 67 #define S5P_SZ_UART SZ_256 73 68 74 - #define S5PV310_PA_IIC0 (0x13860000) 69 + #define S5PV310_PA_IIC(x) (0x13860000 + ((x) * 0x10000)) 75 70 76 71 #define S5PV310_PA_TIMER (0x139D0000) 77 72 #define S5P_PA_TIMER S5PV310_PA_TIMER ··· 85 80 #define S3C_PA_HSMMC1 S5PV310_PA_HSMMC(1) 86 81 #define S3C_PA_HSMMC2 S5PV310_PA_HSMMC(2) 87 82 #define S3C_PA_HSMMC3 S5PV310_PA_HSMMC(3) 88 - #define S3C_PA_IIC S5PV310_PA_IIC0 83 + #define S3C_PA_IIC S5PV310_PA_IIC(0) 84 + #define S3C_PA_IIC1 S5PV310_PA_IIC(1) 85 + #define S3C_PA_IIC2 S5PV310_PA_IIC(2) 86 + #define S3C_PA_IIC3 S5PV310_PA_IIC(3) 87 + #define S3C_PA_IIC4 S5PV310_PA_IIC(4) 88 + #define S3C_PA_IIC5 S5PV310_PA_IIC(5) 89 + #define S3C_PA_IIC6 S5PV310_PA_IIC(6) 90 + #define S3C_PA_IIC7 S5PV310_PA_IIC(7) 91 + #define S3C_PA_RTC S5PV310_PA_RTC 89 92 #define S3C_PA_WDT S5PV310_PA_WATCHDOG 90 93 91 94 #endif /* __ASM_ARCH_MAP_H */
+30 -2
arch/arm/mach-s5pv310/include/mach/regs-clock.h
··· 26 26 27 27 #define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210) 28 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 34 #define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250) 35 + #define S5P_CLKSRC_PERIL1 S5P_CLKREG(0x0C254) 31 36 32 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 46 #define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x0C550) 35 47 #define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x0C554) 36 48 #define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558) ··· 50 38 #define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560) 51 39 #define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564) 52 40 41 + #define S5P_CLKSRC_MASK_TOP S5P_CLKREG(0x0C310) 42 + #define S5P_CLKSRC_MASK_CAM S5P_CLKREG(0x0C320) 43 + #define S5P_CLKSRC_MASK_LCD0 S5P_CLKREG(0x0C334) 44 + #define S5P_CLKSRC_MASK_LCD1 S5P_CLKREG(0x0C338) 45 + #define S5P_CLKSRC_MASK_FSYS S5P_CLKREG(0x0C340) 53 46 #define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350) 47 + #define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354) 54 48 49 + #define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920) 50 + #define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930) 51 + #define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934) 52 + #define S5P_CLKGATE_IP_LCD1 S5P_CLKREG(0x0C938) 53 + #define S5P_CLKGATE_IP_FSYS S5P_CLKREG(0x0C940) 55 54 #define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950) 55 + #define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960) 56 56 57 57 #define S5P_CLKSRC_CORE S5P_CLKREG(0x10200) 58 58 #define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500) ··· 83 59 #define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600) 84 60 85 61 #define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800) 62 + 63 + /* Compatibility defines */ 64 + 65 + #define S5P_EPLL_CON S5P_EPLL_CON0 86 66 87 67 #endif /* __ASM_ARCH_REGS_CLOCK_H */
+42
arch/arm/mach-s5pv310/include/mach/regs-gpio.h
··· 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 */
+50
arch/arm/mach-s5pv310/include/mach/regs-srom.h
··· 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 */
+1 -1
arch/arm/mach-s5pv310/include/mach/vmalloc.h
··· 17 17 #ifndef __ASM_ARCH_VMALLOC_H 18 18 #define __ASM_ARCH_VMALLOC_H __FILE__ 19 19 20 - #define VMALLOC_END (0xF0000000UL) 20 + #define VMALLOC_END 0xF6000000UL 21 21 22 22 #endif /* __ASM_ARCH_VMALLOC_H */
+1 -5
arch/arm/mach-s5pv310/irq-combiner.c
··· 66 66 if (status == 0) 67 67 goto out; 68 68 69 - for (combiner_irq = 0; combiner_irq < 32; combiner_irq++) { 70 - if (status & 0x1) 71 - break; 72 - status >>= 1; 73 - } 69 + combiner_irq = __ffs(status); 74 70 75 71 cascade_irq = combiner_irq + (chip_data->irq_offset & ~31); 76 72 if (unlikely(cascade_irq >= NR_IRQS))
+228
arch/arm/mach-s5pv310/irq-eint.c
··· 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);
+202
arch/arm/mach-s5pv310/mach-smdkc210.c
··· 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
+117 -4
arch/arm/mach-s5pv310/mach-smdkv310.c
··· 9 9 */ 10 10 11 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 18 #include <asm/mach/arch.h> 14 19 #include <asm/mach-types.h> 15 - #include <asm/hardware/cache-l2x0.h> 16 20 17 21 #include <plat/regs-serial.h> 18 22 #include <plat/s5pv310.h> 19 23 #include <plat/cpu.h> 24 + #include <plat/devs.h> 25 + #include <plat/sdhci.h> 20 26 21 27 #include <mach/map.h> 28 + #include <mach/regs-srom.h> 22 29 23 30 /* Following are default values for UCON, ULCON and UFCON UART registers */ 24 31 #define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ ··· 72 65 }, 73 66 }; 74 67 68 + static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = { 69 + .cd_type = S3C_SDHCI_CD_GPIO, 70 + .ext_cd_gpio = S5PV310_GPK0(2), 71 + .ext_cd_gpio_invert = 1, 72 + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, 73 + #ifdef CONFIG_S5PV310_SDHCI_CH0_8BIT 74 + .max_width = 8, 75 + .host_caps = MMC_CAP_8_BIT_DATA, 76 + #endif 77 + }; 78 + 79 + static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = { 80 + .cd_type = S3C_SDHCI_CD_GPIO, 81 + .ext_cd_gpio = S5PV310_GPK0(2), 82 + .ext_cd_gpio_invert = 1, 83 + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, 84 + }; 85 + 86 + static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = { 87 + .cd_type = S3C_SDHCI_CD_GPIO, 88 + .ext_cd_gpio = S5PV310_GPK2(2), 89 + .ext_cd_gpio_invert = 1, 90 + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, 91 + #ifdef CONFIG_S5PV310_SDHCI_CH2_8BIT 92 + .max_width = 8, 93 + .host_caps = MMC_CAP_8_BIT_DATA, 94 + #endif 95 + }; 96 + 97 + static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = { 98 + .cd_type = S3C_SDHCI_CD_GPIO, 99 + .ext_cd_gpio = S5PV310_GPK2(2), 100 + .ext_cd_gpio_invert = 1, 101 + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, 102 + }; 103 + 104 + static struct resource smdkv310_smsc911x_resources[] = { 105 + [0] = { 106 + .start = S5PV310_PA_SROM_BANK(1), 107 + .end = S5PV310_PA_SROM_BANK(1) + SZ_64K - 1, 108 + .flags = IORESOURCE_MEM, 109 + }, 110 + [1] = { 111 + .start = IRQ_EINT(5), 112 + .end = IRQ_EINT(5), 113 + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, 114 + }, 115 + }; 116 + 117 + static struct smsc911x_platform_config smsc9215_config = { 118 + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH, 119 + .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, 120 + .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY, 121 + .phy_interface = PHY_INTERFACE_MODE_MII, 122 + .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67}, 123 + }; 124 + 125 + static struct platform_device smdkv310_smsc911x = { 126 + .name = "smsc911x", 127 + .id = -1, 128 + .num_resources = ARRAY_SIZE(smdkv310_smsc911x_resources), 129 + .resource = smdkv310_smsc911x_resources, 130 + .dev = { 131 + .platform_data = &smsc9215_config, 132 + }, 133 + }; 134 + 135 + static struct platform_device *smdkv310_devices[] __initdata = { 136 + &s3c_device_hsmmc0, 137 + &s3c_device_hsmmc1, 138 + &s3c_device_hsmmc2, 139 + &s3c_device_hsmmc3, 140 + &s3c_device_rtc, 141 + &s3c_device_wdt, 142 + &smdkv310_smsc911x, 143 + }; 144 + 145 + static void __init smdkv310_smsc911x_init(void) 146 + { 147 + u32 cs1; 148 + 149 + /* configure nCS1 width to 16 bits */ 150 + cs1 = __raw_readl(S5PV310_SROM_BW) & 151 + ~(S5PV310_SROM_BW__CS_MASK << 152 + S5PV310_SROM_BW__NCS1__SHIFT); 153 + cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) | 154 + (1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) | 155 + (1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) << 156 + S5PV310_SROM_BW__NCS1__SHIFT; 157 + __raw_writel(cs1, S5PV310_SROM_BW); 158 + 159 + /* set timing for nCS1 suitable for ethernet chip */ 160 + __raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) | 161 + (0x9 << S5PV310_SROM_BCX__TACP__SHIFT) | 162 + (0xc << S5PV310_SROM_BCX__TCAH__SHIFT) | 163 + (0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) | 164 + (0x6 << S5PV310_SROM_BCX__TACC__SHIFT) | 165 + (0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) | 166 + (0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1); 167 + } 168 + 75 169 static void __init smdkv310_map_io(void) 76 170 { 77 171 s5p_init_io(NULL, 0, S5P_VA_CHIPID); ··· 182 74 183 75 static void __init smdkv310_machine_init(void) 184 76 { 185 - #ifdef CONFIG_CACHE_L2X0 186 - l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff); 187 - #endif 77 + smdkv310_smsc911x_init(); 78 + 79 + s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata); 80 + s3c_sdhci1_set_platdata(&smdkv310_hsmmc1_pdata); 81 + s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata); 82 + s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata); 83 + 84 + platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices)); 188 85 } 189 86 190 87 MACHINE_START(SMDKV310, "SMDKV310")
+77 -4
arch/arm/mach-s5pv310/mach-universal_c210.c
··· 7 7 * published by the Free Software Foundation. 8 8 */ 9 9 10 + #include <linux/platform_device.h> 10 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 17 #include <asm/mach/arch.h> 13 18 #include <asm/mach-types.h> 14 - #include <asm/hardware/cache-l2x0.h> 15 19 16 20 #include <plat/regs-serial.h> 17 21 #include <plat/s5pv310.h> 18 22 #include <plat/cpu.h> 23 + #include <plat/devs.h> 19 24 20 25 #include <mach/map.h> 21 26 ··· 65 60 }, 66 61 }; 67 62 63 + static struct gpio_keys_button universal_gpio_keys_tables[] = { 64 + { 65 + .code = KEY_VOLUMEUP, 66 + .gpio = S5PV310_GPX2(0), /* XEINT16 */ 67 + .desc = "gpio-keys: KEY_VOLUMEUP", 68 + .type = EV_KEY, 69 + .active_low = 1, 70 + .debounce_interval = 1, 71 + }, { 72 + .code = KEY_VOLUMEDOWN, 73 + .gpio = S5PV310_GPX2(1), /* XEINT17 */ 74 + .desc = "gpio-keys: KEY_VOLUMEDOWN", 75 + .type = EV_KEY, 76 + .active_low = 1, 77 + .debounce_interval = 1, 78 + }, { 79 + .code = KEY_CONFIG, 80 + .gpio = S5PV310_GPX2(2), /* XEINT18 */ 81 + .desc = "gpio-keys: KEY_CONFIG", 82 + .type = EV_KEY, 83 + .active_low = 1, 84 + .debounce_interval = 1, 85 + }, { 86 + .code = KEY_CAMERA, 87 + .gpio = S5PV310_GPX2(3), /* XEINT19 */ 88 + .desc = "gpio-keys: KEY_CAMERA", 89 + .type = EV_KEY, 90 + .active_low = 1, 91 + .debounce_interval = 1, 92 + }, { 93 + .code = KEY_OK, 94 + .gpio = S5PV310_GPX3(5), /* XEINT29 */ 95 + .desc = "gpio-keys: KEY_OK", 96 + .type = EV_KEY, 97 + .active_low = 1, 98 + .debounce_interval = 1, 99 + }, 100 + }; 101 + 102 + static struct gpio_keys_platform_data universal_gpio_keys_data = { 103 + .buttons = universal_gpio_keys_tables, 104 + .nbuttons = ARRAY_SIZE(universal_gpio_keys_tables), 105 + }; 106 + 107 + static struct platform_device universal_gpio_keys = { 108 + .name = "gpio-keys", 109 + .dev = { 110 + .platform_data = &universal_gpio_keys_data, 111 + }, 112 + }; 113 + 114 + /* I2C0 */ 115 + static struct i2c_board_info i2c0_devs[] __initdata = { 116 + /* Camera, To be updated */ 117 + }; 118 + 119 + /* I2C1 */ 120 + static struct i2c_board_info i2c1_devs[] __initdata = { 121 + /* Gyro, To be updated */ 122 + }; 123 + 124 + static struct platform_device *universal_devices[] __initdata = { 125 + &universal_gpio_keys, 126 + &s5p_device_onenand, 127 + }; 128 + 68 129 static void __init universal_map_io(void) 69 130 { 70 131 s5p_init_io(NULL, 0, S5P_VA_CHIPID); ··· 140 69 141 70 static void __init universal_machine_init(void) 142 71 { 143 - #ifdef CONFIG_CACHE_L2X0 144 - l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff); 145 - #endif 72 + i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs)); 73 + i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); 74 + 75 + /* Last */ 76 + platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices)); 146 77 } 147 78 148 79 MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
+2 -4
arch/arm/mach-s5pv310/setup-i2c0.c
··· 21 21 22 22 void s3c_i2c0_cfg_gpio(struct platform_device *dev) 23 23 { 24 - s3c_gpio_cfgpin(S5PV310_GPD1(0), S3C_GPIO_SFN(2)); 25 - s3c_gpio_setpull(S5PV310_GPD1(0), 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); 24 + s3c_gpio_cfgall_range(S5PV310_GPD1(0), 2, 25 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 28 26 }
+2 -4
arch/arm/mach-s5pv310/setup-i2c1.c
··· 18 18 19 19 void s3c_i2c1_cfg_gpio(struct platform_device *dev) 20 20 { 21 - s3c_gpio_cfgpin(S5PV310_GPD1(2), S3C_GPIO_SFN(2)); 22 - s3c_gpio_setpull(S5PV310_GPD1(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); 21 + s3c_gpio_cfgall_range(S5PV310_GPD1(2), 2, 22 + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 25 23 }
+2 -4
arch/arm/mach-s5pv310/setup-i2c2.c
··· 18 18 19 19 void s3c_i2c2_cfg_gpio(struct platform_device *dev) 20 20 { 21 - s3c_gpio_cfgpin(S5PV310_GPA0(6), S3C_GPIO_SFN(3)); 22 - s3c_gpio_setpull(S5PV310_GPA0(6), 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); 21 + s3c_gpio_cfgall_range(S5PV310_GPA0(6), 2, 22 + S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP); 25 23 }
+23
arch/arm/mach-s5pv310/setup-i2c3.c
··· 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 + }
+23
arch/arm/mach-s5pv310/setup-i2c4.c
··· 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 + }
+23
arch/arm/mach-s5pv310/setup-i2c5.c
··· 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 + }
+23
arch/arm/mach-s5pv310/setup-i2c6.c
··· 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 + }
+23
arch/arm/mach-s5pv310/setup-i2c7.c
··· 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 + }
+152
arch/arm/mach-s5pv310/setup-sdhci-gpio.c
··· 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 + }
+69
arch/arm/mach-s5pv310/setup-sdhci.c
··· 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 + }
+215 -111
arch/arm/mach-shmobile/board-ap4evb.c
··· 30 30 #include <linux/mtd/mtd.h> 31 31 #include <linux/mtd/partitions.h> 32 32 #include <linux/mtd/physmap.h> 33 - #include <linux/mmc/host.h> 34 33 #include <linux/mmc/sh_mmcif.h> 35 34 #include <linux/i2c.h> 36 35 #include <linux/i2c/tsc2007.h> ··· 42 43 #include <linux/leds.h> 43 44 #include <linux/input/sh_keysc.h> 44 45 #include <linux/usb/r8a66597.h> 46 + 47 + #include <media/sh_mobile_ceu.h> 48 + #include <media/sh_mobile_csi2.h> 49 + #include <media/soc_camera.h> 45 50 46 51 #include <sound/sh_fsi.h> 47 52 ··· 241 238 /* SH_MMCIF */ 242 239 static struct resource sh_mmcif_resources[] = { 243 240 [0] = { 244 - .name = "SH_MMCIF", 241 + .name = "MMCIF", 245 242 .start = 0xE6BD0000, 246 243 .end = 0xE6BD00FF, 247 244 .flags = IORESOURCE_MEM, ··· 378 375 .resource = usb1_host_resources, 379 376 }; 380 377 378 + const static struct fb_videomode ap4evb_lcdc_modes[] = { 379 + { 380 + #ifdef CONFIG_AP4EVB_QHD 381 + .name = "R63302(QHD)", 382 + .xres = 544, 383 + .yres = 961, 384 + .left_margin = 72, 385 + .right_margin = 600, 386 + .hsync_len = 16, 387 + .upper_margin = 8, 388 + .lower_margin = 8, 389 + .vsync_len = 2, 390 + .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, 391 + #else 392 + .name = "WVGA Panel", 393 + .xres = 800, 394 + .yres = 480, 395 + .left_margin = 220, 396 + .right_margin = 110, 397 + .hsync_len = 70, 398 + .upper_margin = 20, 399 + .lower_margin = 5, 400 + .vsync_len = 5, 401 + .sync = 0, 402 + #endif 403 + }, 404 + }; 405 + 381 406 static struct sh_mobile_lcdc_info lcdc_info = { 382 407 .ch[0] = { 383 408 .chan = LCDC_CHAN_MAINLCD, 384 409 .bpp = 16, 410 + .lcd_cfg = ap4evb_lcdc_modes, 411 + .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes), 385 412 } 386 413 }; 387 414 ··· 550 517 551 518 /* FSI */ 552 519 #define IRQ_FSI evt2irq(0x1840) 553 - #define FSIACKCR 0xE6150018 554 - static void fsiackcr_init(struct clk *clk) 555 - { 556 - u32 status = __raw_readl(clk->enable_reg); 557 - 558 - /* use external clock */ 559 - status &= ~0x000000ff; 560 - status |= 0x00000080; 561 - __raw_writel(status, clk->enable_reg); 562 - } 563 - 564 - static struct clk_ops fsiackcr_clk_ops = { 565 - .init = fsiackcr_init, 566 - }; 567 - 568 - static struct clk fsiackcr_clk = { 569 - .ops = &fsiackcr_clk_ops, 570 - .enable_reg = (void __iomem *)FSIACKCR, 571 - .rate = 0, /* unknown */ 572 - }; 573 - 574 520 static struct sh_fsi_platform_info fsi_info = { 575 521 .porta_flags = SH_FSI_BRS_INV | 576 522 SH_FSI_OUT_SLAVE_MODE | ··· 589 577 .interface_type = RGB24, 590 578 .clock_divider = 1, 591 579 .flags = LCDC_FLAGS_DWPOL, 592 - .lcd_cfg = { 593 - .name = "HDMI", 594 - /* So far only 720p is supported */ 595 - .xres = 1280, 596 - .yres = 720, 597 - /* 598 - * If left and right margins are not multiples of 8, 599 - * LDHAJR will be adjusted accordingly by the LCDC 600 - * driver. Until we start using EDID, these values 601 - * might have to be adjusted for different monitors. 602 - */ 603 - .left_margin = 200, 604 - .right_margin = 88, 605 - .hsync_len = 48, 606 - .upper_margin = 20, 607 - .lower_margin = 5, 608 - .vsync_len = 5, 609 - .pixclock = 13468, 610 - .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, 611 - }, 612 580 } 613 581 }; 614 582 ··· 600 608 .flags = IORESOURCE_MEM, 601 609 }, 602 610 [1] = { 603 - .start = intcs_evt2irq(0x17a0), 611 + .start = intcs_evt2irq(0x1780), 604 612 .flags = IORESOURCE_IRQ, 605 613 }, 606 614 }; ··· 681 689 }, 682 690 }; 683 691 692 + static struct i2c_board_info imx074_info = { 693 + I2C_BOARD_INFO("imx074", 0x1a), 694 + }; 695 + 696 + struct soc_camera_link imx074_link = { 697 + .bus_id = 0, 698 + .board_info = &imx074_info, 699 + .i2c_adapter_id = 0, 700 + .module_name = "imx074", 701 + }; 702 + 703 + static struct platform_device ap4evb_camera = { 704 + .name = "soc-camera-pdrv", 705 + .id = 0, 706 + .dev = { 707 + .platform_data = &imx074_link, 708 + }, 709 + }; 710 + 711 + static struct sh_csi2_client_config csi2_clients[] = { 712 + { 713 + .phy = SH_CSI2_PHY_MAIN, 714 + .lanes = 3, 715 + .channel = 0, 716 + .pdev = &ap4evb_camera, 717 + }, 718 + }; 719 + 720 + static struct sh_csi2_pdata csi2_info = { 721 + .type = SH_CSI2C, 722 + .clients = csi2_clients, 723 + .num_clients = ARRAY_SIZE(csi2_clients), 724 + .flags = SH_CSI2_ECC | SH_CSI2_CRC, 725 + }; 726 + 727 + static struct resource csi2_resources[] = { 728 + [0] = { 729 + .name = "CSI2", 730 + .start = 0xffc90000, 731 + .end = 0xffc90fff, 732 + .flags = IORESOURCE_MEM, 733 + }, 734 + [1] = { 735 + .start = intcs_evt2irq(0x17a0), 736 + .flags = IORESOURCE_IRQ, 737 + }, 738 + }; 739 + 740 + static struct platform_device csi2_device = { 741 + .name = "sh-mobile-csi2", 742 + .id = 0, 743 + .num_resources = ARRAY_SIZE(csi2_resources), 744 + .resource = csi2_resources, 745 + .dev = { 746 + .platform_data = &csi2_info, 747 + }, 748 + }; 749 + 750 + static struct sh_mobile_ceu_info sh_mobile_ceu_info = { 751 + .flags = SH_CEU_FLAG_USE_8BIT_BUS, 752 + .csi2_dev = &csi2_device.dev, 753 + }; 754 + 755 + static struct resource ceu_resources[] = { 756 + [0] = { 757 + .name = "CEU", 758 + .start = 0xfe910000, 759 + .end = 0xfe91009f, 760 + .flags = IORESOURCE_MEM, 761 + }, 762 + [1] = { 763 + .start = intcs_evt2irq(0x880), 764 + .flags = IORESOURCE_IRQ, 765 + }, 766 + [2] = { 767 + /* place holder for contiguous memory */ 768 + }, 769 + }; 770 + 771 + static struct platform_device ceu_device = { 772 + .name = "sh_mobile_ceu", 773 + .id = 0, /* "ceu0" clock */ 774 + .num_resources = ARRAY_SIZE(ceu_resources), 775 + .resource = ceu_resources, 776 + .dev = { 777 + .platform_data = &sh_mobile_ceu_info, 778 + }, 779 + }; 780 + 684 781 static struct platform_device *ap4evb_devices[] __initdata = { 685 782 &leds_device, 686 783 &nor_flash_device, ··· 782 701 &lcdc1_device, 783 702 &lcdc_device, 784 703 &hdmi_device, 704 + &csi2_device, 705 + &ceu_device, 706 + &ap4evb_camera, 785 707 }; 786 708 787 709 static int __init hdmi_init_pm_clock(void) ··· 799 715 goto out; 800 716 } 801 717 802 - ret = clk_set_parent(&pllc2_clk, &dv_clki_div2_clk); 718 + ret = clk_set_parent(&sh7372_pllc2_clk, &sh7372_dv_clki_div2_clk); 803 719 if (ret < 0) { 804 - pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, pllc2_clk.usecount); 720 + pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, sh7372_pllc2_clk.usecount); 805 721 goto out; 806 722 } 807 723 808 - pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&pllc2_clk)); 724 + pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&sh7372_pllc2_clk)); 809 725 810 - rate = clk_round_rate(&pllc2_clk, 594000000); 726 + rate = clk_round_rate(&sh7372_pllc2_clk, 594000000); 811 727 if (rate < 0) { 812 728 pr_err("Cannot get suitable rate: %ld\n", rate); 813 729 ret = rate; 814 730 goto out; 815 731 } 816 732 817 - ret = clk_set_rate(&pllc2_clk, rate); 733 + ret = clk_set_rate(&sh7372_pllc2_clk, rate); 818 734 if (ret < 0) { 819 735 pr_err("Cannot set rate %ld: %d\n", rate, ret); 820 736 goto out; ··· 822 738 823 739 pr_debug("PLLC2 set frequency %lu\n", rate); 824 740 825 - ret = clk_set_parent(hdmi_ick, &pllc2_clk); 741 + ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); 826 742 if (ret < 0) { 827 743 pr_err("Cannot set HDMI parent: %d\n", ret); 828 744 goto out; ··· 836 752 837 753 device_initcall(hdmi_init_pm_clock); 838 754 755 + #define FSIACK_DUMMY_RATE 48000 756 + static int __init fsi_init_pm_clock(void) 757 + { 758 + struct clk *fsia_ick; 759 + int ret; 760 + 761 + /* 762 + * FSIACK is connected to AK4642, 763 + * and the rate is depend on playing sound rate. 764 + * So, set dummy rate (= 48k) here 765 + */ 766 + ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE); 767 + if (ret < 0) { 768 + pr_err("Cannot set FSIACK dummy rate: %d\n", ret); 769 + return ret; 770 + } 771 + 772 + fsia_ick = clk_get(&fsi_device.dev, "icka"); 773 + if (IS_ERR(fsia_ick)) { 774 + ret = PTR_ERR(fsia_ick); 775 + pr_err("Cannot get FSI ICK: %d\n", ret); 776 + return ret; 777 + } 778 + 779 + ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk); 780 + if (ret < 0) { 781 + pr_err("Cannot set FSI-A parent: %d\n", ret); 782 + goto out; 783 + } 784 + 785 + ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE); 786 + if (ret < 0) 787 + pr_err("Cannot set FSI-A rate: %d\n", ret); 788 + 789 + out: 790 + clk_put(fsia_ick); 791 + 792 + return ret; 793 + } 794 + device_initcall(fsi_init_pm_clock); 795 + 839 796 /* 840 797 * FIXME !! 841 798 * 842 799 * gpio_no_direction 843 - * gpio_pull_up 844 800 * are quick_hack. 845 801 * 846 802 * current gpio frame work doesn't have ··· 892 768 __raw_writeb(0x00, addr); 893 769 } 894 770 895 - static void __init gpio_pull_up(u32 addr) 896 - { 897 - u8 data = __raw_readb(addr); 898 - 899 - data &= 0x0F; 900 - data |= 0xC0; 901 - __raw_writeb(data, addr); 902 - } 903 - 904 771 /* TouchScreen */ 772 + #ifdef CONFIG_AP4EVB_QHD 773 + # define GPIO_TSC_IRQ GPIO_FN_IRQ28_123 774 + # define GPIO_TSC_PORT GPIO_PORT123 775 + #else /* WVGA */ 776 + # define GPIO_TSC_IRQ GPIO_FN_IRQ7_40 777 + # define GPIO_TSC_PORT GPIO_PORT40 778 + #endif 779 + 905 780 #define IRQ28 evt2irq(0x3380) /* IRQ28A */ 906 781 #define IRQ7 evt2irq(0x02e0) /* IRQ7A */ 907 782 static int ts_get_pendown_state(void) 908 783 { 909 - int val1, val2; 784 + int val; 910 785 911 - gpio_free(GPIO_FN_IRQ28_123); 912 - gpio_free(GPIO_FN_IRQ7_40); 786 + gpio_free(GPIO_TSC_IRQ); 913 787 914 - gpio_request(GPIO_PORT123, NULL); 915 - gpio_request(GPIO_PORT40, NULL); 788 + gpio_request(GPIO_TSC_PORT, NULL); 916 789 917 - gpio_direction_input(GPIO_PORT123); 918 - gpio_direction_input(GPIO_PORT40); 790 + gpio_direction_input(GPIO_TSC_PORT); 919 791 920 - val1 = gpio_get_value(GPIO_PORT123); 921 - val2 = gpio_get_value(GPIO_PORT40); 792 + val = gpio_get_value(GPIO_TSC_PORT); 922 793 923 - gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */ 924 - gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */ 794 + gpio_request(GPIO_TSC_IRQ, NULL); 925 795 926 - return val1 ^ val2; 796 + return !val; 927 797 } 928 798 929 - #define PORT40CR 0xE6051028 930 - #define PORT123CR 0xE605007B 931 799 static int ts_init(void) 932 800 { 933 - gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */ 934 - gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */ 935 - 936 - gpio_pull_up(PORT40CR); 937 - gpio_pull_up(PORT123CR); 801 + gpio_request(GPIO_TSC_IRQ, NULL); 938 802 939 803 return 0; 940 804 } ··· 1067 955 clk_put(clk); 1068 956 } 1069 957 1070 - /* change parent of FSI A */ 1071 - clk = clk_get(NULL, "fsia_clk"); 1072 - if (!IS_ERR(clk)) { 1073 - clk_register(&fsiackcr_clk); 1074 - clk_set_parent(clk, &fsiackcr_clk); 1075 - clk_put(clk); 1076 - } 1077 - 1078 958 /* 1079 959 * set irq priority, to avoid sound chopping 1080 960 * when NFS rootfs is used ··· 1081 977 ARRAY_SIZE(i2c1_devices)); 1082 978 1083 979 #ifdef CONFIG_AP4EVB_QHD 980 + 1084 981 /* 1085 - * QHD 982 + * For QHD Panel (MIPI-DSI, CONFIG_AP4EVB_QHD=y) and 983 + * IRQ28 for Touch Panel, set dip switches S3, S43 as OFF, ON. 1086 984 */ 1087 985 1088 986 /* enable KEYSC */ ··· 1110 1004 lcdc_info.ch[0].interface_type = RGB24; 1111 1005 lcdc_info.ch[0].clock_divider = 1; 1112 1006 lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL; 1113 - lcdc_info.ch[0].lcd_cfg.name = "R63302(QHD)"; 1114 - lcdc_info.ch[0].lcd_cfg.xres = 544; 1115 - lcdc_info.ch[0].lcd_cfg.yres = 961; 1116 - lcdc_info.ch[0].lcd_cfg.left_margin = 72; 1117 - lcdc_info.ch[0].lcd_cfg.right_margin = 600; 1118 - lcdc_info.ch[0].lcd_cfg.hsync_len = 16; 1119 - lcdc_info.ch[0].lcd_cfg.upper_margin = 8; 1120 - lcdc_info.ch[0].lcd_cfg.lower_margin = 8; 1121 - lcdc_info.ch[0].lcd_cfg.vsync_len = 2; 1122 - lcdc_info.ch[0].lcd_cfg.sync = FB_SYNC_VERT_HIGH_ACT | 1123 - FB_SYNC_HOR_HIGH_ACT; 1124 1007 lcdc_info.ch[0].lcd_size_cfg.width = 44; 1125 1008 lcdc_info.ch[0].lcd_size_cfg.height = 79; 1126 1009 ··· 1117 1022 1118 1023 #else 1119 1024 /* 1120 - * WVGA 1025 + * For WVGA Panel (18-bit RGB, CONFIG_AP4EVB_WVGA=y) and 1026 + * IRQ7 for Touch Panel, set dip switches S3, S43 to ON, OFF. 1121 1027 */ 1028 + 1122 1029 gpio_request(GPIO_FN_LCDD17, NULL); 1123 1030 gpio_request(GPIO_FN_LCDD16, NULL); 1124 1031 gpio_request(GPIO_FN_LCDD15, NULL); ··· 1152 1055 lcdc_info.ch[0].interface_type = RGB18; 1153 1056 lcdc_info.ch[0].clock_divider = 2; 1154 1057 lcdc_info.ch[0].flags = 0; 1155 - lcdc_info.ch[0].lcd_cfg.name = "WVGA Panel"; 1156 - lcdc_info.ch[0].lcd_cfg.xres = 800; 1157 - lcdc_info.ch[0].lcd_cfg.yres = 480; 1158 - lcdc_info.ch[0].lcd_cfg.left_margin = 220; 1159 - lcdc_info.ch[0].lcd_cfg.right_margin = 110; 1160 - lcdc_info.ch[0].lcd_cfg.hsync_len = 70; 1161 - lcdc_info.ch[0].lcd_cfg.upper_margin = 20; 1162 - lcdc_info.ch[0].lcd_cfg.lower_margin = 5; 1163 - lcdc_info.ch[0].lcd_cfg.vsync_len = 5; 1164 - lcdc_info.ch[0].lcd_cfg.sync = 0; 1165 1058 lcdc_info.ch[0].lcd_size_cfg.width = 152; 1166 1059 lcdc_info.ch[0].lcd_size_cfg.height = 91; 1167 1060 ··· 1161 1074 tsc_device.irq = IRQ7; 1162 1075 i2c_register_board_info(0, &tsc_device, 1); 1163 1076 #endif /* CONFIG_AP4EVB_QHD */ 1077 + 1078 + /* CEU */ 1079 + 1080 + /* 1081 + * TODO: reserve memory for V4L2 DMA buffers, when a suitable API 1082 + * becomes available 1083 + */ 1084 + 1085 + /* MIPI-CSI stuff */ 1086 + gpio_request(GPIO_FN_VIO_CKO, NULL); 1087 + 1088 + clk = clk_get(NULL, "vck1_clk"); 1089 + if (!IS_ERR(clk)) { 1090 + clk_set_rate(clk, clk_round_rate(clk, 13000000)); 1091 + clk_enable(clk); 1092 + clk_put(clk); 1093 + } 1164 1094 1165 1095 sh7372_add_standard_devices(); 1166 1096 ··· 1201 1097 shmobile_timer.init(); 1202 1098 1203 1099 /* External clock source */ 1204 - clk_set_rate(&dv_clki_clk, 27000000); 1100 + clk_set_rate(&sh7372_dv_clki_clk, 27000000); 1205 1101 } 1206 1102 1207 1103 static struct sys_timer ap4evb_timer = {
+1 -1
arch/arm/mach-shmobile/clock-sh7367.c
··· 321 321 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */ 322 322 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */ 323 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 325 CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */ 326 326 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */ 327 327 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */
+55 -23
arch/arm/mach-shmobile/clock-sh7372.c
··· 51 51 #define SMSTPCR4 0xe6150140 52 52 53 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 57 /* Fixed 32 KHz root clock from EXTALR pin */ ··· 86 86 }; 87 87 88 88 /* Divide dv_clki by two */ 89 - struct clk dv_clki_div2_clk = { 89 + struct clk sh7372_dv_clki_div2_clk = { 90 90 .ops = &div2_clk_ops, 91 - .parent = &dv_clki_clk, 91 + .parent = &sh7372_dv_clki_clk, 92 92 }; 93 93 94 94 /* Divide extal1 by two */ ··· 150 150 static struct clk *pllc2_parent[] = { 151 151 [0] = &extal1_div2_clk, 152 152 [1] = &extal2_div2_clk, 153 - [2] = &dv_clki_div2_clk, 153 + [2] = &sh7372_dv_clki_div2_clk, 154 154 }; 155 155 156 156 /* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */ ··· 284 284 .set_parent = pllc2_set_parent, 285 285 }; 286 286 287 - struct clk pllc2_clk = { 287 + struct clk sh7372_pllc2_clk = { 288 288 .ops = &pllc2_clk_ops, 289 289 .parent = &extal1_div2_clk, 290 290 .freq_table = pllc2_freq_table, ··· 292 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 302 static struct clk *main_clks[] = { 296 - &dv_clki_clk, 303 + &sh7372_dv_clki_clk, 297 304 &r_clk, 298 305 &sh7372_extal1_clk, 299 306 &sh7372_extal2_clk, 300 - &dv_clki_div2_clk, 307 + &sh7372_dv_clki_div2_clk, 301 308 &extal1_div2_clk, 302 309 &extal2_div2_clk, 303 310 &extal2_div4_clk, 304 311 &pllc0_clk, 305 312 &pllc1_clk, 306 313 &pllc1_div2_clk, 307 - &pllc2_clk, 314 + &sh7372_pllc2_clk, 315 + &sh7372_fsiack_clk, 316 + &sh7372_fsibck_clk, 308 317 }; 309 318 310 319 static void div4_kick(struct clk *clk) ··· 366 357 }; 367 358 368 359 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO, 369 - DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU, 360 + DIV6_SUB, DIV6_SPU, 370 361 DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P, 371 362 DIV6_NR }; 372 363 ··· 376 367 [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), 377 368 [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0), 378 369 [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0), 379 - [DIV6_FSIA] = SH_CLK_DIV6(&pllc1_div2_clk, FSIACKCR, 0), 380 - [DIV6_FSIB] = SH_CLK_DIV6(&pllc1_div2_clk, FSIBCKCR, 0), 381 370 [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0), 382 371 [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), 383 372 [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0), ··· 384 377 [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0), 385 378 }; 386 379 387 - enum { DIV6_HDMI, DIV6_REPARENT_NR }; 380 + enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR }; 388 381 389 382 /* Indices are important - they are the actual src selecting values */ 390 383 static struct clk *hdmi_parent[] = { 391 384 [0] = &pllc1_div2_clk, 392 - [1] = &pllc2_clk, 393 - [2] = &dv_clki_clk, 385 + [1] = &sh7372_pllc2_clk, 386 + [2] = &sh7372_dv_clki_clk, 394 387 [3] = NULL, /* pllc2_div4 not implemented yet */ 388 + }; 389 + 390 + static struct clk *fsiackcr_parent[] = { 391 + [0] = &pllc1_div2_clk, 392 + [1] = &sh7372_pllc2_clk, 393 + [2] = &sh7372_fsiack_clk, /* external input for FSI A */ 394 + [3] = NULL, /* setting prohibited */ 395 + }; 396 + 397 + static struct clk *fsibckcr_parent[] = { 398 + [0] = &pllc1_div2_clk, 399 + [1] = &sh7372_pllc2_clk, 400 + [2] = &sh7372_fsibck_clk, /* external input for FSI B */ 401 + [3] = NULL, /* setting prohibited */ 395 402 }; 396 403 397 404 static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { 398 405 [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0, 399 406 hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2), 407 + [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0, 408 + fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2), 409 + [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0, 410 + fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2), 400 411 }; 401 412 402 413 enum { MSTP001, 403 414 MSTP131, MSTP130, 404 - MSTP129, MSTP128, MSTP127, MSTP126, 415 + MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, 405 416 MSTP118, MSTP117, MSTP116, 406 417 MSTP106, MSTP101, MSTP100, 407 418 MSTP223, ··· 439 414 [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */ 440 415 [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */ 441 416 [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */ 417 + [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */ 442 418 [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */ 443 419 [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ 444 420 [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ ··· 455 429 [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ 456 430 [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ 457 431 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ 458 - [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSIA */ 432 + [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */ 459 433 [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ 460 434 [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ 461 435 [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ ··· 471 445 472 446 #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } 473 447 #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } 448 + #define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk } 474 449 475 450 static struct clk_lookup lookups[] = { 476 451 /* main clocks */ 477 - CLKDEV_CON_ID("dv_clki_div2_clk", &dv_clki_div2_clk), 452 + CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk), 478 453 CLKDEV_CON_ID("r_clk", &r_clk), 479 454 CLKDEV_CON_ID("extal1", &sh7372_extal1_clk), 480 455 CLKDEV_CON_ID("extal2", &sh7372_extal2_clk), ··· 485 458 CLKDEV_CON_ID("pllc0_clk", &pllc0_clk), 486 459 CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), 487 460 CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), 488 - CLKDEV_CON_ID("pllc2_clk", &pllc2_clk), 461 + CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk), 489 462 490 463 /* DIV4 clocks */ 491 464 CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), ··· 510 483 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), 511 484 CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), 512 485 CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), 513 - CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FSIA]), 514 - CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FSIB]), 486 + CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FSIA]), 487 + CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FSIB]), 515 488 CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), 516 489 CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), 517 490 CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), ··· 528 501 CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ 529 502 CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */ 530 503 CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */ 504 + CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */ 505 + CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */ 531 506 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ 532 507 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ 533 508 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ ··· 545 516 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */ 546 517 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ 547 518 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ 548 - CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */ 519 + CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ 549 520 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ 550 521 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ 551 522 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */ ··· 560 531 CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ 561 532 CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ 562 533 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ 563 - {.con_id = "ick", .dev_id = "sh-mobile-hdmi", .clk = &div6_reparent_clks[DIV6_HDMI]}, 534 + 535 + CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]), 536 + CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]), 537 + CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]), 564 538 }; 565 539 566 540 void __init sh7372_clock_init(void) ··· 580 548 ret = sh_clk_div6_register(div6_clks, DIV6_NR); 581 549 582 550 if (!ret) 583 - ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_NR); 551 + ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR); 584 552 585 553 if (!ret) 586 554 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+1 -1
arch/arm/mach-shmobile/clock-sh7377.c
··· 333 333 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */ 334 334 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */ 335 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 337 CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */ 338 338 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ 339 339 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */
+7 -3
arch/arm/mach-shmobile/include/mach/sh7372.h
··· 457 457 SHDMA_SLAVE_SDHI2_TX, 458 458 }; 459 459 460 - extern struct clk dv_clki_clk; 461 - extern struct clk dv_clki_div2_clk; 462 - extern struct clk pllc2_clk; 460 + extern struct clk sh7372_extal1_clk; 461 + extern struct clk sh7372_extal2_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 468 #endif /* __ASM_SH7372_H__ */
+28
arch/arm/mach-shmobile/intc-sh7372.c
··· 369 369 INTCS, 370 370 371 371 /* interrupt sources INTCS */ 372 + 373 + /* IRQ0S - IRQ31S */ 372 374 VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3, 373 375 RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3, 374 376 CEU, BEU_BEU0, BEU_BEU1, BEU_BEU2, 377 + /* MFI */ 378 + /* BBIF2 */ 375 379 VPU, 376 380 TSIF1, 377 381 _3DG_SGX530, ··· 383 379 IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2, 384 380 IPMMU_IPMMUR, IPMMU_IPMMUR2, 385 381 RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR, 382 + /* KEYSC */ 383 + /* TTI20 */ 386 384 MSIOF, 387 385 IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0, 388 386 TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, 389 387 CMT0, 390 388 TSIF0, 389 + /* CMT2 */ 391 390 LMB, 392 391 CTI, 392 + /* RWDT0 */ 393 393 ICB, 394 394 JPU_JPEG, 395 395 LCDC, ··· 405 397 CSIRX, 406 398 DSITX_DSITX0, 407 399 DSITX_DSITX1, 400 + /* SPU2 */ 401 + /* FSI */ 402 + /* FMSI */ 403 + /* HDMI */ 408 404 TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2, 409 405 CMT4, 410 406 DSITX1_DSITX1_0, 411 407 DSITX1_DSITX1_1, 408 + /* MFIS2 */ 412 409 CPORTS2R, 410 + /* CEC */ 413 411 JPU6E, 414 412 415 413 /* interrupt groups INTCS */ ··· 424 410 }; 425 411 426 412 static struct intc_vect intcs_vectors[] = { 413 + /* IRQ0S - IRQ31S */ 427 414 INTCS_VECT(VEU_VEU0, 0x700), INTCS_VECT(VEU_VEU1, 0x720), 428 415 INTCS_VECT(VEU_VEU2, 0x740), INTCS_VECT(VEU_VEU3, 0x760), 429 416 INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820), 430 417 INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860), 431 418 INTCS_VECT(CEU, 0x880), INTCS_VECT(BEU_BEU0, 0x8a0), 432 419 INTCS_VECT(BEU_BEU1, 0x8c0), INTCS_VECT(BEU_BEU2, 0x8e0), 420 + /* MFI */ 421 + /* BBIF2 */ 433 422 INTCS_VECT(VPU, 0x980), 434 423 INTCS_VECT(TSIF1, 0x9a0), 435 424 INTCS_VECT(_3DG_SGX530, 0x9e0), ··· 442 425 INTCS_VECT(IPMMU_IPMMUR, 0xb00), INTCS_VECT(IPMMU_IPMMUR2, 0xb20), 443 426 INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0), 444 427 INTCS_VECT(RTDMAC_2_DADERR, 0xbc0), 428 + /* KEYSC */ 429 + /* TTI20 */ 430 + INTCS_VECT(MSIOF, 0x0d20), 445 431 INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20), 446 432 INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60), 447 433 INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0), 448 434 INTCS_VECT(TMU_TUNI2, 0xec0), 449 435 INTCS_VECT(CMT0, 0xf00), 450 436 INTCS_VECT(TSIF0, 0xf20), 437 + /* CMT2 */ 451 438 INTCS_VECT(LMB, 0xf60), 452 439 INTCS_VECT(CTI, 0x400), 440 + /* RWDT0 */ 453 441 INTCS_VECT(ICB, 0x480), 454 442 INTCS_VECT(JPU_JPEG, 0x560), 455 443 INTCS_VECT(LCDC, 0x580), ··· 468 446 INTCS_VECT(CSIRX, 0x17a0), 469 447 INTCS_VECT(DSITX_DSITX0, 0x17c0), 470 448 INTCS_VECT(DSITX_DSITX1, 0x17e0), 449 + /* SPU2 */ 450 + /* FSI */ 451 + /* FMSI */ 452 + /* HDMI */ 471 453 INTCS_VECT(TMU1_TUNI0, 0x1900), INTCS_VECT(TMU1_TUNI1, 0x1920), 472 454 INTCS_VECT(TMU1_TUNI2, 0x1940), 473 455 INTCS_VECT(CMT4, 0x1980), 474 456 INTCS_VECT(DSITX1_DSITX1_0, 0x19a0), 475 457 INTCS_VECT(DSITX1_DSITX1_1, 0x19c0), 458 + /* MFIS2 */ 476 459 INTCS_VECT(CPORTS2R, 0x1a20), 460 + /* CEC */ 477 461 INTCS_VECT(JPU6E, 0x1a80), 478 462 479 463 INTC_VECT(INTCS, 0xf80),
+4 -4
arch/arm/mach-shmobile/pfc-sh7372.c
··· 166 166 MSIOF2_TSYNC_MARK, MSIOF2_TSCK_MARK, MSIOF2_RXD_MARK, 167 167 MSIOF2_TXD_MARK, 168 168 169 - /* MSIOF3 */ 169 + /* BBIF1 */ 170 170 BBIF1_RXD_MARK, BBIF1_TSYNC_MARK, BBIF1_TSCK_MARK, 171 171 BBIF1_TXD_MARK, BBIF1_RSCK_MARK, BBIF1_RSYNC_MARK, 172 172 BBIF1_FLOW_MARK, BB_RX_FLOW_N_MARK, 173 173 174 - /* MSIOF4 */ 174 + /* BBIF2 */ 175 175 BBIF2_TSCK1_MARK, BBIF2_TSYNC1_MARK, 176 176 BBIF2_TXD1_MARK, BBIF2_RXD_MARK, 177 177 ··· 976 976 GPIO_FN(MSIOF2_TSYNC), GPIO_FN(MSIOF2_TSCK), GPIO_FN(MSIOF2_RXD), 977 977 GPIO_FN(MSIOF2_TXD), 978 978 979 - /* MSIOF3 */ 979 + /* BBIF1 */ 980 980 GPIO_FN(BBIF1_RXD), GPIO_FN(BBIF1_TSYNC), GPIO_FN(BBIF1_TSCK), 981 981 GPIO_FN(BBIF1_TXD), GPIO_FN(BBIF1_RSCK), GPIO_FN(BBIF1_RSYNC), 982 982 GPIO_FN(BBIF1_FLOW), GPIO_FN(BB_RX_FLOW_N), 983 983 984 - /* MSIOF4 */ 984 + /* BBIF2 */ 985 985 GPIO_FN(BBIF2_TSCK1), GPIO_FN(BBIF2_TSYNC1), 986 986 GPIO_FN(BBIF2_TXD1), GPIO_FN(BBIF2_RXD), 987 987
-1
arch/arm/mach-shmobile/setup-sh7367.c
··· 154 154 .name = "CMT10", 155 155 .channel_offset = 0x10, 156 156 .timer_bit = 0, 157 - .clk = "r_clk", 158 157 .clockevent_rating = 125, 159 158 .clocksource_rating = 125, 160 159 };
+81 -13
arch/arm/mach-shmobile/setup-sh7372.c
··· 158 158 .name = "CMT10", 159 159 .channel_offset = 0x10, 160 160 .timer_bit = 0, 161 - .clk = "cmt1", 162 161 .clockevent_rating = 125, 163 162 .clocksource_rating = 125, 164 163 }; ··· 183 184 }, 184 185 .resource = cmt10_resources, 185 186 .num_resources = ARRAY_SIZE(cmt10_resources), 187 + }; 188 + 189 + /* TMU */ 190 + static struct sh_timer_config tmu00_platform_data = { 191 + .name = "TMU00", 192 + .channel_offset = 0x4, 193 + .timer_bit = 0, 194 + .clockevent_rating = 200, 195 + }; 196 + 197 + static struct resource tmu00_resources[] = { 198 + [0] = { 199 + .name = "TMU00", 200 + .start = 0xfff60008, 201 + .end = 0xfff60013, 202 + .flags = IORESOURCE_MEM, 203 + }, 204 + [1] = { 205 + .start = intcs_evt2irq(0xe80), /* TMU_TUNI0 */ 206 + .flags = IORESOURCE_IRQ, 207 + }, 208 + }; 209 + 210 + static struct platform_device tmu00_device = { 211 + .name = "sh_tmu", 212 + .id = 0, 213 + .dev = { 214 + .platform_data = &tmu00_platform_data, 215 + }, 216 + .resource = tmu00_resources, 217 + .num_resources = ARRAY_SIZE(tmu00_resources), 218 + }; 219 + 220 + static struct sh_timer_config tmu01_platform_data = { 221 + .name = "TMU01", 222 + .channel_offset = 0x10, 223 + .timer_bit = 1, 224 + .clocksource_rating = 200, 225 + }; 226 + 227 + static struct resource tmu01_resources[] = { 228 + [0] = { 229 + .name = "TMU01", 230 + .start = 0xfff60014, 231 + .end = 0xfff6001f, 232 + .flags = IORESOURCE_MEM, 233 + }, 234 + [1] = { 235 + .start = intcs_evt2irq(0xea0), /* TMU_TUNI1 */ 236 + .flags = IORESOURCE_IRQ, 237 + }, 238 + }; 239 + 240 + static struct platform_device tmu01_device = { 241 + .name = "sh_tmu", 242 + .id = 1, 243 + .dev = { 244 + .platform_data = &tmu01_platform_data, 245 + }, 246 + .resource = tmu01_resources, 247 + .num_resources = ARRAY_SIZE(tmu01_resources), 186 248 }; 187 249 188 250 /* I2C */ ··· 479 419 }, 480 420 { 481 421 /* DMA error IRQ */ 482 - .start = 246, 483 - .end = 246, 422 + .start = evt2irq(0x20c0), 423 + .end = evt2irq(0x20c0), 484 424 .flags = IORESOURCE_IRQ, 485 425 }, 486 426 { 487 427 /* IRQ for channels 0-5 */ 488 - .start = 240, 489 - .end = 245, 428 + .start = evt2irq(0x2000), 429 + .end = evt2irq(0x20a0), 490 430 .flags = IORESOURCE_IRQ, 491 431 }, 492 432 }; ··· 507 447 }, 508 448 { 509 449 /* DMA error IRQ */ 510 - .start = 254, 511 - .end = 254, 450 + .start = evt2irq(0x21c0), 451 + .end = evt2irq(0x21c0), 512 452 .flags = IORESOURCE_IRQ, 513 453 }, 514 454 { 515 455 /* IRQ for channels 0-5 */ 516 - .start = 248, 517 - .end = 253, 456 + .start = evt2irq(0x2100), 457 + .end = evt2irq(0x21a0), 518 458 .flags = IORESOURCE_IRQ, 519 459 }, 520 460 }; ··· 535 475 }, 536 476 { 537 477 /* DMA error IRQ */ 538 - .start = 262, 539 - .end = 262, 478 + .start = evt2irq(0x22c0), 479 + .end = evt2irq(0x22c0), 540 480 .flags = IORESOURCE_IRQ, 541 481 }, 542 482 { 543 483 /* IRQ for channels 0-5 */ 544 - .start = 256, 545 - .end = 261, 484 + .start = evt2irq(0x2200), 485 + .end = evt2irq(0x22a0), 546 486 .flags = IORESOURCE_IRQ, 547 487 }, 548 488 }; ··· 586 526 &scif5_device, 587 527 &scif6_device, 588 528 &cmt10_device, 529 + &tmu00_device, 530 + &tmu01_device, 531 + }; 532 + 533 + static struct platform_device *sh7372_late_devices[] __initdata = { 589 534 &iic0_device, 590 535 &iic1_device, 591 536 &dma0_device, ··· 602 537 { 603 538 platform_add_devices(sh7372_early_devices, 604 539 ARRAY_SIZE(sh7372_early_devices)); 540 + 541 + platform_add_devices(sh7372_late_devices, 542 + ARRAY_SIZE(sh7372_late_devices)); 605 543 } 606 544 607 545 void __init sh7372_add_early_devices(void)
-1
arch/arm/mach-shmobile/setup-sh7377.c
··· 172 172 .name = "CMT10", 173 173 .channel_offset = 0x10, 174 174 .timer_bit = 0, 175 - .clk = "r_clk", 176 175 .clockevent_rating = 125, 177 176 .clocksource_rating = 125, 178 177 };
+45
arch/arm/mach-ux500/cpu.c
··· 10 10 #include <linux/io.h> 11 11 #include <linux/clk.h> 12 12 13 + #include <asm/cacheflush.h> 13 14 #include <asm/hardware/cache-l2x0.h> 14 15 #include <asm/hardware/gic.h> 15 16 #include <asm/mach/map.h> ··· 72 71 } 73 72 74 73 #ifdef CONFIG_CACHE_L2X0 74 + static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask) 75 + { 76 + /* wait for the operation to complete */ 77 + while (readl(reg) & mask) 78 + ; 79 + } 80 + 81 + static inline void ux500_cache_sync(void) 82 + { 83 + void __iomem *base = __io_address(UX500_L2CC_BASE); 84 + writel(0, base + L2X0_CACHE_SYNC); 85 + ux500_cache_wait(base + L2X0_CACHE_SYNC, 1); 86 + } 87 + 88 + /* 89 + * The L2 cache cannot be turned off in the non-secure world. 90 + * Dummy until a secure service is in place. 91 + */ 92 + static void ux500_l2x0_disable(void) 93 + { 94 + } 95 + 96 + /* 97 + * This is only called when doing a kexec, just after turning off the L2 98 + * and L1 cache, and it is surrounded by a spinlock in the generic version. 99 + * However, we're not really turning off the L2 cache right now and the 100 + * PL310 does not support exclusive accesses (used to implement the spinlock). 101 + * So, the invalidation needs to be done without the spinlock. 102 + */ 103 + static void ux500_l2x0_inv_all(void) 104 + { 105 + void __iomem *l2x0_base = __io_address(UX500_L2CC_BASE); 106 + uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */ 107 + 108 + /* invalidate all ways */ 109 + writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); 110 + ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); 111 + ux500_cache_sync(); 112 + } 113 + 75 114 static int ux500_l2x0_init(void) 76 115 { 77 116 void __iomem *l2x0_base; ··· 120 79 121 80 /* 64KB way size, 8 way associativity, force WA */ 122 81 l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); 82 + 83 + /* Override invalidate function */ 84 + outer_cache.disable = ux500_l2x0_disable; 85 + outer_cache.inv_all = ux500_l2x0_inv_all; 123 86 124 87 return 0; 125 88 }
+8
arch/arm/mm/Kconfig
··· 779 779 help 780 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 790 config CACHE_TAUROS2 783 791 bool "Enable the Tauros2 L2 cache controller" 784 792 depends on (ARCH_DOVE || ARCH_MMP)
+72 -6
arch/arm/mm/cache-l2x0.c
··· 28 28 static void __iomem *l2x0_base; 29 29 static DEFINE_SPINLOCK(l2x0_lock); 30 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 36 while (readl_relaxed(reg) & mask) 36 37 ; 37 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 38 48 39 49 static inline void cache_sync(void) 40 50 { ··· 113 103 spin_unlock_irqrestore(&l2x0_lock, flags); 114 104 } 115 105 116 - static inline void l2x0_inv_all(void) 106 + static void l2x0_flush_all(void) 107 + { 108 + unsigned long flags; 109 + 110 + /* clean all ways */ 111 + spin_lock_irqsave(&l2x0_lock, flags); 112 + writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY); 113 + cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask); 114 + cache_sync(); 115 + spin_unlock_irqrestore(&l2x0_lock, flags); 116 + } 117 + 118 + static void l2x0_clean_all(void) 119 + { 120 + unsigned long flags; 121 + 122 + /* clean all ways */ 123 + spin_lock_irqsave(&l2x0_lock, flags); 124 + writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY); 125 + cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask); 126 + cache_sync(); 127 + spin_unlock_irqrestore(&l2x0_lock, flags); 128 + } 129 + 130 + static void l2x0_inv_all(void) 117 131 { 118 132 unsigned long flags; 119 133 120 134 /* invalidate all ways */ 121 135 spin_lock_irqsave(&l2x0_lock, flags); 136 + /* Invalidating when L2 is enabled is a nono */ 137 + BUG_ON(readl(l2x0_base + L2X0_CTRL) & 1); 122 138 writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); 123 - cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); 139 + cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); 124 140 cache_sync(); 125 141 spin_unlock_irqrestore(&l2x0_lock, flags); 126 142 } ··· 195 159 void __iomem *base = l2x0_base; 196 160 unsigned long flags; 197 161 162 + if ((end - start) >= l2x0_size) { 163 + l2x0_clean_all(); 164 + return; 165 + } 166 + 198 167 spin_lock_irqsave(&l2x0_lock, flags); 199 168 start &= ~(CACHE_LINE_SIZE - 1); 200 169 while (start < end) { ··· 225 184 void __iomem *base = l2x0_base; 226 185 unsigned long flags; 227 186 187 + if ((end - start) >= l2x0_size) { 188 + l2x0_flush_all(); 189 + return; 190 + } 191 + 228 192 spin_lock_irqsave(&l2x0_lock, flags); 229 193 start &= ~(CACHE_LINE_SIZE - 1); 230 194 while (start < end) { ··· 252 206 spin_unlock_irqrestore(&l2x0_lock, flags); 253 207 } 254 208 209 + static void l2x0_disable(void) 210 + { 211 + unsigned long flags; 212 + 213 + spin_lock_irqsave(&l2x0_lock, flags); 214 + writel(0, l2x0_base + L2X0_CTRL); 215 + spin_unlock_irqrestore(&l2x0_lock, flags); 216 + } 217 + 255 218 void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) 256 219 { 257 220 __u32 aux; 258 221 __u32 cache_id; 222 + __u32 way_size = 0; 259 223 int ways; 260 224 const char *type; 261 225 ··· 300 244 l2x0_way_mask = (1 << ways) - 1; 301 245 302 246 /* 247 + * L2 cache Size = Way size * Number of ways 248 + */ 249 + way_size = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17; 250 + way_size = 1 << (way_size + 3); 251 + l2x0_size = ways * way_size * SZ_1K; 252 + 253 + /* 303 254 * Check if l2x0 controller is already enabled. 304 255 * If you are booting from non-secure mode 305 256 * accessing the below registers will fault. ··· 326 263 outer_cache.clean_range = l2x0_clean_range; 327 264 outer_cache.flush_range = l2x0_flush_range; 328 265 outer_cache.sync = l2x0_cache_sync; 266 + outer_cache.flush_all = l2x0_flush_all; 267 + outer_cache.inv_all = l2x0_inv_all; 268 + outer_cache.disable = l2x0_disable; 329 269 330 270 printk(KERN_INFO "%s cache controller enabled\n", type); 331 - printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n", 332 - ways, cache_id, aux); 271 + printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", 272 + ways, cache_id, aux, l2x0_size); 333 273 }
+1
arch/arm/plat-mxc/Makefile
··· 18 18 obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o 19 19 obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o 20 20 obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o 21 + obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o 21 22 ifdef CONFIG_SND_IMX_SOC 22 23 obj-y += ssi-fiq.o 23 24 obj-y += ssi-fiq-ksym.o
+206
arch/arm/plat-mxc/cpufreq.c
··· 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");
+5 -1
arch/arm/plat-mxc/devices/Kconfig
··· 6 6 default y if ARCH_MX25 || SOC_IMX27 || ARCH_MX35 || ARCH_MX51 7 7 8 8 config IMX_HAVE_PLATFORM_FLEXCAN 9 - select HAVE_CAN_FLEXCAN 9 + select HAVE_CAN_FLEXCAN if CAN 10 10 bool 11 11 12 + config IMX_HAVE_PLATFORM_GPIO_KEYS 13 + bool 14 + default y if ARCH_MX51 15 + 12 16 config IMX_HAVE_PLATFORM_IMX_I2C 13 17 bool 14 18
+1
arch/arm/plat-mxc/devices/Makefile
··· 1 1 obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o 2 2 obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o 3 3 obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o 4 + obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o 4 5 obj-y += platform-imx-dma.o 5 6 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o 6 7 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o
+27
arch/arm/plat-mxc/devices/platform-gpio_keys.c
··· 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 + }
+32
arch/arm/plat-mxc/gpio.c
··· 20 20 */ 21 21 22 22 #include <linux/init.h> 23 + #include <linux/interrupt.h> 23 24 #include <linux/io.h> 24 25 #include <linux/irq.h> 25 26 #include <linux/gpio.h> ··· 202 201 } 203 202 } 204 203 204 + /* 205 + * Set interrupt number "irq" in the GPIO as a wake-up source. 206 + * While system is running, all registered GPIO interrupts need to have 207 + * wake-up enabled. When system is suspended, only selected GPIO interrupts 208 + * need to have wake-up enabled. 209 + * @param irq interrupt source number 210 + * @param enable enable as wake-up if equal to non-zero 211 + * @return This function returns 0 on success. 212 + */ 213 + static int gpio_set_wake_irq(u32 irq, u32 enable) 214 + { 215 + u32 gpio = irq_to_gpio(irq); 216 + u32 gpio_idx = gpio & 0x1F; 217 + struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; 218 + 219 + if (enable) { 220 + if (port->irq_high && (gpio_idx >= 16)) 221 + enable_irq_wake(port->irq_high); 222 + else 223 + enable_irq_wake(port->irq); 224 + } else { 225 + if (port->irq_high && (gpio_idx >= 16)) 226 + disable_irq_wake(port->irq_high); 227 + else 228 + disable_irq_wake(port->irq); 229 + } 230 + 231 + return 0; 232 + } 233 + 205 234 static struct irq_chip gpio_irq_chip = { 206 235 .ack = gpio_ack_irq, 207 236 .mask = gpio_mask_irq, 208 237 .unmask = gpio_unmask_irq, 209 238 .set_type = gpio_set_irq_type, 239 + .set_wake = gpio_set_wake_irq, 210 240 }; 211 241 212 242 static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+4
arch/arm/plat-mxc/include/mach/devices-common.h
··· 29 29 resource_size_t irq, 30 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 36 #include <mach/i2c.h> 33 37 struct imx_imx_i2c_data { 34 38 int id;
+2
arch/arm/plat-mxc/include/mach/iomux-mx51.h
··· 45 45 PAD_CTL_PKE | PAD_CTL_HYS) 46 46 #define MX51_GPIO_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | \ 47 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 50 #define MX51_ECSPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \ 49 51 PAD_CTL_SRE_FAST) 50 52 #define MX51_SDHCI_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP | \
-1
arch/arm/plat-mxc/include/mach/mx31.h
··· 240 240 #define MPEG4_ENC_BASE_ADDR MX31_MPEG4_ENC_BASE_ADDR 241 241 #define MXC_INT_MPEG4_ENCODER MX31_INT_MPEG4_ENCODER 242 242 #define MXC_INT_FIRI MX31_INT_FIRI 243 - #define MXC_INT_MMC_SDHC1 MX31_INT_MMC_SDHC1 244 243 #define MXC_INT_MBX MX31_INT_MBX 245 244 #define MXC_INT_CSPI3 MX31_INT_CSPI3 246 245 #define MXC_INT_SIM2 MX31_INT_SIM2
-2
arch/arm/plat-mxc/include/mach/mx35.h
··· 197 197 /* these should go away */ 198 198 #define MXC_FEC_BASE_ADDR MX35_FEC_BASE_ADDR 199 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 200 #define MXC_INT_GPU2D MX35_INT_GPU2D 203 201 #define MXC_INT_ASRC MX35_INT_ASRC 204 202 #define MXC_INT_USBHS MX35_INT_USBHS
+12 -1
arch/arm/plat-mxc/include/mach/mxc.h
··· 1 1 /* 2 - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. 2 + * Copyright 2004-2007, 2010 Freescale Semiconductor, Inc. All Rights Reserved. 3 3 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) 4 4 * 5 5 * This program is free software; you can redistribute it and/or ··· 19 19 20 20 #ifndef __ASM_ARCH_MXC_H__ 21 21 #define __ASM_ARCH_MXC_H__ 22 + 23 + #include <linux/types.h> 22 24 23 25 #ifndef __ASM_ARCH_MXC_HARDWARE_H__ 24 26 #error "Do not include directly." ··· 133 131 # define cpu_is_mxc91231() (mxc_cpu_type == MXC_CPU_MXC91231) 134 132 #else 135 133 # define cpu_is_mxc91231() (0) 134 + #endif 135 + 136 + #ifndef __ASSEMBLY__ 137 + 138 + struct cpu_op { 139 + u32 cpu_rate; 140 + }; 141 + 142 + extern struct cpu_op *(*get_cpu_op)(int *op); 136 143 #endif 137 144 138 145 #if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
+1 -1
arch/arm/plat-s3c24xx/common-smdk.c
··· 147 147 [7] = { 148 148 .name = "S3C2410 flash partition 7", 149 149 .offset = SZ_1M * 48, 150 - .size = SZ_16M, 150 + .size = MTDPART_SIZ_FULL, 151 151 } 152 152 }; 153 153
+2 -6
arch/arm/plat-s3c24xx/gpiolib.c
··· 74 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 77 static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = { 83 78 .set_config = s3c_gpio_setcfg_s3c24xx_a, 84 79 .get_config = s3c_gpio_getcfg_s3c24xx_a, ··· 152 157 [6] = { 153 158 .base = S3C2410_GPGCON, 154 159 .pm = __gpio_pm(&s3c_gpio_pm_2bit), 160 + .irq_base = IRQ_EINT8, 155 161 .chip = { 156 162 .base = S3C2410_GPG(0), 157 163 .owner = THIS_MODULE, 158 164 .label = "GPIOG", 159 165 .ngpio = 16, 160 - .to_irq = s3c24xx_gpiolib_bankg_toirq, 166 + .to_irq = samsung_gpiolib_to_irq, 161 167 }, 162 168 }, { 163 169 .base = S3C2410_GPHCON,
+5
arch/arm/plat-s5p/Kconfig
··· 32 32 Use the external interrupts (other than GPIO interrupts.) 33 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 40 config S5P_DEV_FIMC0 36 41 bool 37 42 help
+3
arch/arm/plat-s5p/Makefile
··· 18 18 obj-y += clock.o 19 19 obj-y += irq.o 20 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 25 # devices 23 26
+20 -9
arch/arm/plat-s5p/clock.c
··· 21 21 #include <linux/io.h> 22 22 #include <asm/div64.h> 23 23 24 + #include <mach/regs-clock.h> 25 + 24 26 #include <plat/clock.h> 25 27 #include <plat/clock-clksrc.h> 26 28 #include <plat/s5p-clock.h> ··· 90 88 .ctrlbit = (1 << 31), 91 89 }; 92 90 93 - /* ARM clock */ 94 - struct clk clk_arm = { 95 - .name = "armclk", 96 - .id = -1, 97 - .rate = 0, 98 - .ctrlbit = 0, 99 - }; 100 - 101 91 /* Possible clock sources for APLL Mux */ 102 92 static struct clk *clk_src_apll_list[] = { 103 93 [0] = &clk_fin_apll, ··· 150 156 return 0; 151 157 } 152 158 159 + int s5p_epll_enable(struct clk *clk, int enable) 160 + { 161 + unsigned int ctrlbit = clk->ctrlbit; 162 + unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; 163 + 164 + if (enable) 165 + __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); 166 + else 167 + __raw_writel(epll_con, S5P_EPLL_CON); 168 + 169 + return 0; 170 + } 171 + 172 + unsigned long s5p_epll_get_rate(struct clk *clk) 173 + { 174 + return clk->rate; 175 + } 176 + 153 177 static struct clk *s5p_clks[] __initdata = { 154 178 &clk_ext_xtal_mux, 155 179 &clk_48m, ··· 177 165 &clk_fout_epll, 178 166 &clk_fout_dpll, 179 167 &clk_fout_vpll, 180 - &clk_arm, 181 168 &clk_vpll, 182 169 &clk_xusbxti, 183 170 };
+18
arch/arm/plat-s5p/include/plat/irqs.h
··· 94 94 ((irq) - S5P_EINT_BASE1) : \ 95 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 115 #endif /* __ASM_PLAT_S5P_IRQS_H */
+23 -15
arch/arm/plat-s5p/include/plat/map-s5p.h
··· 13 13 #ifndef __ASM_PLAT_MAP_S5P_H 14 14 #define __ASM_PLAT_MAP_S5P_H __FILE__ 15 15 16 - #define S5P_VA_CHIPID S3C_ADDR(0x00700000) 17 - #define S5P_VA_GPIO S3C_ADDR(0x00500000) 18 - #define S5P_VA_SYSTIMER S3C_ADDR(0x01200000) 19 - #define S5P_VA_SROMC S3C_ADDR(0x01100000) 20 - #define S5P_VA_SYSRAM S3C_ADDR(0x01180000) 16 + #define S5P_VA_CHIPID S3C_ADDR(0x02000000) 17 + #define S5P_VA_CMU S3C_ADDR(0x02100000) 18 + #define S5P_VA_GPIO S3C_ADDR(0x02200000) 19 + #define S5P_VA_GPIO1 S5P_VA_GPIO 20 + #define S5P_VA_GPIO2 S3C_ADDR(0x02240000) 21 + #define S5P_VA_GPIO3 S3C_ADDR(0x02280000) 21 22 22 - #define S5P_VA_COMBINER_BASE S3C_ADDR(0x00600000) 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 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 35 #define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x)) 27 36 #define S5P_VA_SCU S5P_VA_COREPERI(0x0) 28 37 #define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100) 29 38 #define S5P_VA_TWD S5P_VA_COREPERI(0x600) 30 39 #define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000) 31 40 32 - #define S5P_VA_L2CC S3C_ADDR(0x00900000) 33 - #define S5P_VA_CMU S3C_ADDR(0x00920000) 41 + #define S3C_VA_USB_HSPHY S3C_ADDR(0x02900000) 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 49 #define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) 36 50 #define S5P_VA_UART0 S5P_VA_UART(0) ··· 55 41 #ifndef S3C_UART_OFFSET 56 42 #define S3C_UART_OFFSET (0x400) 57 43 #endif 58 - 59 - #define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000)) 60 - #define VA_VIC0 VA_VIC(0) 61 - #define VA_VIC1 VA_VIC(1) 62 - #define VA_VIC2 VA_VIC(2) 63 - #define VA_VIC3 VA_VIC(3) 64 44 65 45 #endif /* __ASM_PLAT_MAP_S5P_H */
+4
arch/arm/plat-s5p/include/plat/s5p-clock.h
··· 43 43 44 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 50 #endif /* __ASM_PLAT_S5P_CLOCK_H */
+5 -5
arch/arm/plat-s5p/irq-eint.c
··· 67 67 68 68 switch (type) { 69 69 case IRQ_TYPE_EDGE_RISING: 70 - newvalue = S5P_EXTINT_RISEEDGE; 70 + newvalue = S5P_IRQ_TYPE_EDGE_RISING; 71 71 break; 72 72 73 73 case IRQ_TYPE_EDGE_FALLING: 74 - newvalue = S5P_EXTINT_FALLEDGE; 74 + newvalue = S5P_IRQ_TYPE_EDGE_FALLING; 75 75 break; 76 76 77 77 case IRQ_TYPE_EDGE_BOTH: 78 - newvalue = S5P_EXTINT_BOTHEDGE; 78 + newvalue = S5P_IRQ_TYPE_EDGE_BOTH; 79 79 break; 80 80 81 81 case IRQ_TYPE_LEVEL_LOW: 82 - newvalue = S5P_EXTINT_LOWLEV; 82 + newvalue = S5P_IRQ_TYPE_LEVEL_LOW; 83 83 break; 84 84 85 85 case IRQ_TYPE_LEVEL_HIGH: 86 - newvalue = S5P_EXTINT_HILEV; 86 + newvalue = S5P_IRQ_TYPE_LEVEL_HIGH; 87 87 break; 88 88 89 89 default:
+237
arch/arm/plat-s5p/irq-gpioint.c
··· 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 + }
+93
arch/arm/plat-s5p/irq-pm.c
··· 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 +
+52
arch/arm/plat-s5p/pm.c
··· 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 +
+25
arch/arm/plat-samsung/Kconfig
··· 180 180 help 181 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 208 config S3C_DEV_FB 184 209 bool 185 210 help
+5
arch/arm/plat-samsung/Makefile
··· 40 40 obj-y += dev-i2c0.o 41 41 obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o 42 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 48 obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o 44 49 obj-y += dev-uart.o 45 50 obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
+6 -2
arch/arm/plat-samsung/dev-hsmmc.c
··· 41 41 .max_width = 4, 42 42 .host_caps = (MMC_CAP_4_BIT_DATA | 43 43 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), 44 + .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, 44 45 }; 45 46 46 47 struct platform_device s3c_device_hsmmc0 = { ··· 60 59 { 61 60 struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata; 62 61 63 - set->max_width = pd->max_width; 64 62 set->cd_type = pd->cd_type; 65 63 set->ext_cd_init = pd->ext_cd_init; 66 64 set->ext_cd_cleanup = pd->ext_cd_cleanup; 67 65 set->ext_cd_gpio = pd->ext_cd_gpio; 68 66 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; 69 67 68 + if (pd->max_width) 69 + set->max_width = pd->max_width; 70 70 if (pd->cfg_gpio) 71 71 set->cfg_gpio = pd->cfg_gpio; 72 72 if (pd->cfg_card) 73 73 set->cfg_card = pd->cfg_card; 74 74 if (pd->host_caps) 75 - set->host_caps = pd->host_caps; 75 + set->host_caps |= pd->host_caps; 76 + if (pd->clk_type) 77 + set->clk_type = pd->clk_type; 76 78 }
+6 -2
arch/arm/plat-samsung/dev-hsmmc1.c
··· 41 41 .max_width = 4, 42 42 .host_caps = (MMC_CAP_4_BIT_DATA | 43 43 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), 44 + .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, 44 45 }; 45 46 46 47 struct platform_device s3c_device_hsmmc1 = { ··· 60 59 { 61 60 struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata; 62 61 63 - set->max_width = pd->max_width; 64 62 set->cd_type = pd->cd_type; 65 63 set->ext_cd_init = pd->ext_cd_init; 66 64 set->ext_cd_cleanup = pd->ext_cd_cleanup; 67 65 set->ext_cd_gpio = pd->ext_cd_gpio; 68 66 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; 69 67 68 + if (pd->max_width) 69 + set->max_width = pd->max_width; 70 70 if (pd->cfg_gpio) 71 71 set->cfg_gpio = pd->cfg_gpio; 72 72 if (pd->cfg_card) 73 73 set->cfg_card = pd->cfg_card; 74 74 if (pd->host_caps) 75 - set->host_caps = pd->host_caps; 75 + set->host_caps |= pd->host_caps; 76 + if (pd->clk_type) 77 + set->clk_type = pd->clk_type; 76 78 }
+6 -2
arch/arm/plat-samsung/dev-hsmmc2.c
··· 42 42 .max_width = 4, 43 43 .host_caps = (MMC_CAP_4_BIT_DATA | 44 44 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), 45 + .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, 45 46 }; 46 47 47 48 struct platform_device s3c_device_hsmmc2 = { ··· 61 60 { 62 61 struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata; 63 62 64 - set->max_width = pd->max_width; 65 63 set->cd_type = pd->cd_type; 66 64 set->ext_cd_init = pd->ext_cd_init; 67 65 set->ext_cd_cleanup = pd->ext_cd_cleanup; 68 66 set->ext_cd_gpio = pd->ext_cd_gpio; 69 67 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; 70 68 69 + if (pd->max_width) 70 + set->max_width = pd->max_width; 71 71 if (pd->cfg_gpio) 72 72 set->cfg_gpio = pd->cfg_gpio; 73 73 if (pd->cfg_card) 74 74 set->cfg_card = pd->cfg_card; 75 75 if (pd->host_caps) 76 - 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; 77 79 }
+9 -3
arch/arm/plat-samsung/dev-hsmmc3.c
··· 33 33 .flags = IORESOURCE_MEM, 34 34 }, 35 35 [1] = { 36 - .start = IRQ_MMC3, 37 - .end = IRQ_MMC3, 36 + .start = IRQ_HSMMC3, 37 + .end = IRQ_HSMMC3, 38 38 .flags = IORESOURCE_IRQ, 39 39 } 40 40 }; ··· 45 45 .max_width = 4, 46 46 .host_caps = (MMC_CAP_4_BIT_DATA | 47 47 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), 48 + .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, 48 49 }; 49 50 50 51 struct platform_device s3c_device_hsmmc3 = { ··· 64 63 { 65 64 struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata; 66 65 67 - set->max_width = pd->max_width; 68 66 set->cd_type = pd->cd_type; 69 67 set->ext_cd_init = pd->ext_cd_init; 70 68 set->ext_cd_cleanup = pd->ext_cd_cleanup; 71 69 set->ext_cd_gpio = pd->ext_cd_gpio; 72 70 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; 73 71 72 + if (pd->max_width) 73 + set->max_width = pd->max_width; 74 74 if (pd->cfg_gpio) 75 75 set->cfg_gpio = pd->cfg_gpio; 76 76 if (pd->cfg_card) 77 77 set->cfg_card = pd->cfg_card; 78 + if (pd->host_caps) 79 + set->host_caps |= pd->host_caps; 80 + if (pd->clk_type) 81 + set->clk_type = pd->clk_type; 78 82 }
+2 -2
arch/arm/plat-samsung/dev-i2c2.c
··· 32 32 .flags = IORESOURCE_MEM, 33 33 }, 34 34 [1] = { 35 - .start = IRQ_CAN0, 36 - .end = IRQ_CAN0, 35 + .start = IRQ_IIC2, 36 + .end = IRQ_IIC2, 37 37 .flags = IORESOURCE_IRQ, 38 38 }, 39 39 };
+68
arch/arm/plat-samsung/dev-i2c3.c
··· 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 + }
+68
arch/arm/plat-samsung/dev-i2c4.c
··· 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 + }
+68
arch/arm/plat-samsung/dev-i2c5.c
··· 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 + }
+68
arch/arm/plat-samsung/dev-i2c6.c
··· 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 + }
+68
arch/arm/plat-samsung/dev-i2c7.c
··· 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 + }
+50
arch/arm/plat-samsung/gpio-config.c
··· 41 41 } 42 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 75 unsigned s3c_gpio_getcfg(unsigned int pin) 45 76 { 46 77 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); ··· 110 79 return ret; 111 80 } 112 81 EXPORT_SYMBOL(s3c_gpio_setpull); 82 + 83 + s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin) 84 + { 85 + struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); 86 + unsigned long flags; 87 + int offset; 88 + u32 pup = 0; 89 + 90 + if (chip) { 91 + offset = pin - chip->chip.base; 92 + 93 + s3c_gpio_lock(chip, flags); 94 + pup = s3c_gpio_do_getpull(chip, offset); 95 + s3c_gpio_unlock(chip, flags); 96 + } 97 + 98 + return (__force s3c_gpio_pull_t)pup; 99 + } 100 + EXPORT_SYMBOL(s3c_gpio_getpull); 113 101 114 102 #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX 115 103 int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+8
arch/arm/plat-samsung/gpio.c
··· 157 157 if (ret >= 0) 158 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 + }
+9
arch/arm/plat-samsung/include/plat/audio.h
··· 16 16 #define S3C64XX_AC97_GPE 1 17 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 29 * struct s3c_audio_pdata - common platform data for audio device drivers 21 30 * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
+7
arch/arm/plat-samsung/include/plat/devs.h
··· 48 48 extern struct platform_device s3c_device_i2c0; 49 49 extern struct platform_device s3c_device_i2c1; 50 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 56 extern struct platform_device s3c_device_rtc; 52 57 extern struct platform_device s3c_device_adc; 53 58 extern struct platform_device s3c_device_sdi; ··· 94 89 extern struct platform_device s5pv210_device_iis0; 95 90 extern struct platform_device s5pv210_device_iis1; 96 91 extern struct platform_device s5pv210_device_iis2; 92 + extern struct platform_device s5pv210_device_spdif; 97 93 98 94 extern struct platform_device s5p6442_device_pcm0; 99 95 extern struct platform_device s5p6442_device_pcm1; ··· 114 108 extern struct platform_device s5pc100_device_iis0; 115 109 extern struct platform_device s5pc100_device_iis1; 116 110 extern struct platform_device s5pc100_device_iis2; 111 + extern struct platform_device s5pc100_device_spdif; 117 112 118 113 extern struct platform_device samsung_device_keypad; 119 114
+6
arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
··· 42 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 52 * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration. 47 53 * @chip: The gpio chip that is being configured.
+56
arch/arm/plat-samsung/include/plat/gpio-cfg.h
··· 108 108 */ 109 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 124 /* Define values for the pull-{up,down} available for each gpio pin. 112 125 * 113 126 * These values control the state of the weak pull-{up,down} resistors ··· 153 140 */ 154 141 extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); 155 142 143 + /* configure `all` aspects of an gpio */ 144 + 145 + /** 146 + * s3c_gpio_cfgall_range() - configure range of gpio functtion and pull. 147 + * @start: The gpio number to start at. 148 + * @nr: The number of gpio to configure from @start. 149 + * @cfg: The configuration to use 150 + * @pull: The pull setting to use. 151 + * 152 + * Run s3c_gpio_cfgpin() and s3c_gpio_setpull() over the gpio range starting 153 + * @gpio and running for @size. 154 + * 155 + * @sa s3c_gpio_cfgpin 156 + * @sa s3c_gpio_setpull 157 + * @sa s3c_gpio_cfgpin_range 158 + */ 159 + extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, 160 + unsigned int cfg, s3c_gpio_pull_t pull); 161 + 162 + static inline int s3c_gpio_cfgrange_nopull(unsigned int pin, unsigned int size, 163 + unsigned int cfg) 164 + { 165 + return s3c_gpio_cfgall_range(pin, size, cfg, S3C_GPIO_PULL_NONE); 166 + } 167 + 156 168 /* Define values for the drvstr available for each gpio pin. 157 169 * 158 170 * These values control the value of the output signal driver strength, ··· 206 168 * cannot support the requested setting. 207 169 */ 208 170 extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr); 171 + 172 + /** 173 + * s5p_register_gpio_interrupt() - register interrupt support for a gpio group 174 + * @pin: The pin number from the group to be registered 175 + * 176 + * This function registers gpio interrupt support for the group that the 177 + * specified pin belongs to. 178 + * 179 + * The total number of gpio pins is quite large ob s5p series. Registering 180 + * irq support for all of them would be a resource waste. Because of that the 181 + * interrupt support for standard gpio pins is registered dynamically. 182 + * 183 + * It will return the irq number of the interrupt that has been registered 184 + * or -ENOMEM if no more gpio interrupts can be registered. It is allowed 185 + * to call this function more than once for the same gpio group (the group 186 + * will be registered only once). 187 + */ 188 + extern int s5p_register_gpio_interrupt(int pin); 209 189 210 190 #endif /* __PLAT_GPIO_CFG_H */
+15
arch/arm/plat-samsung/include/plat/gpio-core.h
··· 43 43 * struct s3c_gpio_chip - wrapper for specific implementation of gpio 44 44 * @chip: The chip structure to be exported via gpiolib. 45 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 48 * @config: special function and pull-resistor control information. 47 49 * @lock: Lock for exclusive access to this gpio bank. 48 50 * @pm_save: Save information for suspend/resume support. ··· 65 63 struct s3c_gpio_cfg *config; 66 64 struct s3c_gpio_pm *pm; 67 65 void __iomem *base; 66 + int irq_base; 67 + int group; 68 68 spinlock_t lock; 69 69 #ifdef CONFIG_PM 70 70 u32 pm_save[4]; ··· 121 117 122 118 extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip); 123 119 extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip); 120 + 121 + 122 + /** 123 + * samsung_gpiolib_to_irq - convert gpio pin to irq number 124 + * @chip: The gpio chip that the pin belongs to. 125 + * @offset: The offset of the pin in the chip. 126 + * 127 + * This helper returns the irq number calculated from the chip->irq_base and 128 + * the provided offset. 129 + */ 130 + extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset); 124 131 125 132 /* exported for core SoC support to change */ 126 133 extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
+10
arch/arm/plat-samsung/include/plat/iic.h
··· 55 55 extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c); 56 56 extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c); 57 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 64 /* defined by architecture to configure gpio */ 60 65 extern void s3c_i2c0_cfg_gpio(struct platform_device *dev); 61 66 extern void s3c_i2c1_cfg_gpio(struct platform_device *dev); 62 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 74 #endif /* __ASM_ARCH_IIC_H */
+2 -2
arch/arm/plat-samsung/include/plat/map-base.h
··· 14 14 #ifndef __ASM_PLAT_MAP_H 15 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 18 * little of the VA space as possible so vmalloc and friends have a 19 19 * better chance of getting memory. 20 20 * ··· 22 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 27 #ifndef __ASSEMBLY__ 28 28 #define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
+28
arch/arm/plat-samsung/include/plat/nand-core.h
··· 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 */
+64
arch/arm/plat-samsung/include/plat/sdhci.h
··· 28 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 37 * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI 33 38 * @max_width: The maximum number of data bits supported. 34 39 * @host_caps: Standard MMC host capabilities bit field. 35 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 42 * @ext_cd_init: Initialize external card detect subsystem. Called on 37 43 * sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL. 38 44 * notify_func argument is a callback to the sdhci-s3c driver ··· 65 59 unsigned int max_width; 66 60 unsigned int host_caps; 67 61 enum cd_types cd_type; 62 + enum clk_types clk_type; 68 63 69 64 char **clocks; /* set of clock sources */ 70 65 ··· 117 110 extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w); 118 111 extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w); 119 112 extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w); 113 + extern void s5pv310_setup_sdhci0_cfg_gpio(struct platform_device *, int w); 114 + extern void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *, int w); 115 + extern void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *, int w); 116 + extern void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *, int w); 120 117 121 118 /* S3C64XX SDHCI setup */ 122 119 ··· 298 287 static inline void s5pv210_default_sdhci3(void) { } 299 288 300 289 #endif /* CONFIG_S5PV210_SETUP_SDHCI */ 290 + 291 + /* S5PV310 SDHCI setup */ 292 + #ifdef CONFIG_S5PV310_SETUP_SDHCI 293 + extern char *s5pv310_hsmmc_clksrcs[4]; 294 + 295 + extern void s5pv310_setup_sdhci_cfg_card(struct platform_device *dev, 296 + void __iomem *r, 297 + struct mmc_ios *ios, 298 + struct mmc_card *card); 299 + 300 + static inline void s5pv310_default_sdhci0(void) 301 + { 302 + #ifdef CONFIG_S3C_DEV_HSMMC 303 + s3c_hsmmc0_def_platdata.clocks = s5pv310_hsmmc_clksrcs; 304 + s3c_hsmmc0_def_platdata.cfg_gpio = s5pv310_setup_sdhci0_cfg_gpio; 305 + s3c_hsmmc0_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card; 306 + #endif 307 + } 308 + 309 + static inline void s5pv310_default_sdhci1(void) 310 + { 311 + #ifdef CONFIG_S3C_DEV_HSMMC1 312 + s3c_hsmmc1_def_platdata.clocks = s5pv310_hsmmc_clksrcs; 313 + s3c_hsmmc1_def_platdata.cfg_gpio = s5pv310_setup_sdhci1_cfg_gpio; 314 + s3c_hsmmc1_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card; 315 + #endif 316 + } 317 + 318 + static inline void s5pv310_default_sdhci2(void) 319 + { 320 + #ifdef CONFIG_S3C_DEV_HSMMC2 321 + s3c_hsmmc2_def_platdata.clocks = s5pv310_hsmmc_clksrcs; 322 + s3c_hsmmc2_def_platdata.cfg_gpio = s5pv310_setup_sdhci2_cfg_gpio; 323 + s3c_hsmmc2_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card; 324 + #endif 325 + } 326 + 327 + static inline void s5pv310_default_sdhci3(void) 328 + { 329 + #ifdef CONFIG_S3C_DEV_HSMMC3 330 + s3c_hsmmc3_def_platdata.clocks = s5pv310_hsmmc_clksrcs; 331 + s3c_hsmmc3_def_platdata.cfg_gpio = s5pv310_setup_sdhci3_cfg_gpio; 332 + s3c_hsmmc3_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card; 333 + #endif 334 + } 335 + 336 + #else 337 + static inline void s5pv310_default_sdhci0(void) { } 338 + static inline void s5pv310_default_sdhci1(void) { } 339 + static inline void s5pv310_default_sdhci2(void) { } 340 + static inline void s5pv310_default_sdhci3(void) { } 341 + 342 + #endif /* CONFIG_S5PV310_SETUP_SDHCI */ 301 343 302 344 #endif /* __PLAT_S3C_SDHCI_H */
+2 -2
arch/arm/plat-samsung/pm-gpio.c
··· 192 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 196 static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip) 197 197 { 198 198 chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON); ··· 302 302 .save = s3c_gpio_pm_4bit_save, 303 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 308 * s3c_pm_save_gpio() - save gpio chip data for suspend
+28 -8
arch/arm/plat-samsung/s3c-pl330.c
··· 15 15 #include <linux/io.h> 16 16 #include <linux/slab.h> 17 17 #include <linux/platform_device.h> 18 + #include <linux/clk.h> 19 + #include <linux/err.h> 18 20 19 21 #include <asm/hardware/pl330.h> 20 22 ··· 29 27 * @node: To attach to the global list of DMACs. 30 28 * @pi: PL330 configuration info for the DMAC. 31 29 * @kmcache: Pool to quickly allocate xfers for all channels in the dmac. 30 + * @clk: Pointer of DMAC operation clock. 32 31 */ 33 32 struct s3c_pl330_dmac { 34 33 unsigned busy_chan; ··· 37 34 struct list_head node; 38 35 struct pl330_info *pi; 39 36 struct kmem_cache *kmcache; 37 + struct clk *clk; 40 38 }; 41 39 42 40 /** ··· 1076 1072 if (ret) 1077 1073 goto probe_err4; 1078 1074 1079 - ret = pl330_add(pl330_info); 1080 - if (ret) 1081 - goto probe_err5; 1082 - 1083 1075 /* Allocate a new DMAC */ 1084 1076 s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL); 1085 1077 if (!s3c_pl330_dmac) { 1086 1078 ret = -ENOMEM; 1079 + goto probe_err5; 1080 + } 1081 + 1082 + /* Get operation clock and enable it */ 1083 + s3c_pl330_dmac->clk = clk_get(&pdev->dev, "pdma"); 1084 + if (IS_ERR(s3c_pl330_dmac->clk)) { 1085 + dev_err(&pdev->dev, "Cannot get operation clock.\n"); 1086 + ret = -EINVAL; 1087 1087 goto probe_err6; 1088 1088 } 1089 + clk_enable(s3c_pl330_dmac->clk); 1090 + 1091 + ret = pl330_add(pl330_info); 1092 + if (ret) 1093 + goto probe_err7; 1089 1094 1090 1095 /* Hook the info */ 1091 1096 s3c_pl330_dmac->pi = pl330_info; ··· 1107 1094 1108 1095 if (!s3c_pl330_dmac->kmcache) { 1109 1096 ret = -ENOMEM; 1110 - goto probe_err7; 1097 + goto probe_err8; 1111 1098 } 1112 1099 1113 1100 /* Get the list of peripherals */ ··· 1133 1120 1134 1121 return 0; 1135 1122 1136 - probe_err7: 1137 - kfree(s3c_pl330_dmac); 1138 - probe_err6: 1123 + probe_err8: 1139 1124 pl330_del(pl330_info); 1125 + probe_err7: 1126 + clk_disable(s3c_pl330_dmac->clk); 1127 + clk_put(s3c_pl330_dmac->clk); 1128 + probe_err6: 1129 + kfree(s3c_pl330_dmac); 1140 1130 probe_err5: 1141 1131 free_irq(irq, pl330_info); 1142 1132 probe_err4: ··· 1203 1187 kfree(ch); 1204 1188 } 1205 1189 } 1190 + 1191 + /* Disable operation clock */ 1192 + clk_disable(dmac->clk); 1193 + clk_put(dmac->clk); 1206 1194 1207 1195 /* Remove the DMAC */ 1208 1196 list_del(&dmac->node);
+17 -12
arch/sh/boards/mach-ap325rxa/setup.c
··· 176 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 194 static struct sh_mobile_lcdc_info lcdc_info = { 180 195 .clock_source = LCDC_CLK_EXTERNAL, 181 196 .ch[0] = { ··· 198 183 .bpp = 16, 199 184 .interface_type = RGB18, 200 185 .clock_divider = 1, 201 - .lcd_cfg = { 202 - .name = "LB070WV1", 203 - .xres = 800, 204 - .yres = 480, 205 - .left_margin = 32, 206 - .right_margin = 160, 207 - .hsync_len = 8, 208 - .upper_margin = 63, 209 - .lower_margin = 80, 210 - .vsync_len = 1, 211 - .sync = 0, /* hsync and vsync are active low */ 212 - }, 186 + .lcd_cfg = ap325rxa_lcdc_modes, 187 + .num_cfg = ARRAY_SIZE(ap325rxa_lcdc_modes), 213 188 .lcd_size_cfg = { /* 7.0 inch */ 214 189 .width = 152, 215 190 .height = 91,
+36 -24
arch/sh/boards/mach-ecovec24/setup.c
··· 231 231 }; 232 232 233 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 264 static struct sh_mobile_lcdc_info lcdc_info = { 235 265 .ch[0] = { 236 266 .interface_type = RGB18, 237 267 .chan = LCDC_CHAN_MAINLCD, 238 268 .bpp = 16, 239 - .lcd_cfg = { 240 - .sync = 0, /* hsync and vsync are active low */ 241 - }, 242 269 .lcd_size_cfg = { /* 7.0 inch */ 243 270 .width = 152, 244 271 .height = 91, ··· 1106 1079 if (gpio_get_value(GPIO_PTE6)) { 1107 1080 /* DVI */ 1108 1081 lcdc_info.clock_source = LCDC_CLK_EXTERNAL; 1109 - lcdc_info.ch[0].clock_divider = 1, 1110 - lcdc_info.ch[0].lcd_cfg.name = "DVI"; 1111 - lcdc_info.ch[0].lcd_cfg.xres = 1280; 1112 - lcdc_info.ch[0].lcd_cfg.yres = 720; 1113 - lcdc_info.ch[0].lcd_cfg.left_margin = 220; 1114 - lcdc_info.ch[0].lcd_cfg.right_margin = 110; 1115 - lcdc_info.ch[0].lcd_cfg.hsync_len = 40; 1116 - lcdc_info.ch[0].lcd_cfg.upper_margin = 20; 1117 - lcdc_info.ch[0].lcd_cfg.lower_margin = 5; 1118 - lcdc_info.ch[0].lcd_cfg.vsync_len = 5; 1082 + lcdc_info.ch[0].clock_divider = 1; 1083 + lcdc_info.ch[0].lcd_cfg = ecovec_dvi_modes; 1084 + lcdc_info.ch[0].num_cfg = ARRAY_SIZE(ecovec_dvi_modes); 1119 1085 1120 1086 gpio_set_value(GPIO_PTA2, 1); 1121 1087 gpio_set_value(GPIO_PTU1, 1); 1122 1088 } else { 1123 1089 /* Panel */ 1124 - 1125 1090 lcdc_info.clock_source = LCDC_CLK_PERIPHERAL; 1126 - lcdc_info.ch[0].clock_divider = 2, 1127 - lcdc_info.ch[0].lcd_cfg.name = "Panel"; 1128 - lcdc_info.ch[0].lcd_cfg.xres = 800; 1129 - lcdc_info.ch[0].lcd_cfg.yres = 480; 1130 - lcdc_info.ch[0].lcd_cfg.left_margin = 220; 1131 - lcdc_info.ch[0].lcd_cfg.right_margin = 110; 1132 - lcdc_info.ch[0].lcd_cfg.hsync_len = 70; 1133 - lcdc_info.ch[0].lcd_cfg.upper_margin = 20; 1134 - lcdc_info.ch[0].lcd_cfg.lower_margin = 5; 1135 - lcdc_info.ch[0].lcd_cfg.vsync_len = 5; 1091 + lcdc_info.ch[0].clock_divider = 2; 1092 + lcdc_info.ch[0].lcd_cfg = ecovec_lcd_modes; 1093 + lcdc_info.ch[0].num_cfg = ARRAY_SIZE(ecovec_lcd_modes); 1136 1094 1137 1095 gpio_set_value(GPIO_PTR1, 1); 1138 1096
+17 -12
arch/sh/boards/mach-kfr2r09/setup.c
··· 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 144 static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = { 130 145 .clock_source = LCDC_CLK_BUS, 131 146 .ch[0] = { ··· 149 134 .interface_type = SYS18, 150 135 .clock_divider = 6, 151 136 .flags = LCDC_FLAGS_DWPOL, 152 - .lcd_cfg = { 153 - .name = "TX07D34VM0AAA", 154 - .xres = 240, 155 - .yres = 400, 156 - .left_margin = 0, 157 - .right_margin = 16, 158 - .hsync_len = 8, 159 - .upper_margin = 0, 160 - .lower_margin = 1, 161 - .vsync_len = 1, 162 - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 163 - }, 137 + .lcd_cfg = kfr2r09_lcdc_modes, 138 + .num_cfg = ARRAY_SIZE(kfr2r09_lcdc_modes), 164 139 .lcd_size_cfg = { 165 140 .width = 35, 166 141 .height = 58,
+31 -27
arch/sh/boards/mach-migor/setup.c
··· 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 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 243 .clock_source = LCDC_CLK_BUS, 219 244 .ch[0] = { 220 245 .chan = LCDC_CHAN_MAINLCD, 221 246 .bpp = 16, 222 247 .interface_type = RGB16, 223 248 .clock_divider = 2, 224 - .lcd_cfg = { 225 - .name = "LB070WV1", 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 - }, 249 + .lcd_cfg = migor_lcd_modes, 250 + .num_cfg = ARRAY_SIZE(migor_lcd_modes), 236 251 .lcd_size_cfg = { /* 7.0 inch */ 237 252 .width = 152, 238 253 .height = 91, 239 254 }, 240 255 } 241 - #endif 242 - #ifdef CONFIG_SH_MIGOR_QVGA 256 + #elif defined(CONFIG_SH_MIGOR_QVGA) 243 257 .clock_source = LCDC_CLK_PERIPHERAL, 244 258 .ch[0] = { 245 259 .chan = LCDC_CHAN_MAINLCD, 246 260 .bpp = 16, 247 261 .interface_type = SYS16A, 248 262 .clock_divider = 10, 249 - .lcd_cfg = { 250 - .name = "PH240320T", 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 - }, 263 + .lcd_cfg = migor_lcd_modes, 264 + .num_cfg = ARRAY_SIZE(migor_lcd_modes), 261 265 .lcd_size_cfg = { /* 2.4 inch */ 262 266 .width = 49, 263 267 .height = 37,
+34 -20
arch/sh/boards/mach-se/7724/setup.c
··· 144 144 }; 145 145 146 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 177 static struct sh_mobile_lcdc_info lcdc_info = { 148 178 .clock_source = LCDC_CLK_EXTERNAL, 149 179 .ch[0] = { 150 180 .chan = LCDC_CHAN_MAINLCD, 151 181 .bpp = 16, 152 182 .clock_divider = 1, 153 - .lcd_cfg = { 154 - .name = "LB070WV1", 155 - .sync = 0, /* hsync and vsync are active low */ 156 - }, 157 183 .lcd_size_cfg = { /* 7.0 inch */ 158 184 .width = 152, 159 185 .height = 91, ··· 935 909 936 910 if (sw & SW41_B) { 937 911 /* 720p */ 938 - lcdc_info.ch[0].lcd_cfg.xres = 1280; 939 - lcdc_info.ch[0].lcd_cfg.yres = 720; 940 - lcdc_info.ch[0].lcd_cfg.left_margin = 220; 941 - lcdc_info.ch[0].lcd_cfg.right_margin = 110; 942 - lcdc_info.ch[0].lcd_cfg.hsync_len = 40; 943 - lcdc_info.ch[0].lcd_cfg.upper_margin = 20; 944 - lcdc_info.ch[0].lcd_cfg.lower_margin = 5; 945 - lcdc_info.ch[0].lcd_cfg.vsync_len = 5; 912 + lcdc_info.ch[0].lcd_cfg = lcdc_720p_modes; 913 + lcdc_info.ch[0].num_cfg = ARRAY_SIZE(lcdc_720p_modes); 946 914 } else { 947 915 /* VGA */ 948 - lcdc_info.ch[0].lcd_cfg.xres = 640; 949 - lcdc_info.ch[0].lcd_cfg.yres = 480; 950 - lcdc_info.ch[0].lcd_cfg.left_margin = 105; 951 - lcdc_info.ch[0].lcd_cfg.right_margin = 50; 952 - lcdc_info.ch[0].lcd_cfg.hsync_len = 96; 953 - lcdc_info.ch[0].lcd_cfg.upper_margin = 33; 954 - lcdc_info.ch[0].lcd_cfg.lower_margin = 10; 955 - lcdc_info.ch[0].lcd_cfg.vsync_len = 2; 916 + lcdc_info.ch[0].lcd_cfg = lcdc_vga_modes; 917 + lcdc_info.ch[0].num_cfg = ARRAY_SIZE(lcdc_vga_modes); 956 918 } 957 919 958 920 if (sw & SW41_A) {
+18 -14
drivers/video/sh_mipi_dsi.c
··· 123 123 u32 linelength; 124 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 131 switch (pdata->data_format) { 128 132 case MIPI_RGB888: 129 133 pctype = 0; 130 134 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; 131 135 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; 132 - linelength = ch->lcd_cfg.xres * 3; 136 + linelength = ch->lcd_cfg[0].xres * 3; 133 137 yuv = false; 134 138 break; 135 139 case MIPI_RGB565: 136 140 pctype = 1; 137 141 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; 138 142 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; 139 - linelength = ch->lcd_cfg.xres * 2; 143 + linelength = ch->lcd_cfg[0].xres * 2; 140 144 yuv = false; 141 145 break; 142 146 case MIPI_RGB666_LP: 143 147 pctype = 2; 144 148 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; 145 149 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; 146 - linelength = ch->lcd_cfg.xres * 3; 150 + linelength = ch->lcd_cfg[0].xres * 3; 147 151 yuv = false; 148 152 break; 149 153 case MIPI_RGB666: 150 154 pctype = 3; 151 155 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; 152 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 158 yuv = false; 155 159 break; 156 160 case MIPI_BGR888: 157 161 pctype = 8; 158 162 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; 159 163 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; 160 - linelength = ch->lcd_cfg.xres * 3; 164 + linelength = ch->lcd_cfg[0].xres * 3; 161 165 yuv = false; 162 166 break; 163 167 case MIPI_BGR565: 164 168 pctype = 9; 165 169 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; 166 170 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; 167 - linelength = ch->lcd_cfg.xres * 2; 171 + linelength = ch->lcd_cfg[0].xres * 2; 168 172 yuv = false; 169 173 break; 170 174 case MIPI_BGR666_LP: 171 175 pctype = 0xa; 172 176 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; 173 177 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; 174 - linelength = ch->lcd_cfg.xres * 3; 178 + linelength = ch->lcd_cfg[0].xres * 3; 175 179 yuv = false; 176 180 break; 177 181 case MIPI_BGR666: 178 182 pctype = 0xb; 179 183 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; 180 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 186 yuv = false; 183 187 break; 184 188 case MIPI_YUYV: 185 189 pctype = 4; 186 190 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; 187 191 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; 188 - linelength = ch->lcd_cfg.xres * 2; 192 + linelength = ch->lcd_cfg[0].xres * 2; 189 193 yuv = true; 190 194 break; 191 195 case MIPI_UYVY: 192 196 pctype = 5; 193 197 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; 194 198 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; 195 - linelength = ch->lcd_cfg.xres * 2; 199 + linelength = ch->lcd_cfg[0].xres * 2; 196 200 yuv = true; 197 201 break; 198 202 case MIPI_YUV420_L: 199 203 pctype = 6; 200 204 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; 201 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 207 yuv = true; 204 208 break; 205 209 case MIPI_YUV420: ··· 211 207 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; 212 208 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; 213 209 /* Length of U/V line */ 214 - linelength = (ch->lcd_cfg.xres + 1) / 2; 210 + linelength = (ch->lcd_cfg[0].xres + 1) / 2; 215 211 yuv = true; 216 212 break; 217 213 default: ··· 285 281 iowrite32(0x00e00000, base + 0x8024); /* VMCTR2 */ 286 282 /* 287 283 * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see 288 - * sh_mobile_lcdc_info.ch[0].lcd_cfg.xres), HSALEN = 1 - default 284 + * sh_mobile_lcdc_info.ch[0].lcd_cfg[0].xres), HSALEN = 1 - default 289 285 * (unused, since VMCTR2[HSABM] = 0) 290 286 */ 291 287 iowrite32(1 | (linelength << 16), base + 0x8028); /* VMLEN1 */
+404 -223
drivers/video/sh_mobile_hdmi.c
··· 28 28 #include <video/sh_mobile_hdmi.h> 29 29 #include <video/sh_mobile_lcdc.h> 30 30 31 + #include "sh_mobile_lcdcfb.h" 32 + 31 33 #define HDMI_SYSTEM_CTRL 0x00 /* System control */ 32 34 #define HDMI_L_R_DATA_SWAP_CTRL_RPKT 0x01 /* L/R data swap control, 33 35 bits 19..16 of 20-bit N for Audio Clock Regeneration packet */ ··· 208 206 209 207 struct sh_hdmi { 210 208 void __iomem *base; 211 - enum hotplug_state hp_state; 209 + enum hotplug_state hp_state; /* hot-plug status */ 210 + bool preprogrammed_mode; /* use a pre-programmed VIC or the external mode */ 212 211 struct clk *hdmi_clk; 213 212 struct device *dev; 214 213 struct fb_info *info; 214 + struct mutex mutex; /* Protect the info pointer */ 215 215 struct delayed_work edid_work; 216 216 struct fb_var_screeninfo var; 217 + struct fb_monspecs monspec; 217 218 }; 218 219 219 220 static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg) ··· 282 277 */ 283 278 284 279 /* External video parameter settings */ 285 - static void hdmi_external_video_param(struct sh_hdmi *hdmi) 280 + static void sh_hdmi_external_video_param(struct sh_hdmi *hdmi) 286 281 { 287 282 struct fb_var_screeninfo *var = &hdmi->var; 288 283 u16 htotal, hblank, hdelay, vtotal, vblank, vdelay, voffset; ··· 314 309 if (var->sync & FB_SYNC_VERT_HIGH_ACT) 315 310 sync |= 8; 316 311 317 - pr_debug("H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n", 318 - htotal, hblank, hdelay, var->hsync_len, 319 - vtotal, vblank, vdelay, var->vsync_len, sync); 312 + 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, 314 + vtotal, vblank, vdelay, var->vsync_len, sync); 320 315 321 316 hdmi_write(hdmi, sync | (voffset << 4), HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS); 322 317 ··· 341 336 342 337 hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION); 343 338 344 - /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for manual mode */ 339 + /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for external mode */ 340 + if (!hdmi->preprogrammed_mode) 341 + hdmi_write(hdmi, sync | 1 | (voffset << 4), 342 + HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS); 345 343 } 346 344 347 345 /** ··· 462 454 } 463 455 464 456 /** 465 - * sh_hdmi_phy_config() 457 + * sh_hdmi_phy_config() - configure the HDMI PHY for the used video mode 466 458 */ 467 459 static void sh_hdmi_phy_config(struct sh_hdmi *hdmi) 468 460 { 469 - /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */ 470 - hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1); 471 - hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2); 472 - hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3); 473 - /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */ 474 - hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5); 475 - hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6); 476 - hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7); 477 - hdmi_write(hdmi, 0x0E, HDMI_SLIPHDMIT_PARAM_SETTINGS_8); 478 - hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9); 479 - hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10); 461 + if (hdmi->var.yres > 480) { 462 + /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */ 463 + /* 464 + * [1:0] Speed_A 465 + * [3:2] Speed_B 466 + * [4] PLLA_Bypass 467 + * [6] DRV_TEST_EN 468 + * [7] DRV_TEST_IN 469 + */ 470 + hdmi_write(hdmi, 0x0f, HDMI_SLIPHDMIT_PARAM_SETTINGS_1); 471 + /* PLLB_CONFIG[17], PLLA_CONFIG[17] - not in PHY datasheet */ 472 + hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2); 473 + /* 474 + * [2:0] BGR_I_OFFSET 475 + * [6:4] BGR_V_OFFSET 476 + */ 477 + hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3); 478 + /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */ 479 + hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5); 480 + /* 481 + * PLLA_CONFIG[15:8]: regulator voltage[0], CP current, 482 + * LPF capacitance, LPF resistance[1] 483 + */ 484 + hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6); 485 + /* PLLB_CONFIG[7:0]: LPF resistance[0], VCO offset, VCO gain */ 486 + hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7); 487 + /* 488 + * PLLB_CONFIG[15:8]: regulator voltage[0], CP current, 489 + * LPF capacitance, LPF resistance[1] 490 + */ 491 + hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_8); 492 + /* DRV_CONFIG, PE_CONFIG */ 493 + hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9); 494 + /* 495 + * [2:0] AMON_SEL (4 == LPF voltage) 496 + * [4] PLLA_CONFIG[16] 497 + * [5] PLLB_CONFIG[16] 498 + */ 499 + hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10); 500 + } else { 501 + /* for 480p8bit 27MHz */ 502 + hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1); 503 + hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2); 504 + hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3); 505 + hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5); 506 + hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6); 507 + hdmi_write(hdmi, 0x48, HDMI_SLIPHDMIT_PARAM_SETTINGS_7); 508 + hdmi_write(hdmi, 0x0F, HDMI_SLIPHDMIT_PARAM_SETTINGS_8); 509 + hdmi_write(hdmi, 0x20, HDMI_SLIPHDMIT_PARAM_SETTINGS_9); 510 + hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10); 511 + } 480 512 } 481 513 482 514 /** ··· 524 476 */ 525 477 static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi) 526 478 { 479 + u8 vic; 480 + 527 481 /* AVI InfoFrame */ 528 482 hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_INDEX); 529 483 ··· 550 500 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB1); 551 501 552 502 /* 553 - * C = No Data 554 - * M = 16:9 Picture Aspect Ratio 555 - * R = Same as picture aspect ratio 503 + * [7:6] C = Colorimetry: no data 504 + * [5:4] M = 2: 16:9, 1: 4:3 Picture Aspect Ratio 505 + * [3:0] R = 8: Active Frame Aspect Ratio: same as picture aspect ratio 556 506 */ 557 507 hdmi_write(hdmi, 0x28, HDMI_CTRL_PKT_BUF_ACCESS_PB2); 558 508 ··· 566 516 567 517 /* 568 518 * VIC = 1280 x 720p: ignored if external config is used 569 - * Send 2 for 720 x 480p, 16 for 1080p 519 + * Send 2 for 720 x 480p, 16 for 1080p, ignored in external mode 570 520 */ 571 - hdmi_write(hdmi, 4, HDMI_CTRL_PKT_BUF_ACCESS_PB4); 521 + if (hdmi->var.yres == 1080 && hdmi->var.xres == 1920) 522 + vic = 16; 523 + else if (hdmi->var.yres == 480 && hdmi->var.xres == 720) 524 + vic = 2; 525 + else 526 + vic = 4; 527 + hdmi_write(hdmi, vic, HDMI_CTRL_PKT_BUF_ACCESS_PB4); 572 528 573 529 /* PR = No Repetition */ 574 530 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB5); ··· 648 592 } 649 593 650 594 /** 651 - * sh_hdmi_gamut_metadata_setup() - Gamut Metadata Packet of CONTROL PACKET 652 - */ 653 - static void sh_hdmi_gamut_metadata_setup(struct sh_hdmi *hdmi) 654 - { 655 - int i; 656 - 657 - /* Gamut Metadata Packet */ 658 - hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_INDEX); 659 - 660 - /* Packet Type = 0x0A */ 661 - hdmi_write(hdmi, 0x0A, HDMI_CTRL_PKT_BUF_ACCESS_HB0); 662 - /* Gamut Packet is not used, so default value */ 663 - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1); 664 - /* Gamut Packet is not used, so default value */ 665 - hdmi_write(hdmi, 0x10, HDMI_CTRL_PKT_BUF_ACCESS_HB2); 666 - 667 - /* GBD bytes 0 through 27 */ 668 - for (i = 0; i <= 27; i++) 669 - /* HDMI_CTRL_PKT_BUF_ACCESS_PB0_63H - PB27_7EH */ 670 - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i); 671 - } 672 - 673 - /** 674 - * sh_hdmi_acp_setup() - Audio Content Protection Packet (ACP) 675 - */ 676 - static void sh_hdmi_acp_setup(struct sh_hdmi *hdmi) 677 - { 678 - int i; 679 - 680 - /* Audio Content Protection Packet (ACP) */ 681 - hdmi_write(hdmi, 0x01, HDMI_CTRL_PKT_BUF_INDEX); 682 - 683 - /* Packet Type = 0x04 */ 684 - hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_ACCESS_HB0); 685 - /* ACP_Type */ 686 - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1); 687 - /* Reserved (0) */ 688 - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2); 689 - 690 - /* GBD bytes 0 through 27 */ 691 - for (i = 0; i <= 27; i++) 692 - /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */ 693 - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i); 694 - } 695 - 696 - /** 697 - * sh_hdmi_isrc1_setup() - ISRC1 Packet 698 - */ 699 - static void sh_hdmi_isrc1_setup(struct sh_hdmi *hdmi) 700 - { 701 - int i; 702 - 703 - /* ISRC1 Packet */ 704 - hdmi_write(hdmi, 0x02, HDMI_CTRL_PKT_BUF_INDEX); 705 - 706 - /* Packet Type = 0x05 */ 707 - hdmi_write(hdmi, 0x05, HDMI_CTRL_PKT_BUF_ACCESS_HB0); 708 - /* ISRC_Cont, ISRC_Valid, Reserved (0), ISRC_Status */ 709 - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1); 710 - /* Reserved (0) */ 711 - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2); 712 - 713 - /* PB0 UPC_EAN_ISRC_0-15 */ 714 - /* Bytes PB16-PB27 shall be set to a value of 0. */ 715 - for (i = 0; i <= 27; i++) 716 - /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */ 717 - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i); 718 - } 719 - 720 - /** 721 - * sh_hdmi_isrc2_setup() - ISRC2 Packet 722 - */ 723 - static void sh_hdmi_isrc2_setup(struct sh_hdmi *hdmi) 724 - { 725 - int i; 726 - 727 - /* ISRC2 Packet */ 728 - hdmi_write(hdmi, 0x03, HDMI_CTRL_PKT_BUF_INDEX); 729 - 730 - /* HB0 Packet Type = 0x06 */ 731 - hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_ACCESS_HB0); 732 - /* Reserved (0) */ 733 - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1); 734 - /* Reserved (0) */ 735 - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2); 736 - 737 - /* PB0 UPC_EAN_ISRC_16-31 */ 738 - /* Bytes PB16-PB27 shall be set to a value of 0. */ 739 - for (i = 0; i <= 27; i++) 740 - /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */ 741 - hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i); 742 - } 743 - 744 - /** 745 595 * sh_hdmi_configure() - Initialise HDMI for output 746 596 */ 747 597 static void sh_hdmi_configure(struct sh_hdmi *hdmi) ··· 667 705 /* Audio InfoFrame */ 668 706 sh_hdmi_audio_infoframe_setup(hdmi); 669 707 670 - /* Gamut Metadata packet */ 671 - sh_hdmi_gamut_metadata_setup(hdmi); 672 - 673 - /* Audio Content Protection (ACP) Packet */ 674 - sh_hdmi_acp_setup(hdmi); 675 - 676 - /* ISRC1 Packet */ 677 - sh_hdmi_isrc1_setup(hdmi); 678 - 679 - /* ISRC2 Packet */ 680 - sh_hdmi_isrc2_setup(hdmi); 681 - 682 708 /* 683 709 * Control packet auto send with VSYNC control: auto send 684 710 * General control, Gamut metadata, ISRC, and ACP packets ··· 684 734 hdmi_write(hdmi, 0x40, HDMI_SYSTEM_CTRL); 685 735 } 686 736 687 - static void sh_hdmi_read_edid(struct sh_hdmi *hdmi) 737 + static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi, 738 + const struct fb_videomode *mode) 688 739 { 689 - struct fb_var_screeninfo *var = &hdmi->var; 690 - struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; 691 - struct fb_videomode *lcd_cfg = &pdata->lcd_chan->lcd_cfg; 692 - unsigned long height = var->height, width = var->width; 693 - int i; 740 + long target = PICOS2KHZ(mode->pixclock) * 1000, 741 + rate = clk_round_rate(hdmi->hdmi_clk, target); 742 + unsigned long rate_error = rate > 0 ? abs(rate - target) : ULONG_MAX; 743 + 744 + dev_dbg(hdmi->dev, "%u-%u-%u-%u x %u-%u-%u-%u\n", 745 + mode->left_margin, mode->xres, 746 + mode->right_margin, mode->hsync_len, 747 + mode->upper_margin, mode->yres, 748 + mode->lower_margin, mode->vsync_len); 749 + 750 + dev_dbg(hdmi->dev, "\t@%lu(+/-%lu)Hz, e=%lu / 1000, r=%uHz\n", target, 751 + rate_error, rate_error ? 10000 / (10 * target / rate_error) : 0, 752 + mode->refresh); 753 + 754 + return rate_error; 755 + } 756 + 757 + static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) 758 + { 759 + struct fb_var_screeninfo tmpvar; 760 + struct fb_var_screeninfo *var = &tmpvar; 761 + const struct fb_videomode *mode, *found = NULL; 762 + struct fb_info *info = hdmi->info; 763 + struct fb_modelist *modelist = NULL; 764 + unsigned int f_width = 0, f_height = 0, f_refresh = 0; 765 + unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */ 766 + bool exact_match = false; 694 767 u8 edid[128]; 768 + char *forced; 769 + int i; 695 770 696 771 /* Read EDID */ 697 - pr_debug("Read back EDID code:"); 772 + dev_dbg(hdmi->dev, "Read back EDID code:"); 698 773 for (i = 0; i < 128; i++) { 699 774 edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW); 700 775 #ifdef DEBUG ··· 734 759 #ifdef DEBUG 735 760 printk(KERN_CONT "\n"); 736 761 #endif 737 - fb_parse_edid(edid, var); 738 - pr_debug("%u-%u-%u-%u x %u-%u-%u-%u @ %lu kHz monitor detected\n", 739 - var->left_margin, var->xres, var->right_margin, var->hsync_len, 740 - var->upper_margin, var->yres, var->lower_margin, var->vsync_len, 741 - PICOS2KHZ(var->pixclock)); 742 762 743 - /* FIXME: Use user-provided configuration instead of EDID */ 744 - var->width = width; 745 - var->xres = lcd_cfg->xres; 746 - var->xres_virtual = lcd_cfg->xres; 747 - var->left_margin = lcd_cfg->left_margin; 748 - var->right_margin = lcd_cfg->right_margin; 749 - var->hsync_len = lcd_cfg->hsync_len; 750 - var->height = height; 751 - var->yres = lcd_cfg->yres; 752 - var->yres_virtual = lcd_cfg->yres * 2; 753 - var->upper_margin = lcd_cfg->upper_margin; 754 - var->lower_margin = lcd_cfg->lower_margin; 755 - var->vsync_len = lcd_cfg->vsync_len; 756 - var->sync = lcd_cfg->sync; 757 - var->pixclock = lcd_cfg->pixclock; 763 + fb_edid_to_monspecs(edid, &hdmi->monspec); 758 764 759 - hdmi_external_video_param(hdmi); 765 + fb_get_options("sh_mobile_lcdc", &forced); 766 + if (forced && *forced) { 767 + /* Only primitive parsing so far */ 768 + i = sscanf(forced, "%ux%u@%u", 769 + &f_width, &f_height, &f_refresh); 770 + if (i < 2) { 771 + f_width = 0; 772 + f_height = 0; 773 + } 774 + dev_dbg(hdmi->dev, "Forced mode %ux%u@%uHz\n", 775 + f_width, f_height, f_refresh); 776 + } 777 + 778 + /* Walk monitor modes to find the best or the exact match */ 779 + for (i = 0, mode = hdmi->monspec.modedb; 780 + f_width && f_height && i < hdmi->monspec.modedb_len && !exact_match; 781 + i++, mode++) { 782 + unsigned long rate_error = sh_hdmi_rate_error(hdmi, mode); 783 + 784 + /* No interest in unmatching modes */ 785 + if (f_width != mode->xres || f_height != mode->yres) 786 + continue; 787 + if (f_refresh == mode->refresh || (!f_refresh && !rate_error)) 788 + /* 789 + * Exact match if either the refresh rate matches or it 790 + * hasn't been specified and we've found a mode, for 791 + * which we can configure the clock precisely 792 + */ 793 + exact_match = true; 794 + else if (found && found_rate_error <= rate_error) 795 + /* 796 + * We otherwise search for the closest matching clock 797 + * rate - either if no refresh rate has been specified 798 + * or we cannot find an exactly matching one 799 + */ 800 + continue; 801 + 802 + /* Check if supported: sufficient fb memory, supported clock-rate */ 803 + fb_videomode_to_var(var, mode); 804 + 805 + if (info && info->fbops->fb_check_var && 806 + info->fbops->fb_check_var(var, info)) { 807 + exact_match = false; 808 + continue; 809 + } 810 + 811 + found = mode; 812 + found_rate_error = rate_error; 813 + } 814 + 815 + /* 816 + * TODO 1: if no ->info is present, postpone running the config until 817 + * after ->info first gets registered. 818 + * TODO 2: consider registering the HDMI platform device from the LCDC 819 + * driver, and passing ->info with HDMI platform data. 820 + */ 821 + if (info && !found) { 822 + modelist = hdmi->info->modelist.next && 823 + !list_empty(&hdmi->info->modelist) ? 824 + list_entry(hdmi->info->modelist.next, 825 + struct fb_modelist, list) : 826 + NULL; 827 + 828 + if (modelist) { 829 + found = &modelist->mode; 830 + found_rate_error = sh_hdmi_rate_error(hdmi, found); 831 + } 832 + } 833 + 834 + /* No cookie today */ 835 + if (!found) 836 + return -ENXIO; 837 + 838 + dev_info(hdmi->dev, "Using %s mode %ux%u@%uHz (%luHz), clock error %luHz\n", 839 + modelist ? "default" : "EDID", found->xres, found->yres, 840 + found->refresh, PICOS2KHZ(found->pixclock) * 1000, found_rate_error); 841 + 842 + if ((found->xres == 720 && found->yres == 480) || 843 + (found->xres == 1280 && found->yres == 720) || 844 + (found->xres == 1920 && found->yres == 1080)) 845 + hdmi->preprogrammed_mode = true; 846 + else 847 + hdmi->preprogrammed_mode = false; 848 + 849 + fb_videomode_to_var(&hdmi->var, found); 850 + sh_hdmi_external_video_param(hdmi); 851 + 852 + return 0; 760 853 } 761 854 762 855 static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id) ··· 852 809 hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_2); 853 810 854 811 if (printk_ratelimit()) 855 - pr_debug("IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n", 856 - irq, status1, mask1, status2, mask2); 812 + dev_dbg(hdmi->dev, "IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n", 813 + irq, status1, mask1, status2, mask2); 857 814 858 815 if (!((status1 & mask1) | (status2 & mask2))) { 859 816 return IRQ_NONE; ··· 864 821 udelay(500); 865 822 866 823 msens = hdmi_read(hdmi, HDMI_HOT_PLUG_MSENS_STATUS); 867 - pr_debug("MSENS 0x%x\n", msens); 824 + dev_dbg(hdmi->dev, "MSENS 0x%x\n", msens); 868 825 /* Check, if hot plug & MSENS pin status are both high */ 869 826 if ((msens & 0xC0) == 0xC0) { 870 827 /* Display plug in */ ··· 900 857 return IRQ_HANDLED; 901 858 } 902 859 903 - static void hdmi_display_on(void *arg, struct fb_info *info) 860 + /* locking: called with info->lock held, or before register_framebuffer() */ 861 + static void sh_hdmi_display_on(void *arg, struct fb_info *info) 904 862 { 863 + /* 864 + * info is guaranteed to be valid, when we are called, because our 865 + * FB_EVENT_FB_UNBIND notify is also called with info->lock held 866 + */ 905 867 struct sh_hdmi *hdmi = arg; 906 868 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; 869 + struct sh_mobile_lcdc_chan *ch = info->par; 907 870 908 - if (info->var.xres != 1280 || info->var.yres != 720) { 909 - dev_warn(info->device, "Unsupported framebuffer geometry %ux%u\n", 910 - info->var.xres, info->var.yres); 911 - return; 912 - } 871 + dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__, 872 + pdata->lcd_dev, info->state); 913 873 914 - pr_debug("%s(%p): state %x\n", __func__, pdata->lcd_dev, info->state); 915 - /* 916 - * FIXME: not a good place to store fb_info. And we cannot nullify it 917 - * even on monitor disconnect. What should the lifecycle be? 918 - */ 874 + /* No need to lock */ 919 875 hdmi->info = info; 876 + 877 + /* 878 + * hp_state can be set to 879 + * HDMI_HOTPLUG_DISCONNECTED: on monitor unplug 880 + * HDMI_HOTPLUG_CONNECTED: on monitor plug-in 881 + * HDMI_HOTPLUG_EDID_DONE: on EDID read completion 882 + */ 920 883 switch (hdmi->hp_state) { 921 884 case HDMI_HOTPLUG_EDID_DONE: 922 885 /* PS mode d->e. All functions are active */ 923 886 hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL); 924 - pr_debug("HDMI running\n"); 887 + dev_dbg(hdmi->dev, "HDMI running\n"); 925 888 break; 926 889 case HDMI_HOTPLUG_DISCONNECTED: 927 890 info->state = FBINFO_STATE_SUSPENDED; 928 891 default: 929 - hdmi->var = info->var; 892 + hdmi->var = ch->display_var; 930 893 } 931 894 } 932 895 933 - static void hdmi_display_off(void *arg) 896 + /* locking: called with info->lock held */ 897 + static void sh_hdmi_display_off(void *arg) 934 898 { 935 899 struct sh_hdmi *hdmi = arg; 936 900 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; 937 901 938 - pr_debug("%s(%p)\n", __func__, pdata->lcd_dev); 902 + dev_dbg(hdmi->dev, "%s(%p)\n", __func__, pdata->lcd_dev); 939 903 /* PS mode e->a */ 940 904 hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL); 941 905 } 942 906 907 + static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi) 908 + { 909 + struct fb_info *info = hdmi->info; 910 + struct sh_mobile_lcdc_chan *ch = info->par; 911 + struct fb_var_screeninfo *new_var = &hdmi->var, *old_var = &ch->display_var; 912 + struct fb_videomode mode1, mode2; 913 + 914 + fb_var_to_videomode(&mode1, old_var); 915 + fb_var_to_videomode(&mode2, new_var); 916 + 917 + dev_dbg(info->dev, "Old %ux%u, new %ux%u\n", 918 + mode1.xres, mode1.yres, mode2.xres, mode2.yres); 919 + 920 + if (fb_mode_is_equal(&mode1, &mode2)) 921 + return false; 922 + 923 + dev_dbg(info->dev, "Switching %u -> %u lines\n", 924 + mode1.yres, mode2.yres); 925 + *old_var = *new_var; 926 + 927 + return true; 928 + } 929 + 930 + /** 931 + * sh_hdmi_clk_configure() - set HDMI clock frequency and enable the clock 932 + * @hdmi: driver context 933 + * @pixclock: pixel clock period in picoseconds 934 + * return: configured positive rate if successful 935 + * 0 if couldn't set the rate, but managed to enable the clock 936 + * negative error, if couldn't enable the clock 937 + */ 938 + static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long pixclock) 939 + { 940 + long rate; 941 + int ret; 942 + 943 + rate = PICOS2KHZ(pixclock) * 1000; 944 + rate = clk_round_rate(hdmi->hdmi_clk, rate); 945 + if (rate > 0) { 946 + ret = clk_set_rate(hdmi->hdmi_clk, rate); 947 + if (ret < 0) { 948 + dev_warn(hdmi->dev, "Cannot set rate %ld: %d\n", rate, ret); 949 + rate = 0; 950 + } else { 951 + dev_dbg(hdmi->dev, "HDMI set frequency %lu\n", rate); 952 + } 953 + } else { 954 + rate = 0; 955 + dev_warn(hdmi->dev, "Cannot get suitable rate: %ld\n", rate); 956 + } 957 + 958 + ret = clk_enable(hdmi->hdmi_clk); 959 + if (ret < 0) { 960 + dev_err(hdmi->dev, "Cannot enable clock: %d\n", ret); 961 + return ret; 962 + } 963 + 964 + return rate; 965 + } 966 + 943 967 /* Hotplug interrupt occurred, read EDID */ 944 - static void edid_work_fn(struct work_struct *work) 968 + static void sh_hdmi_edid_work_fn(struct work_struct *work) 945 969 { 946 970 struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work); 947 971 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; 972 + struct sh_mobile_lcdc_chan *ch; 973 + int ret; 948 974 949 - pr_debug("%s(%p): begin, hotplug status %d\n", __func__, 950 - pdata->lcd_dev, hdmi->hp_state); 975 + dev_dbg(hdmi->dev, "%s(%p): begin, hotplug status %d\n", __func__, 976 + pdata->lcd_dev, hdmi->hp_state); 951 977 952 978 if (!pdata->lcd_dev) 953 979 return; 954 980 981 + mutex_lock(&hdmi->mutex); 982 + 955 983 if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) { 956 - pm_runtime_get_sync(hdmi->dev); 957 984 /* A device has been plugged in */ 958 - sh_hdmi_read_edid(hdmi); 985 + pm_runtime_get_sync(hdmi->dev); 986 + 987 + ret = sh_hdmi_read_edid(hdmi); 988 + if (ret < 0) 989 + goto out; 990 + 991 + /* Reconfigure the clock */ 992 + clk_disable(hdmi->hdmi_clk); 993 + ret = sh_hdmi_clk_configure(hdmi, hdmi->var.pixclock); 994 + if (ret < 0) 995 + goto out; 996 + 959 997 msleep(10); 960 998 sh_hdmi_configure(hdmi); 961 999 /* Switched to another (d) power-save mode */ 962 1000 msleep(10); 963 1001 964 1002 if (!hdmi->info) 965 - return; 1003 + goto out; 1004 + 1005 + ch = hdmi->info->par; 966 1006 967 1007 acquire_console_sem(); 968 1008 969 1009 /* HDMI plug in */ 970 - hdmi->info->var = hdmi->var; 971 - if (hdmi->info->state != FBINFO_STATE_RUNNING) 1010 + if (!sh_hdmi_must_reconfigure(hdmi) && 1011 + hdmi->info->state == FBINFO_STATE_RUNNING) { 1012 + /* 1013 + * First activation with the default monitor - just turn 1014 + * on, if we run a resume here, the logo disappears 1015 + */ 1016 + if (lock_fb_info(hdmi->info)) { 1017 + sh_hdmi_display_on(hdmi, hdmi->info); 1018 + unlock_fb_info(hdmi->info); 1019 + } 1020 + } else { 1021 + /* New monitor or have to wake up */ 972 1022 fb_set_suspend(hdmi->info, 0); 973 - else 974 - hdmi_display_on(hdmi, hdmi->info); 1023 + } 975 1024 976 1025 release_console_sem(); 977 1026 } else { 1027 + ret = 0; 978 1028 if (!hdmi->info) 979 - return; 1029 + goto out; 980 1030 981 1031 acquire_console_sem(); 982 1032 ··· 1078 942 1079 943 release_console_sem(); 1080 944 pm_runtime_put(hdmi->dev); 945 + fb_destroy_modedb(hdmi->monspec.modedb); 1081 946 } 1082 947 1083 - pr_debug("%s(%p): end\n", __func__, pdata->lcd_dev); 948 + out: 949 + if (ret < 0) 950 + hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED; 951 + mutex_unlock(&hdmi->mutex); 952 + 953 + dev_dbg(hdmi->dev, "%s(%p): end\n", __func__, pdata->lcd_dev); 954 + } 955 + 956 + static int sh_hdmi_notify(struct notifier_block *nb, 957 + unsigned long action, void *data); 958 + 959 + static struct notifier_block sh_hdmi_notifier = { 960 + .notifier_call = sh_hdmi_notify, 961 + }; 962 + 963 + static int sh_hdmi_notify(struct notifier_block *nb, 964 + unsigned long action, void *data) 965 + { 966 + struct fb_event *event = data; 967 + struct fb_info *info = event->info; 968 + struct sh_mobile_lcdc_chan *ch = info->par; 969 + struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg; 970 + struct sh_hdmi *hdmi = board_cfg->board_data; 971 + 972 + if (nb != &sh_hdmi_notifier || !hdmi || hdmi->info != info) 973 + return NOTIFY_DONE; 974 + 975 + switch(action) { 976 + case FB_EVENT_FB_REGISTERED: 977 + /* Unneeded, activation taken care by sh_hdmi_display_on() */ 978 + break; 979 + case FB_EVENT_FB_UNREGISTERED: 980 + /* 981 + * We are called from unregister_framebuffer() with the 982 + * info->lock held. This is bad for us, because we can race with 983 + * the scheduled work, which has to call fb_set_suspend(), which 984 + * takes info->lock internally, so, sh_hdmi_edid_work_fn() 985 + * cannot take and hold info->lock for the whole function 986 + * duration. Using an additional lock creates a classical AB-BA 987 + * lock up. Therefore, we have to release the info->lock 988 + * temporarily, synchronise with the work queue and re-acquire 989 + * the info->lock. 990 + */ 991 + unlock_fb_info(hdmi->info); 992 + mutex_lock(&hdmi->mutex); 993 + hdmi->info = NULL; 994 + mutex_unlock(&hdmi->mutex); 995 + lock_fb_info(hdmi->info); 996 + return NOTIFY_OK; 997 + } 998 + return NOTIFY_DONE; 1084 999 } 1085 1000 1086 1001 static int __init sh_hdmi_probe(struct platform_device *pdev) 1087 1002 { 1088 1003 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data; 1089 1004 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1005 + struct sh_mobile_lcdc_board_cfg *board_cfg; 1090 1006 int irq = platform_get_irq(pdev, 0), ret; 1091 1007 struct sh_hdmi *hdmi; 1092 1008 long rate; ··· 1152 964 return -ENOMEM; 1153 965 } 1154 966 1155 - ret = snd_soc_register_codec(&pdev->dev, 1156 - &soc_codec_dev_sh_hdmi, &sh_hdmi_dai, 1); 1157 - if (ret < 0) 1158 - goto esndreg; 967 + mutex_init(&hdmi->mutex); 1159 968 1160 969 hdmi->dev = &pdev->dev; 1161 970 ··· 1163 978 goto egetclk; 1164 979 } 1165 980 1166 - rate = PICOS2KHZ(pdata->lcd_chan->lcd_cfg.pixclock) * 1000; 1167 - 1168 - rate = clk_round_rate(hdmi->hdmi_clk, rate); 981 + /* Some arbitrary relaxed pixclock just to get things started */ 982 + rate = sh_hdmi_clk_configure(hdmi, 37037); 1169 983 if (rate < 0) { 1170 984 ret = rate; 1171 - dev_err(&pdev->dev, "Cannot get suitable rate: %ld\n", rate); 1172 985 goto erate; 1173 986 } 1174 987 1175 - ret = clk_set_rate(hdmi->hdmi_clk, rate); 1176 - if (ret < 0) { 1177 - dev_err(&pdev->dev, "Cannot set rate %ld: %d\n", rate, ret); 1178 - goto erate; 1179 - } 1180 - 1181 - pr_debug("HDMI set frequency %lu\n", rate); 1182 - 1183 - ret = clk_enable(hdmi->hdmi_clk); 1184 - if (ret < 0) { 1185 - dev_err(&pdev->dev, "Cannot enable clock: %d\n", ret); 1186 - goto eclkenable; 1187 - } 1188 - 1189 - dev_info(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate); 988 + dev_dbg(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate); 1190 989 1191 990 if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) { 1192 991 dev_err(&pdev->dev, "HDMI register region already claimed\n"); ··· 1187 1018 1188 1019 platform_set_drvdata(pdev, hdmi); 1189 1020 1190 - #if 1 1191 1021 /* Product and revision IDs are 0 in sh-mobile version */ 1192 1022 dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n", 1193 1023 hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID)); 1194 - #endif 1195 1024 1196 1025 /* Set up LCDC callbacks */ 1197 - pdata->lcd_chan->board_cfg.board_data = hdmi; 1198 - pdata->lcd_chan->board_cfg.display_on = hdmi_display_on; 1199 - pdata->lcd_chan->board_cfg.display_off = hdmi_display_off; 1026 + board_cfg = &pdata->lcd_chan->board_cfg; 1027 + board_cfg->owner = THIS_MODULE; 1028 + board_cfg->board_data = hdmi; 1029 + board_cfg->display_on = sh_hdmi_display_on; 1030 + board_cfg->display_off = sh_hdmi_display_off; 1200 1031 1201 - INIT_DELAYED_WORK(&hdmi->edid_work, edid_work_fn); 1032 + INIT_DELAYED_WORK(&hdmi->edid_work, sh_hdmi_edid_work_fn); 1202 1033 1203 1034 pm_runtime_enable(&pdev->dev); 1204 1035 pm_runtime_resume(&pdev->dev); ··· 1210 1041 goto ereqirq; 1211 1042 } 1212 1043 1044 + ret = snd_soc_register_codec(&pdev->dev, 1045 + &soc_codec_dev_sh_hdmi, &sh_hdmi_dai, 1); 1046 + if (ret < 0) { 1047 + dev_err(&pdev->dev, "codec registration failed\n"); 1048 + goto ecodec; 1049 + } 1050 + 1213 1051 return 0; 1214 1052 1053 + ecodec: 1054 + free_irq(irq, hdmi); 1215 1055 ereqirq: 1216 1056 pm_runtime_disable(&pdev->dev); 1217 1057 iounmap(hdmi->base); ··· 1228 1050 release_mem_region(res->start, resource_size(res)); 1229 1051 ereqreg: 1230 1052 clk_disable(hdmi->hdmi_clk); 1231 - eclkenable: 1232 1053 erate: 1233 1054 clk_put(hdmi->hdmi_clk); 1234 1055 egetclk: 1235 - snd_soc_unregister_codec(&pdev->dev); 1236 - esndreg: 1056 + mutex_destroy(&hdmi->mutex); 1237 1057 kfree(hdmi); 1238 1058 1239 1059 return ret; ··· 1242 1066 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data; 1243 1067 struct sh_hdmi *hdmi = platform_get_drvdata(pdev); 1244 1068 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1069 + struct sh_mobile_lcdc_board_cfg *board_cfg = &pdata->lcd_chan->board_cfg; 1245 1070 int irq = platform_get_irq(pdev, 0); 1246 1071 1247 1072 snd_soc_unregister_codec(&pdev->dev); 1248 1073 1249 - pdata->lcd_chan->board_cfg.display_on = NULL; 1250 - pdata->lcd_chan->board_cfg.display_off = NULL; 1251 - pdata->lcd_chan->board_cfg.board_data = NULL; 1074 + board_cfg->display_on = NULL; 1075 + board_cfg->display_off = NULL; 1076 + board_cfg->board_data = NULL; 1077 + board_cfg->owner = NULL; 1252 1078 1079 + /* No new work will be scheduled, wait for running ISR */ 1253 1080 free_irq(irq, hdmi); 1254 - pm_runtime_disable(&pdev->dev); 1081 + /* Wait for already scheduled work */ 1255 1082 cancel_delayed_work_sync(&hdmi->edid_work); 1083 + pm_runtime_disable(&pdev->dev); 1256 1084 clk_disable(hdmi->hdmi_clk); 1257 1085 clk_put(hdmi->hdmi_clk); 1258 1086 iounmap(hdmi->base); 1259 1087 release_mem_region(res->start, resource_size(res)); 1088 + mutex_destroy(&hdmi->mutex); 1260 1089 kfree(hdmi); 1261 1090 1262 1091 return 0;
+227 -121
drivers/video/sh_mobile_lcdcfb.c
··· 12 12 #include <linux/init.h> 13 13 #include <linux/delay.h> 14 14 #include <linux/mm.h> 15 - #include <linux/fb.h> 16 15 #include <linux/clk.h> 17 16 #include <linux/pm_runtime.h> 18 17 #include <linux/platform_device.h> ··· 20 21 #include <linux/vmalloc.h> 21 22 #include <linux/ioctl.h> 22 23 #include <linux/slab.h> 24 + #include <linux/console.h> 23 25 #include <video/sh_mobile_lcdc.h> 24 26 #include <asm/atomic.h> 25 27 26 - #define PALETTE_NR 16 28 + #include "sh_mobile_lcdcfb.h" 29 + 27 30 #define SIDE_B_OFFSET 0x1000 28 31 #define MIRROR_OFFSET 0x2000 29 32 ··· 54 53 }; 55 54 #define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs) 56 55 57 - /* per-channel registers */ 58 - enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, 59 - LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR, 60 - LDHAJR, 61 - NR_CH_REGS }; 56 + #define DEFAULT_XRES 1280 57 + #define DEFAULT_YRES 1024 62 58 63 59 static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { 64 60 [LDDCKPAT1R] = 0x400, ··· 110 112 #define LDRCNTR_MRC 0x00000001 111 113 #define LDSR_MRS 0x00000100 112 114 113 - struct sh_mobile_lcdc_priv; 114 - struct sh_mobile_lcdc_chan { 115 - struct sh_mobile_lcdc_priv *lcdc; 116 - unsigned long *reg_offs; 117 - unsigned long ldmt1r_value; 118 - unsigned long enabled; /* ME and SE in LDCNT2R */ 119 - struct sh_mobile_lcdc_chan_cfg cfg; 120 - u32 pseudo_palette[PALETTE_NR]; 121 - unsigned long saved_ch_regs[NR_CH_REGS]; 122 - struct fb_info *info; 123 - dma_addr_t dma_handle; 124 - struct fb_deferred_io defio; 125 - struct scatterlist *sglist; 126 - unsigned long frame_end; 127 - unsigned long pan_offset; 128 - wait_queue_head_t frame_end_wait; 129 - struct completion vsync_completion; 115 + static const struct fb_videomode default_720p = { 116 + .name = "HDMI 720p", 117 + .xres = 1280, 118 + .yres = 720, 119 + 120 + .left_margin = 200, 121 + .right_margin = 88, 122 + .hsync_len = 48, 123 + 124 + .upper_margin = 20, 125 + .lower_margin = 5, 126 + .vsync_len = 5, 127 + 128 + .pixclock = 13468, 129 + .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, 130 130 }; 131 131 132 132 struct sh_mobile_lcdc_priv { ··· 405 409 406 410 static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) 407 411 { 408 - struct fb_var_screeninfo *var = &ch->info->var; 409 - unsigned long h_total, hsync_pos; 412 + struct fb_var_screeninfo *var = &ch->info->var, *display_var = &ch->display_var; 413 + unsigned long h_total, hsync_pos, display_h_total; 410 414 u32 tmp; 411 415 412 416 tmp = ch->ldmt1r_value; ··· 424 428 lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r); 425 429 426 430 /* horizontal configuration */ 427 - h_total = var->xres + var->hsync_len + 428 - var->left_margin + var->right_margin; 431 + h_total = display_var->xres + display_var->hsync_len + 432 + display_var->left_margin + display_var->right_margin; 429 433 tmp = h_total / 8; /* HTCN */ 430 - tmp |= (var->xres / 8) << 16; /* HDCN */ 434 + tmp |= (min(display_var->xres, var->xres) / 8) << 16; /* HDCN */ 431 435 lcdc_write_chan(ch, LDHCNR, tmp); 432 436 433 - hsync_pos = var->xres + var->right_margin; 437 + hsync_pos = display_var->xres + display_var->right_margin; 434 438 tmp = hsync_pos / 8; /* HSYNP */ 435 - tmp |= (var->hsync_len / 8) << 16; /* HSYNW */ 439 + tmp |= (display_var->hsync_len / 8) << 16; /* HSYNW */ 436 440 lcdc_write_chan(ch, LDHSYNR, tmp); 437 441 438 442 /* vertical configuration */ 439 - tmp = var->yres + var->vsync_len + 440 - var->upper_margin + var->lower_margin; /* VTLN */ 441 - tmp |= var->yres << 16; /* VDLN */ 443 + tmp = display_var->yres + display_var->vsync_len + 444 + display_var->upper_margin + display_var->lower_margin; /* VTLN */ 445 + tmp |= min(display_var->yres, var->yres) << 16; /* VDLN */ 442 446 lcdc_write_chan(ch, LDVLNR, tmp); 443 447 444 - tmp = var->yres + var->lower_margin; /* VSYNP */ 445 - tmp |= var->vsync_len << 16; /* VSYNW */ 448 + tmp = display_var->yres + display_var->lower_margin; /* VSYNP */ 449 + tmp |= display_var->vsync_len << 16; /* VSYNW */ 446 450 lcdc_write_chan(ch, LDVSYNR, tmp); 447 451 448 452 /* Adjust horizontal synchronisation for HDMI */ 449 - tmp = ((var->xres & 7) << 24) | 450 - ((h_total & 7) << 16) | 451 - ((var->hsync_len & 7) << 8) | 453 + display_h_total = display_var->xres + display_var->hsync_len + 454 + display_var->left_margin + display_var->right_margin; 455 + tmp = ((display_var->xres & 7) << 24) | 456 + ((display_h_total & 7) << 16) | 457 + ((display_var->hsync_len & 7) << 8) | 452 458 hsync_pos; 453 459 lcdc_write_chan(ch, LDHAJR, tmp); 454 460 } ··· 458 460 static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) 459 461 { 460 462 struct sh_mobile_lcdc_chan *ch; 461 - struct fb_videomode *lcd_cfg; 462 463 struct sh_mobile_lcdc_board_cfg *board_cfg; 463 464 unsigned long tmp; 464 465 int k, m; ··· 500 503 m = 1 << 6; 501 504 tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0); 502 505 503 - lcdc_write_chan(ch, LDDCKPAT1R, 0x00000000); 506 + /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider denominator */ 507 + lcdc_write_chan(ch, LDDCKPAT1R, 0); 504 508 lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1); 505 509 } 506 510 ··· 516 518 517 519 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 518 520 ch = &priv->ch[k]; 519 - lcd_cfg = &ch->cfg.lcd_cfg; 520 521 521 522 if (!ch->enabled) 522 523 continue; ··· 544 547 545 548 /* set bpp format in PKF[4:0] */ 546 549 tmp = lcdc_read_chan(ch, LDDFR); 547 - tmp &= ~(0x0001001f); 550 + tmp &= ~0x0001001f; 548 551 tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0; 549 552 lcdc_write_chan(ch, LDDFR, tmp); 550 553 ··· 588 591 continue; 589 592 590 593 board_cfg = &ch->cfg.board_cfg; 591 - if (board_cfg->display_on) 594 + if (try_module_get(board_cfg->owner) && board_cfg->display_on) { 592 595 board_cfg->display_on(board_cfg->board_data, ch->info); 596 + module_put(board_cfg->owner); 597 + } 593 598 } 594 599 595 600 return 0; ··· 613 614 * flush frame, and wait for frame end interrupt 614 615 * clean up deferred io and enable clock 615 616 */ 616 - if (ch->info->fbdefio) { 617 + if (ch->info && ch->info->fbdefio) { 617 618 ch->frame_end = 0; 618 619 schedule_delayed_work(&ch->info->deferred_work, 0); 619 620 wait_event(ch->frame_end_wait, ch->frame_end); ··· 623 624 } 624 625 625 626 board_cfg = &ch->cfg.board_cfg; 626 - if (board_cfg->display_off) 627 + if (try_module_get(board_cfg->owner) && board_cfg->display_off) { 627 628 board_cfg->display_off(board_cfg->board_data); 629 + module_put(board_cfg->owner); 630 + } 628 631 } 629 632 630 633 /* stop the lcdc */ ··· 705 704 return PTR_ERR(priv->dot_clk); 706 705 } 707 706 } 708 - atomic_set(&priv->hw_usecnt, -1); 709 707 710 708 /* Runtime PM support involves two step for this driver: 711 709 * 1) Enable Runtime PM ··· 837 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 937 static struct fb_ops sh_mobile_lcdc_ops = { 842 938 .owner = THIS_MODULE, ··· 944 848 .fb_imageblit = sh_mobile_lcdc_imageblit, 945 849 .fb_pan_display = sh_mobile_fb_pan_display, 946 850 .fb_ioctl = sh_mobile_ioctl, 851 + .fb_open = sh_mobile_open, 852 + .fb_release = sh_mobile_release, 853 + .fb_check_var = sh_mobile_check_var, 947 854 }; 948 855 949 856 static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) ··· 1057 958 .runtime_resume = sh_mobile_lcdc_runtime_resume, 1058 959 }; 1059 960 961 + /* locking: called with info->lock held */ 1060 962 static int sh_mobile_lcdc_notify(struct notifier_block *nb, 1061 963 unsigned long action, void *data) 1062 964 { ··· 1065 965 struct fb_info *info = event->info; 1066 966 struct sh_mobile_lcdc_chan *ch = info->par; 1067 967 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg; 1068 - struct fb_var_screeninfo *var; 968 + int ret; 1069 969 1070 970 if (&ch->lcdc->notifier != nb) 1071 - return 0; 971 + return NOTIFY_DONE; 1072 972 1073 973 dev_dbg(info->dev, "%s(): action = %lu, data = %p\n", 1074 974 __func__, action, event->data); 1075 975 1076 976 switch(action) { 1077 977 case FB_EVENT_SUSPEND: 1078 - if (board_cfg->display_off) 978 + if (try_module_get(board_cfg->owner) && board_cfg->display_off) { 1079 979 board_cfg->display_off(board_cfg->board_data); 980 + module_put(board_cfg->owner); 981 + } 1080 982 pm_runtime_put(info->device); 983 + sh_mobile_lcdc_stop(ch->lcdc); 1081 984 break; 1082 985 case FB_EVENT_RESUME: 1083 - var = &info->var; 986 + mutex_lock(&ch->open_lock); 987 + sh_mobile_fb_reconfig(info); 988 + mutex_unlock(&ch->open_lock); 1084 989 1085 990 /* HDMI must be enabled before LCDC configuration */ 1086 - if (board_cfg->display_on) 1087 - board_cfg->display_on(board_cfg->board_data, ch->info); 1088 - 1089 - /* Check if the new display is not in our modelist */ 1090 - if (ch->info->modelist.next && 1091 - !fb_match_mode(var, &ch->info->modelist)) { 1092 - struct fb_videomode mode; 1093 - int ret; 1094 - 1095 - /* Can we handle this display? */ 1096 - if (var->xres > ch->cfg.lcd_cfg.xres || 1097 - var->yres > ch->cfg.lcd_cfg.yres) 1098 - return -ENOMEM; 1099 - 1100 - /* Add to the modelist */ 1101 - fb_var_to_videomode(&mode, var); 1102 - ret = fb_add_videomode(&mode, &ch->info->modelist); 1103 - if (ret < 0) 1104 - return ret; 991 + if (try_module_get(board_cfg->owner) && board_cfg->display_on) { 992 + board_cfg->display_on(board_cfg->board_data, info); 993 + module_put(board_cfg->owner); 1105 994 } 1106 995 1107 - pm_runtime_get_sync(info->device); 1108 - 1109 - sh_mobile_lcdc_geometry(ch); 1110 - 1111 - break; 996 + ret = sh_mobile_lcdc_start(ch->lcdc); 997 + if (!ret) 998 + pm_runtime_get_sync(info->device); 1112 999 } 1113 1000 1114 - return 0; 1001 + return NOTIFY_OK; 1115 1002 } 1116 1003 1117 1004 static int sh_mobile_lcdc_remove(struct platform_device *pdev); ··· 1107 1020 { 1108 1021 struct fb_info *info; 1109 1022 struct sh_mobile_lcdc_priv *priv; 1110 - struct sh_mobile_lcdc_info *pdata; 1111 - struct sh_mobile_lcdc_chan_cfg *cfg; 1023 + struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data; 1112 1024 struct resource *res; 1113 1025 int error; 1114 1026 void *buf; 1115 1027 int i, j; 1116 1028 1117 - if (!pdev->dev.platform_data) { 1029 + if (!pdata) { 1118 1030 dev_err(&pdev->dev, "no platform data defined\n"); 1119 1031 return -EINVAL; 1120 1032 } ··· 1141 1055 } 1142 1056 1143 1057 priv->irq = i; 1144 - pdata = pdev->dev.platform_data; 1058 + atomic_set(&priv->hw_usecnt, -1); 1145 1059 1146 1060 j = 0; 1147 1061 for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) { 1148 - priv->ch[j].lcdc = priv; 1149 - memcpy(&priv->ch[j].cfg, &pdata->ch[i], sizeof(pdata->ch[i])); 1062 + struct sh_mobile_lcdc_chan *ch = priv->ch + j; 1150 1063 1151 - error = sh_mobile_lcdc_check_interface(&priv->ch[j]); 1064 + ch->lcdc = priv; 1065 + memcpy(&ch->cfg, &pdata->ch[i], sizeof(pdata->ch[i])); 1066 + 1067 + error = sh_mobile_lcdc_check_interface(ch); 1152 1068 if (error) { 1153 1069 dev_err(&pdev->dev, "unsupported interface type\n"); 1154 1070 goto err1; 1155 1071 } 1156 - init_waitqueue_head(&priv->ch[j].frame_end_wait); 1157 - init_completion(&priv->ch[j].vsync_completion); 1158 - priv->ch[j].pan_offset = 0; 1072 + init_waitqueue_head(&ch->frame_end_wait); 1073 + init_completion(&ch->vsync_completion); 1074 + ch->pan_offset = 0; 1159 1075 1160 1076 switch (pdata->ch[i].chan) { 1161 1077 case LCDC_CHAN_MAINLCD: 1162 - priv->ch[j].enabled = 1 << 1; 1163 - priv->ch[j].reg_offs = lcdc_offs_mainlcd; 1078 + ch->enabled = 1 << 1; 1079 + ch->reg_offs = lcdc_offs_mainlcd; 1164 1080 j++; 1165 1081 break; 1166 1082 case LCDC_CHAN_SUBLCD: 1167 - priv->ch[j].enabled = 1 << 2; 1168 - priv->ch[j].reg_offs = lcdc_offs_sublcd; 1083 + ch->enabled = 1 << 2; 1084 + ch->reg_offs = lcdc_offs_sublcd; 1169 1085 j++; 1170 1086 break; 1171 1087 } ··· 1191 1103 1192 1104 for (i = 0; i < j; i++) { 1193 1105 struct fb_var_screeninfo *var; 1194 - struct fb_videomode *lcd_cfg; 1195 - cfg = &priv->ch[i].cfg; 1106 + const struct fb_videomode *lcd_cfg, *max_cfg = NULL; 1107 + struct sh_mobile_lcdc_chan *ch = priv->ch + i; 1108 + struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg; 1109 + const struct fb_videomode *mode = cfg->lcd_cfg; 1110 + unsigned long max_size = 0; 1111 + int k; 1196 1112 1197 - priv->ch[i].info = framebuffer_alloc(0, &pdev->dev); 1198 - if (!priv->ch[i].info) { 1113 + ch->info = framebuffer_alloc(0, &pdev->dev); 1114 + if (!ch->info) { 1199 1115 dev_err(&pdev->dev, "unable to allocate fb_info\n"); 1200 1116 error = -ENOMEM; 1201 1117 break; 1202 1118 } 1203 1119 1204 - info = priv->ch[i].info; 1120 + info = ch->info; 1205 1121 var = &info->var; 1206 - lcd_cfg = &cfg->lcd_cfg; 1207 1122 info->fbops = &sh_mobile_lcdc_ops; 1208 - var->xres = var->xres_virtual = lcd_cfg->xres; 1209 - var->yres = lcd_cfg->yres; 1123 + info->par = ch; 1124 + 1125 + mutex_init(&ch->open_lock); 1126 + 1127 + for (k = 0, lcd_cfg = mode; 1128 + k < cfg->num_cfg && lcd_cfg; 1129 + k++, lcd_cfg++) { 1130 + unsigned long size = lcd_cfg->yres * lcd_cfg->xres; 1131 + 1132 + if (size > max_size) { 1133 + max_cfg = lcd_cfg; 1134 + max_size = size; 1135 + } 1136 + } 1137 + 1138 + if (!mode) 1139 + max_size = DEFAULT_XRES * DEFAULT_YRES; 1140 + else if (max_cfg) 1141 + dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n", 1142 + max_cfg->xres, max_cfg->yres); 1143 + 1144 + info->fix = sh_mobile_lcdc_fix; 1145 + info->fix.smem_len = max_size * (cfg->bpp / 8) * 2; 1146 + 1147 + if (!mode) 1148 + mode = &default_720p; 1149 + 1150 + fb_videomode_to_var(var, mode); 1210 1151 /* Default Y virtual resolution is 2x panel size */ 1211 1152 var->yres_virtual = var->yres * 2; 1212 - var->width = cfg->lcd_size_cfg.width; 1213 - var->height = cfg->lcd_size_cfg.height; 1214 1153 var->activate = FB_ACTIVATE_NOW; 1215 - var->left_margin = lcd_cfg->left_margin; 1216 - var->right_margin = lcd_cfg->right_margin; 1217 - var->upper_margin = lcd_cfg->upper_margin; 1218 - var->lower_margin = lcd_cfg->lower_margin; 1219 - var->hsync_len = lcd_cfg->hsync_len; 1220 - var->vsync_len = lcd_cfg->vsync_len; 1221 - var->sync = lcd_cfg->sync; 1222 - var->pixclock = lcd_cfg->pixclock; 1223 1154 1224 1155 error = sh_mobile_lcdc_set_bpp(var, cfg->bpp); 1225 1156 if (error) 1226 1157 break; 1227 1158 1228 - info->fix = sh_mobile_lcdc_fix; 1229 - info->fix.line_length = lcd_cfg->xres * (cfg->bpp / 8); 1230 - info->fix.smem_len = info->fix.line_length * 1231 - var->yres_virtual; 1232 - 1233 1159 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len, 1234 - &priv->ch[i].dma_handle, GFP_KERNEL); 1160 + &ch->dma_handle, GFP_KERNEL); 1235 1161 if (!buf) { 1236 1162 dev_err(&pdev->dev, "unable to allocate buffer\n"); 1237 1163 error = -ENOMEM; 1238 1164 break; 1239 1165 } 1240 1166 1241 - info->pseudo_palette = &priv->ch[i].pseudo_palette; 1167 + info->pseudo_palette = &ch->pseudo_palette; 1242 1168 info->flags = FBINFO_FLAG_DEFAULT; 1243 1169 1244 1170 error = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0); 1245 1171 if (error < 0) { 1246 1172 dev_err(&pdev->dev, "unable to allocate cmap\n"); 1247 1173 dma_free_coherent(&pdev->dev, info->fix.smem_len, 1248 - buf, priv->ch[i].dma_handle); 1174 + buf, ch->dma_handle); 1249 1175 break; 1250 1176 } 1251 1177 1252 - memset(buf, 0, info->fix.smem_len); 1253 - info->fix.smem_start = priv->ch[i].dma_handle; 1178 + info->fix.smem_start = ch->dma_handle; 1179 + info->fix.line_length = var->xres * (cfg->bpp / 8); 1254 1180 info->screen_base = buf; 1255 1181 info->device = &pdev->dev; 1256 - info->par = &priv->ch[i]; 1182 + ch->display_var = *var; 1257 1183 } 1258 1184 1259 1185 if (error) ··· 1281 1179 1282 1180 for (i = 0; i < j; i++) { 1283 1181 struct sh_mobile_lcdc_chan *ch = priv->ch + i; 1182 + const struct fb_videomode *mode = ch->cfg.lcd_cfg; 1183 + 1184 + if (!mode) 1185 + mode = &default_720p; 1284 1186 1285 1187 info = ch->info; 1286 1188 ··· 1297 1191 } 1298 1192 } 1299 1193 1194 + fb_videomode_to_modelist(mode, ch->cfg.num_cfg, &info->modelist); 1300 1195 error = register_framebuffer(info); 1301 1196 if (error < 0) 1302 1197 goto err1; ··· 1307 1200 pdev->name, 1308 1201 (ch->cfg.chan == LCDC_CHAN_MAINLCD) ? 1309 1202 "mainlcd" : "sublcd", 1310 - (int) ch->cfg.lcd_cfg.xres, 1311 - (int) ch->cfg.lcd_cfg.yres, 1203 + info->var.xres, info->var.yres, 1312 1204 ch->cfg.bpp); 1313 1205 1314 1206 /* deferred io mode: disable clock to save power */
+41
drivers/video/sh_mobile_lcdcfb.h
··· 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
+4 -1
include/video/sh_mobile_lcdc.h
··· 49 49 unsigned long (*read_data)(void *handle); 50 50 }; 51 51 52 + struct module; 52 53 struct sh_mobile_lcdc_board_cfg { 54 + struct module *owner; 53 55 void *board_data; 54 56 int (*setup_sys)(void *board_data, void *sys_ops_handle, 55 57 struct sh_mobile_lcdc_sys_bus_ops *sys_ops); ··· 72 70 int interface_type; /* selects RGBn or SYSn I/F, see above */ 73 71 int clock_divider; 74 72 unsigned long flags; /* LCDC_FLAGS_... */ 75 - struct fb_videomode lcd_cfg; 73 + const struct fb_videomode *lcd_cfg; 74 + int num_cfg; 76 75 struct sh_mobile_lcdc_lcd_size_cfg lcd_size_cfg; 77 76 struct sh_mobile_lcdc_board_cfg board_cfg; 78 77 struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */