Commit ff877c49 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'drivers2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull "ARM: More SoC driver updates" from Olof Johansson:
 "This branch contains a handful of driver updates, mostly to the
  LPC32xx platform but also for Samsung EXYNOS and Davinci.

  It had a few context conflicts against patches already merged through
  fixes-non-critical.  We should have resolved this early during the
  development cycle by pulling them in as a dependency, instead I did it
  after the fact this time."

* tag 'drivers2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc:
  gpio/samsung: use ioremap() for EXYNOS4 GPIOlib
  gpio/samsung: add support GPIOlib for EXYNOS5250
  ARM: EXYNOS: add support GPIO for EXYNOS5250
  ARM: LPC32xx: Ethernet support
  ARM: LPC32xx: USB Support
  ARM: davinci: dm644x evm: add support for VPBE display
  ARM: davinci: dm644x: add support for v4l2 video display
  ARM: EXYNOS: Hook up JPEG PD to generic PD infrastructure
  ARM: EXYNOS: Hook up G2D PD to generic PD infrastructure
  arm: lpc32xx: phy3250: add rtc & touch device
  ARM: LPC32xx: clock.c: Clock registration fixes
  ARM: LPC32xx: clock.c: jiffies wrapping
  ARM: LPC32xx: clock.c: Missing header file
  ARM: LPC32XX: Remove broken non-static declaration
  ARM: LPC32xx: clock.c: Fix mutex lock issues
  ARM: LPC32xx: clock.c: warning fix
  ARM: LPC32xx: Added lpc32xx_defconfig
parents 529b73fc 1f5b7dcf
...@@ -613,6 +613,113 @@ static void __init evm_init_i2c(void) ...@@ -613,6 +613,113 @@ static void __init evm_init_i2c(void)
i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
} }
#define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
/* venc standard timings */
static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = {
{
.name = "ntsc",
.timings_type = VPBE_ENC_STD,
.timings = {V4L2_STD_525_60},
.interlaced = 1,
.xres = 720,
.yres = 480,
.aspect = {11, 10},
.fps = {30000, 1001},
.left_margin = 0x79,
.upper_margin = 0x10,
},
{
.name = "pal",
.timings_type = VPBE_ENC_STD,
.timings = {V4L2_STD_625_50},
.interlaced = 1,
.xres = 720,
.yres = 576,
.aspect = {54, 59},
.fps = {25, 1},
.left_margin = 0x7e,
.upper_margin = 0x16,
},
};
/* venc dv preset timings */
static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = {
{
.name = "480p59_94",
.timings_type = VPBE_ENC_DV_PRESET,
.timings = {V4L2_DV_480P59_94},
.interlaced = 0,
.xres = 720,
.yres = 480,
.aspect = {1, 1},
.fps = {5994, 100},
.left_margin = 0x80,
.upper_margin = 0x20,
},
{
.name = "576p50",
.timings_type = VPBE_ENC_DV_PRESET,
.timings = {V4L2_DV_576P50},
.interlaced = 0,
.xres = 720,
.yres = 576,
.aspect = {1, 1},
.fps = {50, 1},
.left_margin = 0x7e,
.upper_margin = 0x30,
},
};
/*
* The outputs available from VPBE + encoders. Keep the order same
* as that of encoders. First those from venc followed by that from
* encoders. Index in the output refers to index on a particular encoder.
* Driver uses this index to pass it to encoder when it supports more
* than one output. Userspace applications use index of the array to
* set an output.
*/
static struct vpbe_output dm644xevm_vpbe_outputs[] = {
{
.output = {
.index = 0,
.name = "Composite",
.type = V4L2_OUTPUT_TYPE_ANALOG,
.std = VENC_STD_ALL,
.capabilities = V4L2_OUT_CAP_STD,
},
.subdev_name = VPBE_VENC_SUBDEV_NAME,
.default_mode = "ntsc",
.num_modes = ARRAY_SIZE(dm644xevm_enc_std_timing),
.modes = dm644xevm_enc_std_timing,
},
{
.output = {
.index = 1,
.name = "Component",
.type = V4L2_OUTPUT_TYPE_ANALOG,
.capabilities = V4L2_OUT_CAP_PRESETS,
},
.subdev_name = VPBE_VENC_SUBDEV_NAME,
.default_mode = "480p59_94",
.num_modes = ARRAY_SIZE(dm644xevm_enc_preset_timing),
.modes = dm644xevm_enc_preset_timing,
},
};
static struct vpbe_config dm644xevm_display_cfg = {
.module_name = "dm644x-vpbe-display",
.i2c_adapter_id = 1,
.osd = {
.module_name = VPBE_OSD_SUBDEV_NAME,
},
.venc = {
.module_name = VPBE_VENC_SUBDEV_NAME,
},
.num_outputs = ARRAY_SIZE(dm644xevm_vpbe_outputs),
.outputs = dm644xevm_vpbe_outputs,
};
static struct platform_device *davinci_evm_devices[] __initdata = { static struct platform_device *davinci_evm_devices[] __initdata = {
&davinci_fb_device, &davinci_fb_device,
&rtc_dev, &rtc_dev,
...@@ -696,7 +803,7 @@ static __init void davinci_evm_init(void) ...@@ -696,7 +803,7 @@ static __init void davinci_evm_init(void)
evm_init_i2c(); evm_init_i2c();
davinci_setup_mmc(0, &dm6446evm_mmc_config); davinci_setup_mmc(0, &dm6446evm_mmc_config);
dm644x_init_video(&dm644xevm_capture_cfg); dm644x_init_video(&dm644xevm_capture_cfg, &dm644xevm_display_cfg);
davinci_serial_init(&uart_config); davinci_serial_init(&uart_config);
dm644x_init_asp(&dm644x_evm_snd_data); dm644x_init_asp(&dm644x_evm_snd_data);
......
...@@ -29,9 +29,15 @@ ...@@ -29,9 +29,15 @@
#include <media/davinci/vpfe_capture.h> #include <media/davinci/vpfe_capture.h>
#include <media/davinci/vpif_types.h> #include <media/davinci/vpif_types.h>
#include <media/davinci/vpss.h>
#include <media/davinci/vpbe_types.h>
#include <media/davinci/vpbe_venc.h>
#include <media/davinci/vpbe.h>
#include <media/davinci/vpbe_osd.h>
#define DAVINCI_SYSTEM_MODULE_BASE 0x01c40000 #define DAVINCI_SYSTEM_MODULE_BASE 0x01c40000
#define SYSMOD_VIDCLKCTL 0x38 #define SYSMOD_VIDCLKCTL 0x38
#define SYSMOD_VPSS_CLKCTL 0x44
#define SYSMOD_VDD3P3VPWDN 0x48 #define SYSMOD_VDD3P3VPWDN 0x48
#define SYSMOD_VSCLKDIS 0x6c #define SYSMOD_VSCLKDIS 0x6c
#define SYSMOD_PUPDCTL1 0x7c #define SYSMOD_PUPDCTL1 0x7c
...@@ -83,7 +89,7 @@ void dm365_set_vpfe_config(struct vpfe_config *cfg); ...@@ -83,7 +89,7 @@ void dm365_set_vpfe_config(struct vpfe_config *cfg);
/* DM644x function declarations */ /* DM644x function declarations */
void __init dm644x_init(void); void __init dm644x_init(void);
void __init dm644x_init_asp(struct snd_platform_data *pdata); void __init dm644x_init_asp(struct snd_platform_data *pdata);
int __init dm644x_init_video(struct vpfe_config *); int __init dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
/* DM646x function declarations */ /* DM646x function declarations */
void __init dm646x_init(void); void __init dm646x_init(void);
......
...@@ -627,7 +627,7 @@ static struct resource dm644x_vpfe_resources[] = { ...@@ -627,7 +627,7 @@ static struct resource dm644x_vpfe_resources[] = {
}, },
}; };
static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32); static u64 dm644x_video_dma_mask = DMA_BIT_MASK(32);
static struct resource dm644x_ccdc_resource[] = { static struct resource dm644x_ccdc_resource[] = {
/* CCDC Base address */ /* CCDC Base address */
{ {
...@@ -643,7 +643,7 @@ static struct platform_device dm644x_ccdc_dev = { ...@@ -643,7 +643,7 @@ static struct platform_device dm644x_ccdc_dev = {
.num_resources = ARRAY_SIZE(dm644x_ccdc_resource), .num_resources = ARRAY_SIZE(dm644x_ccdc_resource),
.resource = dm644x_ccdc_resource, .resource = dm644x_ccdc_resource,
.dev = { .dev = {
.dma_mask = &vpfe_capture_dma_mask, .dma_mask = &dm644x_video_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32), .coherent_dma_mask = DMA_BIT_MASK(32),
}, },
}; };
...@@ -654,7 +654,134 @@ static struct platform_device dm644x_vpfe_dev = { ...@@ -654,7 +654,134 @@ static struct platform_device dm644x_vpfe_dev = {
.num_resources = ARRAY_SIZE(dm644x_vpfe_resources), .num_resources = ARRAY_SIZE(dm644x_vpfe_resources),
.resource = dm644x_vpfe_resources, .resource = dm644x_vpfe_resources,
.dev = { .dev = {
.dma_mask = &vpfe_capture_dma_mask, .dma_mask = &dm644x_video_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
#define DM644X_OSD_BASE 0x01c72600
static struct resource dm644x_osd_resources[] = {
{
.start = DM644X_OSD_BASE,
.end = DM644X_OSD_BASE + 0x1ff,
.flags = IORESOURCE_MEM,
},
};
static struct osd_platform_data dm644x_osd_data = {
.vpbe_type = VPBE_VERSION_1,
};
static struct platform_device dm644x_osd_dev = {
.name = VPBE_OSD_SUBDEV_NAME,
.id = -1,
.num_resources = ARRAY_SIZE(dm644x_osd_resources),
.resource = dm644x_osd_resources,
.dev = {
.dma_mask = &dm644x_video_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &dm644x_osd_data,
},
};
#define DM644X_VENC_BASE 0x01c72400
static struct resource dm644x_venc_resources[] = {
{
.start = DM644X_VENC_BASE,
.end = DM644X_VENC_BASE + 0x17f,
.flags = IORESOURCE_MEM,
},
};
#define DM644X_VPSS_MUXSEL_PLL2_MODE BIT(0)
#define DM644X_VPSS_MUXSEL_VPBECLK_MODE BIT(1)
#define DM644X_VPSS_VENCLKEN BIT(3)
#define DM644X_VPSS_DACCLKEN BIT(4)
static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type,
unsigned int mode)
{
int ret = 0;
u32 v = DM644X_VPSS_VENCLKEN;
switch (type) {
case VPBE_ENC_STD:
v |= DM644X_VPSS_DACCLKEN;
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
break;
case VPBE_ENC_DV_PRESET:
switch (mode) {
case V4L2_DV_480P59_94:
case V4L2_DV_576P50:
v |= DM644X_VPSS_MUXSEL_PLL2_MODE |
DM644X_VPSS_DACCLKEN;
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
break;
case V4L2_DV_720P60:
case V4L2_DV_1080I60:
case V4L2_DV_1080P30:
/*
* For HD, use external clock source since
* HD requires higher clock rate
*/
v |= DM644X_VPSS_MUXSEL_VPBECLK_MODE;
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
break;
default:
ret = -EINVAL;
break;
}
break;
default:
ret = -EINVAL;
}
return ret;
}
static struct resource dm644x_v4l2_disp_resources[] = {
{
.start = IRQ_VENCINT,
.end = IRQ_VENCINT,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dm644x_vpbe_display = {
.name = "vpbe-v4l2",
.id = -1,
.num_resources = ARRAY_SIZE(dm644x_v4l2_disp_resources),
.resource = dm644x_v4l2_disp_resources,
.dev = {
.dma_mask = &dm644x_video_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
static struct venc_platform_data dm644x_venc_pdata = {
.venc_type = VPBE_VERSION_1,
.setup_clock = dm644x_venc_setup_clock,
};
static struct platform_device dm644x_venc_dev = {
.name = VPBE_VENC_SUBDEV_NAME,
.id = -1,
.num_resources = ARRAY_SIZE(dm644x_venc_resources),
.resource = dm644x_venc_resources,
.dev = {
.dma_mask = &dm644x_video_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &dm644x_venc_pdata,
},
};
static struct platform_device dm644x_vpbe_dev = {
.name = "vpbe_controller",
.id = -1,
.dev = {
.dma_mask = &dm644x_video_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32), .coherent_dma_mask = DMA_BIT_MASK(32),
}, },
}; };
...@@ -786,17 +913,30 @@ void __init dm644x_init(void) ...@@ -786,17 +913,30 @@ void __init dm644x_init(void)
davinci_map_sysmod(); davinci_map_sysmod();
} }
int __init dm644x_init_video(struct vpfe_config *vpfe_cfg) int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
struct vpbe_config *vpbe_cfg)
{ {
dm644x_vpfe_dev.dev.platform_data = vpfe_cfg; if (vpfe_cfg || vpbe_cfg)
/* Add ccdc clock aliases */
clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL);
clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL);
platform_device_register(&dm644x_vpss_device); platform_device_register(&dm644x_vpss_device);
if (vpfe_cfg) {
dm644x_vpfe_dev.dev.platform_data = vpfe_cfg;
platform_device_register(&dm644x_ccdc_dev); platform_device_register(&dm644x_ccdc_dev);
platform_device_register(&dm644x_vpfe_dev); platform_device_register(&dm644x_vpfe_dev);
/* Add ccdc clock aliases */
clk_add_alias("master", dm644x_ccdc_dev.name,
"vpss_master", NULL);
clk_add_alias("slave", dm644x_ccdc_dev.name,
"vpss_slave", NULL);
}
if (vpbe_cfg) {
dm644x_vpbe_dev.dev.platform_data = vpbe_cfg;
platform_device_register(&dm644x_osd_dev);
platform_device_register(&dm644x_venc_dev);
platform_device_register(&dm644x_vpbe_dev);
platform_device_register(&dm644x_vpbe_display);
}
return 0; return 0;
} }
......
...@@ -159,21 +159,6 @@ static struct map_desc exynos4_iodesc[] __initdata = { ...@@ -159,21 +159,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
.pfn = __phys_to_pfn(EXYNOS4_PA_L2CC), .pfn = __phys_to_pfn(EXYNOS4_PA_L2CC),
.length = SZ_4K, .length = SZ_4K,
.type = MT_DEVICE, .type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_GPIO1,
.pfn = __phys_to_pfn(EXYNOS4_PA_GPIO1),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_GPIO2,
.pfn = __phys_to_pfn(EXYNOS4_PA_GPIO2),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_GPIO3,
.pfn = __phys_to_pfn(EXYNOS4_PA_GPIO3),
.length = SZ_256,
.type = MT_DEVICE,
}, { }, {
.virtual = (unsigned long)S5P_VA_DMC0, .virtual = (unsigned long)S5P_VA_DMC0,
.pfn = __phys_to_pfn(EXYNOS4_PA_DMC0), .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
......
/* linux/arch/arm/mach-exynos4/include/mach/gpio.h /*
* * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com * http://www.samsung.com
* *
* EXYNOS4 - GPIO lib support * EXYNOS - GPIO lib support
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -13,9 +12,13 @@ ...@@ -13,9 +12,13 @@
#ifndef __ASM_ARCH_GPIO_H #ifndef __ASM_ARCH_GPIO_H
#define __ASM_ARCH_GPIO_H __FILE__ #define __ASM_ARCH_GPIO_H __FILE__
/* Practically, GPIO banks up to GPZ are the configurable gpio banks */ /* Macro for EXYNOS GPIO numbering */
#define EXYNOS_GPIO_NEXT(__gpio) \
((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
/* EXYNOS4 GPIO bank sizes */
/* GPIO bank sizes */
#define EXYNOS4_GPIO_A0_NR (8) #define EXYNOS4_GPIO_A0_NR (8)
#define EXYNOS4_GPIO_A1_NR (6) #define EXYNOS4_GPIO_A1_NR (6)
#define EXYNOS4_GPIO_B_NR (8) #define EXYNOS4_GPIO_B_NR (8)
...@@ -54,52 +57,50 @@ ...@@ -54,52 +57,50 @@
#define EXYNOS4_GPIO_Y6_NR (8) #define EXYNOS4_GPIO_Y6_NR (8)
#define EXYNOS4_GPIO_Z_NR (7) #define EXYNOS4_GPIO_Z_NR (7)
/* GPIO bank numbers */ /* EXYNOS4 GPIO bank numbers */
#define EXYNOS4_GPIO_NEXT(__gpio) \
((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
enum s5p_gpio_number { enum exynos4_gpio_number {
EXYNOS4_GPIO_A0_START = 0, EXYNOS4_GPIO_A0_START = 0,
EXYNOS4_GPIO_A1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A0), EXYNOS4_GPIO_A1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_A0),
EXYNOS4_GPIO_B_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A1), EXYNOS4_GPIO_B_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_A1),
EXYNOS4_GPIO_C0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_B), EXYNOS4_GPIO_C0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_B),
EXYNOS4_GPIO_C1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C0), EXYNOS4_GPIO_C1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_C0),
EXYNOS4_GPIO_D0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C1), EXYNOS4_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_C1),
EXYNOS4_GPIO_D1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D0), EXYNOS4_GPIO_D1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_D0),
EXYNOS4_GPIO_E0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D1), EXYNOS4_GPIO_E0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_D1),
EXYNOS4_GPIO_E1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E0), EXYNOS4_GPIO_E1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E0),
EXYNOS4_GPIO_E2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E1), EXYNOS4_GPIO_E2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E1),
EXYNOS4_GPIO_E3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E2), EXYNOS4_GPIO_E3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E2),
EXYNOS4_GPIO_E4_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E3), EXYNOS4_GPIO_E4_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E3),
EXYNOS4_GPIO_F0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E4), EXYNOS4_GPIO_F0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E4),
EXYNOS4_GPIO_F1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F0), EXYNOS4_GPIO_F1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F0),
EXYNOS4_GPIO_F2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F1), EXYNOS4_GPIO_F2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F1),
EXYNOS4_GPIO_F3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F2), EXYNOS4_GPIO_F3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F2),
EXYNOS4_GPIO_J0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F3), EXYNOS4_GPIO_J0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F3),
EXYNOS4_GPIO_J1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J0), EXYNOS4_GPIO_J1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_J0),
EXYNOS4_GPIO_K0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J1), EXYNOS4_GPIO_K0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_J1),
EXYNOS4_GPIO_K1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K0), EXYNOS4_GPIO_K1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K0),
EXYNOS4_GPIO_K2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K1), EXYNOS4_GPIO_K2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K1),
EXYNOS4_GPIO_K3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K2), EXYNOS4_GPIO_K3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K2),
EXYNOS4_GPIO_L0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K3), EXYNOS4_GPIO_L0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K3),
EXYNOS4_GPIO_L1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L0), EXYNOS4_GPIO_L1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L0),
EXYNOS4_GPIO_L2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L1), EXYNOS4_GPIO_L2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L1),
EXYNOS4_GPIO_X0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L2), EXYNOS4_GPIO_X0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L2),
EXYNOS4_GPIO_X1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X0), EXYNOS4_GPIO_X1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X0),
EXYNOS4_GPIO_X2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X1), EXYNOS4_GPIO_X2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X1),
EXYNOS4_GPIO_X3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X2), EXYNOS4_GPIO_X3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X2),
EXYNOS4_GPIO_Y0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X3), EXYNOS4_GPIO_Y0_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X3),
EXYNOS4_GPIO_Y1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y0), EXYNOS4_GPIO_Y1_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y0),
EXYNOS4_GPIO_Y2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y1), EXYNOS4_GPIO_Y2_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y1),
EXYNOS4_GPIO_Y3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y2), EXYNOS4_GPIO_Y3_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y2),
EXYNOS4_GPIO_Y4_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y3), EXYNOS4_GPIO_Y4_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y3),
EXYNOS4_GPIO_Y5_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y4), EXYNOS4_GPIO_Y5_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y4),
EXYNOS4_GPIO_Y6_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y5), EXYNOS4_GPIO_Y6_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y5),
EXYNOS4_GPIO_Z_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y6), EXYNOS4_GPIO_Z_START = EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y6),
}; };
/* EXYNOS4 GPIO number definitions */ /* EXYNOS4 GPIO number definitions */
#define EXYNOS4_GPA0(_nr) (EXYNOS4_GPIO_A0_START + (_nr)) #define EXYNOS4_GPA0(_nr) (EXYNOS4_GPIO_A0_START + (_nr))
#define EXYNOS4_GPA1(_nr) (EXYNOS4_GPIO_A1_START + (_nr)) #define EXYNOS4_GPA1(_nr) (EXYNOS4_GPIO_A1_START + (_nr))
#define EXYNOS4_GPB(_nr) (EXYNOS4_GPIO_B_START + (_nr)) #define EXYNOS4_GPB(_nr) (EXYNOS4_GPIO_B_START + (_nr))
...@@ -139,11 +140,147 @@ enum s5p_gpio_number { ...@@ -139,11 +140,147 @@ enum s5p_gpio_number {
#define EXYNOS4_GPZ(_nr) (EXYNOS4_GPIO_Z_START + (_nr)) #define EXYNOS4_GPZ(_nr) (EXYNOS4_GPIO_Z_START + (_nr))
/* the end of the EXYNOS4 specific gpios */ /* the end of the EXYNOS4 specific gpios */
#define EXYNOS4_GPIO_END (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + 1) #define EXYNOS4_GPIO_END (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + 1)
#define S3C_GPIO_END EXYNOS4_GPIO_END
/* define the number of gpios we need to the one after the GPZ() range */ /* EXYNOS5 GPIO bank sizes */
#define ARCH_NR_GPIOS (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + \
CONFIG_SAMSUNG_GPIO_EXTRA + 1) #define EXYNOS5_GPIO_A0_NR (8)
#define EXYNOS5_GPIO_A1_NR (6)
#define EXYNOS5_GPIO_A2_NR (8)
#define EXYNOS5_GPIO_B0_NR (5)
#define EXYNOS5_GPIO_B1_NR (5)
#define EXYNOS5_GPIO_B2_NR (4)
#define EXYNOS5_GPIO_B3_NR (4)
#define EXYNOS5_GPIO_C0_NR (7)
#define EXYNOS5_GPIO_C1_NR (7)
#define EXYNOS5_GPIO_C2_NR (7)
#define EXYNOS5_GPIO_C3_NR (7)
#define EXYNOS5_GPIO_D0_NR (8)
#define EXYNOS5_GPIO_D1_NR (8)
#define EXYNOS5_GPIO_Y0_NR (6)
#define EXYNOS5_GPIO_Y1_NR (4)
#define EXYNOS5_GPIO_Y2_NR (6)
#define EXYNOS5_GPIO_Y3_NR (8)
#define EXYNOS5_GPIO_Y4_NR (8)
#define EXYNOS5_GPIO_Y5_NR (8)
#define EXYNOS5_GPIO_Y6_NR (8)
#define EXYNOS5_GPIO_X0_NR (8)
#define EXYNOS5_GPIO_X1_NR (8)
#define EXYNOS5_GPIO_X2_NR (8)
#define EXYNOS5_GPIO_X3_NR (8)
#define EXYNOS5_GPIO_E0_NR (8)
#define EXYNOS5_GPIO_E1_NR (2)
#define EXYNOS5_GPIO_F0_NR (4)
#define EXYNOS5_GPIO_F1_NR (4)
#define EXYNOS5_GPIO_G0_NR (8)
#define EXYNOS5_GPIO_G1_NR (8)
#define EXYNOS5_GPIO_G2_NR (2)
#define EXYNOS5_GPIO_H0_NR (4)
#define EXYNOS5_GPIO_H1_NR (8)
#define EXYNOS5_GPIO_V0_NR (8)
#define EXYNOS5_GPIO_V1_NR (8)
#define EXYNOS5_GPIO_V2_NR (8)
#define EXYNOS5_GPIO_V3_NR (8)
#define EXYNOS5_GPIO_V4_NR (2)
#define EXYNOS5_GPIO_Z_NR (7)
/* EXYNOS5 GPIO bank numbers */
enum exynos5_gpio_number {
EXYNOS5_GPIO_A0_START = 0,
EXYNOS5_GPIO_A1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A0),
EXYNOS5_GPIO_A2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A1),
EXYNOS5_GPIO_B0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A2),
EXYNOS5_GPIO_B1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B0),
EXYNOS5_GPIO_B2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B1),
EXYNOS5_GPIO_B3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B2),
EXYNOS5_GPIO_C0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B3),
EXYNOS5_GPIO_C1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C0),
EXYNOS5_GPIO_C2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C1),
EXYNOS5_GPIO_C3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C2),
EXYNOS5_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3),
EXYNOS5_GPIO_D1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D0),
EXYNOS5_GPIO_Y0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D1),
EXYNOS5_GPIO_Y1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y0),
EXYNOS5_GPIO_Y2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y1),
EXYNOS5_GPIO_Y3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y2),
EXYNOS5_GPIO_Y4_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y3),
EXYNOS5_GPIO_Y5_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y4),
EXYNOS5_GPIO_Y6_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y5),
EXYNOS5_GPIO_X0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y6),
EXYNOS5_GPIO_X1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X0),
EXYNOS5_GPIO_X2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X1),
EXYNOS5_GPIO_X3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X2),
EXYNOS5_GPIO_E0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X3),
EXYNOS5_GPIO_E1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_E0),
EXYNOS5_GPIO_F0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_E1),
EXYNOS5_GPIO_F1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_F0),
EXYNOS5_GPIO_G0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_F1),
EXYNOS5_GPIO_G1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G0),
EXYNOS5_GPIO_G2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G1),
EXYNOS5_GPIO_H0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G2),
EXYNOS5_GPIO_H1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_H0),
EXYNOS5_GPIO_V0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_H1),
EXYNOS5_GPIO_V1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V0),
EXYNOS5_GPIO_V2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V1),
EXYNOS5_GPIO_V3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V2),
EXYNOS5_GPIO_V4_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V3),
EXYNOS5_GPIO_Z_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V4),
};
/* EXYNOS5 GPIO number definitions */
#define EXYNOS5_GPA0(_nr) (EXYNOS5_GPIO_A0_START + (_nr))
#define EXYNOS5_GPA1(_nr) (EXYNOS5_GPIO_A1_START + (_nr))
#define EXYNOS5_GPA2(_nr) (EXYNOS5_GPIO_A2_START + (_nr))
#define EXYNOS5_GPB0(_nr) (EXYNOS5_GPIO_B0_START + (_nr))
#define EXYNOS5_GPB1(_nr) (EXYNOS5_GPIO_B1_START + (_nr))
#define EXYNOS5_GPB2(_nr) (EXYNOS5_GPIO_B2_START + (_nr))
#define EXYNOS5_GPB3(_nr) (EXYNOS5_GPIO_B3_START + (_nr))
#define EXYNOS5_GPC0(_nr) (EXYNOS5_GPIO_C0_START + (_nr))
#define EXYNOS5_GPC1(_nr) (EXYNOS5_GPIO_C1_START + (_nr))
#define EXYNOS5_GPC2(_nr) (EXYNOS5_GPIO_C2_START + (_nr))
#define EXYNOS5_GPC3(_nr) (EXYNOS5_GPIO_C3_START + (_nr))
#define EXYNOS5_GPD0(_nr) (EXYNOS5_GPIO_D0_START + (_nr))
#define EXYNOS5_GPD1(_nr) (EXYNOS5_GPIO_D1_START + (_nr))
#define EXYNOS5_GPY0(_nr) (EXYNOS5_GPIO_Y0_START + (_nr))
#define EXYNOS5_GPY1(_nr) (EXYNOS5_GPIO_Y1_START + (_nr))
#define EXYNOS5_GPY2(_nr) (EXYNOS5_GPIO_Y2_START + (_nr))
#define EXYNOS5_GPY3(_nr) (EXYNOS5_GPIO_Y3_START + (_nr))
#define EXYNOS5_GPY4(_nr) (EXYNOS5_GPIO_Y4_START + (_nr))
#define EXYNOS5_GPY5(_nr) (EXYNOS5_GPIO_Y5_START + (_nr))
#define EXYNOS5_GPY6(_nr) (EXYNOS5_GPIO_Y6_START + (_nr))
#define EXYNOS5_GPX0(_nr) (EXYNOS5_GPIO_X0_START + (_nr))
#define EXYNOS5_GPX1(_nr) (EXYNOS5_GPIO_X1_START + (_nr))
#define EXYNOS5_GPX2(_nr) (EXYNOS5_GPIO_X2_START + (_nr))
#define EXYNOS5_GPX3(_nr) (EXYNOS5_GPIO_X3_START + (_nr))
#define EXYNOS5_GPE0(_nr) (EXYNOS5_GPIO_E0_START + (_nr))
#define EXYNOS5_GPE1(_nr) (EXYNOS5_GPIO_E1_START + (_nr))
#define EXYNOS5_GPF0(_nr) (EXYNOS5_GPIO_F0_START + (_nr))
#define EXYNOS5_GPF1(_nr) (EXYNOS5_GPIO_F1_START + (_nr))
#define EXYNOS5_GPG0(_nr) (EXYNOS5_GPIO_G0_START + (_nr))
#define EXYNOS5_GPG1(_nr) (EXYNOS5_GPIO_G1_START + (_nr))
#define EXYNOS5_GPG2(_nr) (EXYNOS5_GPIO_G2_START + (_nr))
#define EXYNOS5_GPH0(_nr) (EXYNOS5_GPIO_H0_START + (_nr))
#define EXYNOS5_GPH1(_nr) (EXYNOS5_GPIO_H1_START + (_nr))
#define EXYNOS5_GPV0(_nr) (EXYNOS5_GPIO_V0_START + (_nr))
#define EXYNOS5_GPV1(_nr) (EXYNOS5_GPIO_V1_START + (_nr))
#define EXYNOS5_GPV2(_nr) (EXYNOS5_GPIO_V2_START + (_nr))
#define EXYNOS5_GPV3(_nr) (EXYNOS5_GPIO_V3_START + (_nr))
#define EXYNOS5_GPV4(_nr) (EXYNOS5_GPIO_V4_START + (_nr))
#define EXYNOS5_GPZ(_nr) (EXYNOS5_GPIO_Z_START + (_nr))
/* the end of the EXYNOS5 specific gpios */
#define EXYNOS5_GPIO_END (EXYNOS5_GPZ(EXYNOS5_GPIO_Z_NR) + 1)
/* actually, EXYNOS5_GPIO_END is bigger than EXYNOS4 */
#define S3C_GPIO_END (EXYNOS5_GPIO_END)
/* define the number of gpios */
#define ARCH_NR_GPIOS (CONFIG_SAMSUNG_GPIO_EXTRA + S3C_GPIO_END)
#endif /* __ASM_ARCH_GPIO_H */ #endif /* __ASM_ARCH_GPIO_H */
...@@ -101,6 +101,10 @@ ...@@ -101,6 +101,10 @@
#define EXYNOS4_PA_GPIO1 0x11400000 #define EXYNOS4_PA_GPIO1 0x11400000
#define EXYNOS4_PA_GPIO2 0x11000000 #define EXYNOS4_PA_GPIO2 0x11000000
#define EXYNOS4_PA_GPIO3 0x03860000 #define EXYNOS4_PA_GPIO3 0x03860000
#define EXYNOS5_PA_GPIO1 0x11400000
#define EXYNOS5_PA_GPIO2 0x13400000
#define EXYNOS5_PA_GPIO3 0x10D10000
#define EXYNOS5_PA_GPIO4 0x03860000
#define EXYNOS4_PA_MIPI_CSIS0 0x11880000 #define EXYNOS4_PA_MIPI_CSIS0 0x11880000
#define EXYNOS4_PA_MIPI_CSIS1 0x11890000 #define EXYNOS4_PA_MIPI_CSIS1 0x11890000
......
...@@ -182,6 +182,12 @@ static __init int exynos4_pm_init_power_domain(void) ...@@ -182,6 +182,12 @@ static __init int exynos4_pm_init_power_domain(void)
#endif #endif
#ifdef CONFIG_S5P_DEV_CSIS1 #ifdef CONFIG_S5P_DEV_CSIS1
exynos_pm_add_dev_to_genpd(&s5p_device_mipi_csis1, &exynos4_pd_cam); exynos_pm_add_dev_to_genpd(&s5p_device_mipi_csis1, &exynos4_pd_cam);
#endif
#ifdef CONFIG_S5P_DEV_G2D
exynos_pm_add_dev_to_genpd(&s5p_device_g2d, &exynos4_pd_lcd0);
#endif
#ifdef CONFIG_S5P_DEV_JPEG
exynos_pm_add_dev_to_genpd(&s5p_device_jpeg, &exynos4_pd_cam);
#endif #endif
return 0; return 0;
} }
......
...@@ -29,5 +29,30 @@ config ARCH_LPC32XX_UART6_SELECT ...@@ -29,5 +29,30 @@ config ARCH_LPC32XX_UART6_SELECT
endmenu endmenu
menu "LPC32XX chip components"
config ARCH_LPC32XX_IRAM_FOR_NET
bool "Use IRAM for network buffers"
default y
help
Say Y here to use the LPC internal fast IRAM (i.e. 256KB SRAM) as
network buffer. If the total combined required buffer sizes is
larger than the size of IRAM, then SDRAM will be used instead.
This can be enabled safely if the IRAM is not intended for other
uses.
config ARCH_LPC32XX_MII_SUPPORT
bool "Check to enable MII support or leave disabled for RMII support"
help
Say Y here to enable MII support, or N for RMII support. Regardless of
which support is selected, the ethernet interface driver needs to be
selected in the device driver networking section.
The PHY3250 reference board uses RMII, so users of this board should
say N.
endmenu
endif endif
...@@ -87,6 +87,7 @@ ...@@ -87,6 +87,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/amba/bus.h> #include <linux/amba/bus.h>
...@@ -100,6 +101,8 @@ ...@@ -100,6 +101,8 @@
static DEFINE_SPINLOCK(global_clkregs_lock); static DEFINE_SPINLOCK(global_clkregs_lock);
static int usb_pll_enable, usb_pll_valid;
static struct clk clk_armpll; static struct clk clk_armpll;
static struct clk clk_usbpll; static struct clk clk_usbpll;
...@@ -384,30 +387,62 @@ static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup) ...@@ -384,30 +387,62 @@ static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup)
static int local_usbpll_enable(struct clk *clk, int enable) static int local_usbpll_enable(struct clk *clk, int enable)
{ {
u32 reg; u32 reg;
int ret = -ENODEV; int ret = 0;
unsigned long timeout = jiffies + msecs_to_jiffies(10); unsigned long timeout = jiffies + msecs_to_jiffies(20);
reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
if (enable == 0) { __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN2 |
reg &= ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 | LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
LPC32XX_CLKPWR_USBCTRL_CLK_EN2); LPC32XX_CLKPWR_USB_CTRL);
__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); __raw_writel(reg & ~LPC32XX_CLKPWR_USBCTRL_CLK_EN1,
} else if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP) { LPC32XX_CLKPWR_USB_CTRL);
if (enable && usb_pll_valid && usb_pll_enable) {
ret = -ENODEV;
/*
* If the PLL rate has been previously set, then the rate
* in the PLL register is valid and can be enabled here.
* Otherwise, it needs to be enabled as part of setrate.
*/
/*
* Gate clock into PLL
*/
reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1; reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1;
__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
/* Wait for PLL lock */ /*
* Enable PLL
*/
reg |= LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP;
__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
/*
* Wait for PLL to lock
*/
while (time_before(jiffies, timeout) && (ret == -ENODEV)) { while (time_before(jiffies, timeout) && (ret == -ENODEV)) {
reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS) if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS)
ret = 0; ret = 0;
else
udelay(10);
} }
/*
* Gate clock from PLL if PLL is locked
*/
if (ret == 0) { if (ret == 0) {
reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2; __raw_writel(reg | LPC32XX_CLKPWR_USBCTRL_CLK_EN2,
__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); LPC32XX_CLKPWR_USB_CTRL);
} else {
__raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 |
LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
LPC32XX_CLKPWR_USB_CTRL);
} }
} else if ((enable == 0) && usb_pll_valid && usb_pll_enable) {
usb_pll_valid = 0;
usb_pll_enable = 0;
} }
return ret; return ret;
...@@ -425,7 +460,7 @@ static unsigned long local_usbpll_round_rate(struct clk *clk, ...@@ -425,7 +460,7 @@ static unsigned long local_usbpll_round_rate(struct clk *clk,
*/ */
rate = rate * 1000; rate = rate * 1000;
clkin = clk->parent->rate; clkin = clk->get_rate(clk);
usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
clkin = clkin / usbdiv; clkin = clkin / usbdiv;
...@@ -439,7 +474,8 @@ static unsigned long local_usbpll_round_rate(struct clk *clk, ...@@ -439,7 +474,8 @@ static unsigned long local_usbpll_round_rate(struct clk *clk,
static int local_usbpll_set_rate(struct clk *clk, unsigned long rate) static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
{ {
u32 clkin, reg, usbdiv; int ret = -ENODEV;
u32 clkin, usbdiv;
struct clk_pll_setup pllsetup; struct clk_pll_setup pllsetup;
/* /*
...@@ -448,7 +484,7 @@ static int local_usbpll_set_rate(struct clk *clk, unsigned long rate) ...@@ -448,7 +484,7 @@ static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
*/ */
rate = rate * 1000; rate = rate * 1000;
clkin = clk->get_rate(clk); clkin = clk->get_rate(clk->parent);
usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
clkin = clkin / usbdiv; clkin = clkin / usbdiv;
...@@ -457,22 +493,25 @@ static int local_usbpll_set_rate(struct clk *clk, unsigned long rate) ...@@ -457,22 +493,25 @@ static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0) if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0)
return -EINVAL; return -EINVAL;
/*
* Disable PLL clocks during PLL change
*/
local_usbpll_enable(clk, 0); local_usbpll_enable(clk, 0);
pllsetup.analog_on = 0;
local_clk_usbpll_setup(&pllsetup);
reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); /*
reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1; * Start USB PLL and check PLL status
__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); */
pllsetup.analog_on = 1; usb_pll_valid = 1;
local_clk_usbpll_setup(&pllsetup); usb_pll_enable = 1;
ret = local_usbpll_enable(clk, 1);
if (ret >= 0)
clk->rate = clk_check_pll_setup(clkin, &pllsetup); clk->rate = clk_check_pll_setup(clkin, &pllsetup);
reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); return ret;
reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2;
__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
return 0;
} }
static struct clk clk_usbpll = { static struct clk clk_usbpll = {
......
...@@ -159,6 +159,53 @@ struct platform_device lpc32xx_adc_device = { ...@@ -159,6 +159,53 @@ struct platform_device lpc32xx_adc_device = {
.resource = adc_resources, .resource = adc_resources,
}; };
/*
* USB support
*/
/* The dmamask must be set for OHCI to work */
static u64 ohci_dmamask = ~(u32) 0;
static struct resource ohci_resources[] = {
{
.start = IO_ADDRESS(LPC32XX_USB_BASE),
.end = IO_ADDRESS(LPC32XX_USB_BASE + 0x100 - 1),
.flags = IORESOURCE_MEM,
}, {
.start = IRQ_LPC32XX_USB_HOST,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device lpc32xx_ohci_device = {
.name = "usb-ohci",
.id = -1,
.dev = {
.dma_mask = &ohci_dmamask,
.coherent_dma_mask = 0xFFFFFFFF,
},
.num_resources = ARRAY_SIZE(ohci_resources),
.resource = ohci_resources,
};
/*
* Network Support
*/
static struct resource net_resources[] = {
[0] = DEFINE_RES_MEM(LPC32XX_ETHERNET_BASE, SZ_4K),
[1] = DEFINE_RES_MEM(LPC32XX_IRAM_BASE, SZ_128K),
[2] = DEFINE_RES_IRQ(IRQ_LPC32XX_ETHERNET),
};
static u64 lpc32xx_mac_dma_mask = 0xffffffffUL;
struct platform_device lpc32xx_net_device = {
.name = "lpc-eth",
.id = 0,
.dev = {
.dma_mask = &lpc32xx_mac_dma_mask,
.coherent_dma_mask = 0xffffffffUL,
},
.num_resources = ARRAY_SIZE(net_resources),
.resource = net_resources,
};
/* /*
* Returns the unique ID for the device * Returns the unique ID for the device
*/ */
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#ifndef __LPC32XX_COMMON_H #ifndef __LPC32XX_COMMON_H
#define __LPC32XX_COMMON_H #define __LPC32XX_COMMON_H
#include <mach/board.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
/* /*
...@@ -31,6 +32,8 @@ extern struct platform_device lpc32xx_i2c2_device; ...@@ -31,6 +32,8 @@ extern struct platform_device lpc32xx_i2c2_device;
extern struct platform_device lpc32xx_tsc_device; extern struct platform_device lpc32xx_tsc_device;
extern struct platform_device lpc32xx_adc_device; extern struct platform_device lpc32xx_adc_device;
extern struct platform_device lpc32xx_rtc_device; extern struct platform_device lpc32xx_rtc_device;
extern struct platform_device lpc32xx_ohci_device;
extern struct platform_device lpc32xx_net_device;
/* /*
* Other arch specific structures and functions * Other arch specific structures and functions
...@@ -67,7 +70,6 @@ extern u32 clk_get_pclk_div(void); ...@@ -67,7 +70,6 @@ extern u32 clk_get_pclk_div(void);
extern void lpc32xx_get_uid(u32 devid[4]); extern void lpc32xx_get_uid(u32 devid[4]);
extern u32 lpc32xx_return_iram_size(void); extern u32 lpc32xx_return_iram_size(void);
/* /*
* Pointers used for sizing and copying suspend function data * Pointers used for sizing and copying suspend function data
*/ */
......
/*
* arm/arch/mach-lpc32xx/include/mach/board.h
*
* Author: Kevin Wells <kevin.wells@nxp.com>
*
* Copyright (C) 2010 NXP Semiconductors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_ARCH_BOARD_H
#define __ASM_ARCH_BOARD_H
extern u32 lpc32xx_return_iram_size(void);
#endif /* __ASM_ARCH_BOARD_H */
...@@ -150,6 +150,10 @@ static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = { ...@@ -150,6 +150,10 @@ static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = {
.event_group = &lpc32xx_event_int_regs, .event_group = &lpc32xx_event_int_regs,
.mask = LPC32XX_CLKPWR_INTSRC_KEY_BIT, .mask = LPC32XX_CLKPWR_INTSRC_KEY_BIT,
}, },
[IRQ_LPC32XX_ETHERNET] = {
.event_group = &lpc32xx_event_int_regs,
.mask = LPC32XX_CLKPWR_INTSRC_MAC_BIT,
},
[IRQ_LPC32XX_USB_OTG_ATX] = { [IRQ_LPC32XX_USB_OTG_ATX] = {
.event_group = &lpc32xx_event_int_regs, .event_group = &lpc32xx_event_int_regs,
.mask = LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT, .mask = LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT,
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/platform.h> #include <mach/platform.h>
#include <mach/board.h>
#include <mach/gpio-lpc32xx.h> #include <mach/gpio-lpc32xx.h>
#include "common.h" #include "common.h"
...@@ -255,6 +256,8 @@ static struct platform_device *phy3250_devs[] __initdata = { ...@@ -255,6 +256,8 @@ static struct platform_device *phy3250_devs[] __initdata = {
&lpc32xx_watchdog_device, &lpc32xx_watchdog_device,
&lpc32xx_gpio_led_device, &lpc32xx_gpio_led_device,
&lpc32xx_adc_device, &lpc32xx_adc_device,
&lpc32xx_ohci_device,
&lpc32xx_net_device,
}; };
static struct amba_device *amba_devs[] __initdata = { static struct amba_device *amba_devs[] __initdata = {
......
...@@ -169,7 +169,7 @@ int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip, ...@@ -169,7 +169,7 @@ int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN); return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
} }
static int exynos4_gpio_setpull(struct samsung_gpio_chip *chip, static int exynos_gpio_setpull(struct samsung_gpio_chip *chip,
unsigned int off, samsung_gpio_pull_t pull) unsigned int off, samsung_gpio_pull_t pull)
{ {
if (pull == S3C_GPIO_PULL_UP) if (pull == S3C_GPIO_PULL_UP)
...@@ -178,7 +178,7 @@ static int exynos4_gpio_setpull(struct samsung_gpio_chip *chip, ...@@ -178,7 +178,7 @@ static int exynos4_gpio_setpull(struct samsung_gpio_chip *chip,
return samsung_gpio_setpull_updown(chip, off, pull); return samsung_gpio_setpull_updown(chip, off, pull);
} }
static samsung_gpio_pull_t exynos4_gpio_getpull(struct samsung_gpio_chip *chip, static samsung_gpio_pull_t exynos_gpio_getpull(struct samsung_gpio_chip *chip,
unsigned int off) unsigned int off)
{ {
samsung_gpio_pull_t pull; samsung_gpio_pull_t pull;
...@@ -452,9 +452,9 @@ static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = { ...@@ -452,9 +452,9 @@ static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
}; };
#endif #endif
static struct samsung_gpio_cfg exynos4_gpio_cfg = { static struct samsung_gpio_cfg exynos_gpio_cfg = {
.set_pull = exynos4_gpio_setpull, .set_pull = exynos_gpio_setpull,
.get_pull = exynos4_gpio_getpull, .get_pull = exynos_gpio_getpull,
.set_config = samsung_gpio_setcfg_4bit, .set_config = samsung_gpio_setcfg_4bit,
.get_config = samsung_gpio_getcfg_4bit, .get_config = samsung_gpio_getcfg_4bit,
}; };
...@@ -502,13 +502,13 @@ static struct samsung_gpio_cfg samsung_gpio_cfgs[] = { ...@@ -502,13 +502,13 @@ static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
.get_config = samsung_gpio_getcfg_2bit, .get_config = samsung_gpio_getcfg_2bit,
}, },
[8] = { [8] = {
.set_pull = exynos4_gpio_setpull, .set_pull = exynos_gpio_setpull,
.get_pull = exynos4_gpio_getpull, .get_pull = exynos_gpio_getpull,
}, },
[9] = { [9] = {
.cfg_eint = 0x3, .cfg_eint = 0x3,
.set_pull = exynos4_gpio_setpull, .set_pull = exynos_gpio_setpull,
.get_pull = exynos4_gpio_getpull, .get_pull = exynos_gpio_getpull,
} }
}; };
...@@ -2113,10 +2113,10 @@ static struct samsung_gpio_chip s5pv210_gpios_4bit[] = { ...@@ -2113,10 +2113,10 @@ static struct samsung_gpio_chip s5pv210_gpios_4bit[] = {
}; };
/* /*
* Followings are the gpio banks in EXYNOS4210 * Followings are the gpio banks in EXYNOS SoCs
* *
* The 'config' member when left to NULL, is initialized to the default * The 'config' member when left to NULL, is initialized to the default
* structure samsung_gpio_cfgs[3] in the init function below. * structure exynos_gpio_cfg in the init function below.
* *
* The 'base' member is also initialized in the init function below. * The 'base' member is also initialized in the init function below.
* Note: The initialization of 'base' member of samsung_gpio_chip structure * Note: The initialization of 'base' member of samsung_gpio_chip structure
...@@ -2331,7 +2331,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = { ...@@ -2331,7 +2331,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = {
.label = "GPY6", .label = "GPY6",
}, },
}, { }, {
.base = (S5P_VA_GPIO2 + 0xC00),
.config = &samsung_gpio_cfgs[9], .config = &samsung_gpio_cfgs[9],
.irq_base = IRQ_EINT(0), .irq_base = IRQ_EINT(0),
.chip = { .chip = {
...@@ -2341,7 +2340,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = { ...@@ -2341,7 +2340,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = {
.to_irq = samsung_gpiolib_to_irq, .to_irq = samsung_gpiolib_to_irq,
}, },
}, { }, {
.base = (S5P_VA_GPIO2 + 0xC20),
.config = &samsung_gpio_cfgs[9], .config = &samsung_gpio_cfgs[9],
.irq_base = IRQ_EINT(8), .irq_base = IRQ_EINT(8),
.chip = { .chip = {
...@@ -2351,7 +2349,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = { ...@@ -2351,7 +2349,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = {
.to_irq = samsung_gpiolib_to_irq, .to_irq = samsung_gpiolib_to_irq,
}, },
}, { }, {
.base = (S5P_VA_GPIO2 + 0xC40),
.config = &samsung_gpio_cfgs[9], .config = &samsung_gpio_cfgs[9],
.irq_base = IRQ_EINT(16), .irq_base = IRQ_EINT(16),
.chip = { .chip = {
...@@ -2361,7 +2358,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = { ...@@ -2361,7 +2358,6 @@ static struct samsung_gpio_chip exynos4_gpios_2[] = {
.to_irq = samsung_gpiolib_to_irq, .to_irq = samsung_gpiolib_to_irq,
}, },
}, { }, {
.base = (S5P_VA_GPIO2 + 0xC60),
.config = &samsung_gpio_cfgs[9], .config = &samsung_gpio_cfgs[9],
.irq_base = IRQ_EINT(24), .irq_base = IRQ_EINT(24),
.chip = { .chip = {
...@@ -2386,8 +2382,280 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = { ...@@ -2386,8 +2382,280 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = {
#endif #endif
}; };
#if defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF) static struct samsung_gpio_chip exynos5_gpios_1[] = {
static int exynos4_gpio_xlate(struct gpio_chip *gc, #ifdef CONFIG_ARCH_EXYNOS5
{
.chip = {
.base = EXYNOS5_GPA0(0),
.ngpio = EXYNOS5_GPIO_A0_NR,
.label = "GPA0",
},
}, {
.chip = {
.base = EXYNOS5_GPA1(0),
.ngpio = EXYNOS5_GPIO_A1_NR,
.label = "GPA1",
},
}, {
.chip = {
.base = EXYNOS5_GPA2(0),
.ngpio = EXYNOS5_GPIO_A2_NR,
.label = "GPA2",
},
}, {
.chip = {
.base = EXYNOS5_GPB0(0),
.ngpio = EXYNOS5_GPIO_B0_NR,
.label = "GPB0",
},
}, {
.chip = {
.base = EXYNOS5_GPB1(0),
.ngpio = EXYNOS5_GPIO_B1_NR,
.label = "GPB1",
},
}, {
.chip = {
.base = EXYNOS5_GPB2(0),
.ngpio = EXYNOS5_GPIO_B2_NR,
.label = "GPB2",
},
}, {
.chip = {
.base = EXYNOS5_GPB3(0),
.ngpio = EXYNOS5_GPIO_B3_NR,
.label = "GPB3",
},
}, {
.chip = {
.base = EXYNOS5_GPC0(0),
.ngpio = EXYNOS5_GPIO_C0_NR,
.label = "GPC0",
},
}, {
.chip = {
.base = EXYNOS5_GPC1(0),
.ngpio = EXYNOS5_GPIO_C1_NR,
.label = "GPC1",
},
}, {
.chip = {
.base = EXYNOS5_GPC2(0),
.ngpio = EXYNOS5_GPIO_C2_NR,
.label = "GPC2",
},
}, {
.chip = {
.base = EXYNOS5_GPC3(0),
.ngpio = EXYNOS5_GPIO_C3_NR,
.label = "GPC3",
},
}, {
.chip = {
.base = EXYNOS5_GPD0(0),
.ngpio = EXYNOS5_GPIO_D0_NR,
.label = "GPD0",
},
}, {
.chip = {
.base = EXYNOS5_GPD1(0),
.ngpio = EXYNOS5_GPIO_D1_NR,
.label = "GPD1",
},
}, {
.chip = {
.base = EXYNOS5_GPY0(0),
.ngpio = EXYNOS5_GPIO_Y0_NR,
.label = "GPY0",
},
}, {
.chip = {
.base = EXYNOS5_GPY1(0),
.ngpio = EXYNOS5_GPIO_Y1_NR,
.label = "GPY1",
},
}, {
.chip = {
.base = EXYNOS5_GPY2(0),
.ngpio = EXYNOS5_GPIO_Y2_NR,
.label = "GPY2",
},
}, {
.chip = {
.base = EXYNOS5_GPY3(0),
.ngpio = EXYNOS5_GPIO_Y3_NR,
.label = "GPY3",
},
}, {
.chip = {
.base = EXYNOS5_GPY4(0),
.ngpio = EXYNOS5_GPIO_Y4_NR,
.label = "GPY4",
},
}, {
.chip = {
.base = EXYNOS5_GPY5(0),
.ngpio = EXYNOS5_GPIO_Y5_NR,
.label = "GPY5",
},
}, {
.chip = {
.base = EXYNOS5_GPY6(0),
.ngpio = EXYNOS5_GPIO_Y6_NR,
.label = "GPY6",
},
}, {
.config = &samsung_gpio_cfgs[9],
.irq_base = IRQ_EINT(0),
.chip = {
.base = EXYNOS5_GPX0(0),
.ngpio = EXYNOS5_GPIO_X0_NR,
.label = "GPX0",
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.config = &samsung_gpio_cfgs[9],
.irq_base = IRQ_EINT(8),
.chip = {
.base = EXYNOS5_GPX1(0),
.ngpio = EXYNOS5_GPIO_X1_NR,
.label = "GPX1",
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.config = &samsung_gpio_cfgs[9],
.irq_base = IRQ_EINT(16),
.chip = {
.base = EXYNOS5_GPX2(0),
.ngpio = EXYNOS5_GPIO_X2_NR,
.label = "GPX2",
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.config = &samsung_gpio_cfgs[9],
.irq_base = IRQ_EINT(24),
.chip = {
.base = EXYNOS5_GPX3(0),
.ngpio = EXYNOS5_GPIO_X3_NR,
.label = "GPX3",
.to_irq = samsung_gpiolib_to_irq,
},
},
#endif
};
static struct samsung_gpio_chip exynos5_gpios_2[] = {
#ifdef CONFIG_ARCH_EXYNOS5
{
.chip = {
.base = EXYNOS5_GPE0(0),
.ngpio = EXYNOS5_GPIO_E0_NR,
.label = "GPE0",
},
}, {
.chip = {
.base = EXYNOS5_GPE1(0),
.ngpio = EXYNOS5_GPIO_E1_NR,
.label = "GPE1",
},
}, {
.chip = {
.base = EXYNOS5_GPF0(0),
.ngpio = EXYNOS5_GPIO_F0_NR,
.label = "GPF0",
},
}, {
.chip = {
.base = EXYNOS5_GPF1(0),
.ngpio = EXYNOS5_GPIO_F1_NR,
.label = "GPF1",
},
}, {
.chip = {
.base = EXYNOS5_GPG0(0),
.ngpio = EXYNOS5_GPIO_G0_NR,
.label = "GPG0",
},
}, {
.chip = {
.base = EXYNOS5_GPG1(0),
.ngpio = EXYNOS5_GPIO_G1_NR,
.label = "GPG1",
},
}, {
.chip = {
.base = EXYNOS5_GPG2(0),
.ngpio = EXYNOS5_GPIO_G2_NR,
.label = "GPG2",
},
}, {
.chip = {
.base = EXYNOS5_GPH0(0),
.ngpio = EXYNOS5_GPIO_H0_NR,
.label = "GPH0",
},
}, {
.chip = {
.base = EXYNOS5_GPH1(0),
.ngpio = EXYNOS5_GPIO_H1_NR,
.label = "GPH1",
},
},
#endif
};
static struct samsung_gpio_chip exynos5_gpios_3[] = {
#ifdef CONFIG_ARCH_EXYNOS5
{
.chip = {
.base = EXYNOS5_GPV0(0),
.ngpio = EXYNOS5_GPIO_V0_NR,
.label = "GPV0",
},
}, {
.chip = {
.base = EXYNOS5_GPV1(0),
.ngpio = EXYNOS5_GPIO_V1_NR,
.label = "GPV1",
},
}, {
.chip = {
.base = EXYNOS5_GPV2(0),
.ngpio = EXYNOS5_GPIO_V2_NR,
.label = "GPV2",
},
}, {
.chip = {
.base = EXYNOS5_GPV3(0),
.ngpio = EXYNOS5_GPIO_V3_NR,
.label = "GPV3",
},
}, {
.chip = {
.base = EXYNOS5_GPV4(0),
.ngpio = EXYNOS5_GPIO_V4_NR,
.label = "GPV4",
},
},
#endif
};
static struct samsung_gpio_chip exynos5_gpios_4[] = {
#ifdef CONFIG_ARCH_EXYNOS5
{
.chip = {
.base = EXYNOS5_GPZ(0),
.ngpio = EXYNOS5_GPIO_Z_NR,
.label = "GPZ",
},
},
#endif
};
#if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF)
static int exynos_gpio_xlate(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec, u32 *flags) const struct of_phandle_args *gpiospec, u32 *flags)
{ {
unsigned int pin; unsigned int pin;
...@@ -2413,12 +2681,12 @@ static int exynos4_gpio_xlate(struct gpio_chip *gc, ...@@ -2413,12 +2681,12 @@ static int exynos4_gpio_xlate(struct gpio_chip *gc,
return gpiospec->args[0]; return gpiospec->args[0];
} }
static const struct of_device_id exynos4_gpio_dt_match[] __initdata = { static const struct of_device_id exynos_gpio_dt_match[] __initdata = {
{ .compatible = "samsung,exynos4-gpio", }, { .compatible = "samsung,exynos4-gpio", },
{} {}
}; };
static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
u64 base, u64 offset) u64 base, u64 offset)
{ {
struct gpio_chip *gc = &chip->chip; struct gpio_chip *gc = &chip->chip;
...@@ -2429,28 +2697,29 @@ static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, ...@@ -2429,28 +2697,29 @@ static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset; address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
gc->of_node = of_find_matching_node_by_address(NULL, gc->of_node = of_find_matching_node_by_address(NULL,
exynos4_gpio_dt_match, address); exynos_gpio_dt_match, address);
if (!gc->of_node) { if (!gc->of_node) {
pr_info("gpio: device tree node not found for gpio controller" pr_info("gpio: device tree node not found for gpio controller"
" with base address %08llx\n", address); " with base address %08llx\n", address);
return; return;
} }
gc->of_gpio_n_cells = 4; gc->of_gpio_n_cells = 4;
gc->of_xlate = exynos4_gpio_xlate; gc->of_xlate = exynos_gpio_xlate;
} }
#elif defined(CONFIG_ARCH_EXYNOS4) #elif defined(CONFIG_ARCH_EXYNOS)
static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
u64 base, u64 offset) u64 base, u64 offset)
{ {
return; return;
} }
#endif /* defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF) */ #endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */
/* TODO: cleanup soc_is_* */ /* TODO: cleanup soc_is_* */
static __init int samsung_gpiolib_init(void) static __init int samsung_gpiolib_init(void)
{ {
struct samsung_gpio_chip *chip; struct samsung_gpio_chip *chip;
int i, nr_chips; int i, nr_chips;
void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4;
int group = 0; int group = 0;
samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
...@@ -2516,66 +2785,200 @@ static __init int samsung_gpiolib_init(void) ...@@ -2516,66 +2785,200 @@ static __init int samsung_gpiolib_init(void)
s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR); s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
#endif #endif
} else if (soc_is_exynos4210()) { } else if (soc_is_exynos4210()) {
group = 0; #ifdef CONFIG_CPU_EXYNOS4210
void __iomem *gpx_base;
/* gpio part1 */ /* gpio part1 */
gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K);
if (gpio_base1 == NULL) {
pr_err("unable to ioremap for gpio_base1\n");
goto err_ioremap1;
}
chip = exynos4_gpios_1; chip = exynos4_gpios_1;
nr_chips = ARRAY_SIZE(exynos4_gpios_1); nr_chips = ARRAY_SIZE(exynos4_gpios_1);
for (i = 0; i < nr_chips; i++, chip++) { for (i = 0; i < nr_chips; i++, chip++) {
if (!chip->config) { if (!chip->config) {
chip->config = &exynos4_gpio_cfg; chip->config = &exynos_gpio_cfg;
chip->group = group++; chip->group = group++;
} }
#ifdef CONFIG_CPU_EXYNOS4210 exynos_gpiolib_attach_ofnode(chip,
exynos4_gpiolib_attach_ofnode(chip,
EXYNOS4_PA_GPIO1, i * 0x20); EXYNOS4_PA_GPIO1, i * 0x20);
#endif
} }
samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1); samsung_gpiolib_add_4bit_chips(exynos4_gpios_1,
nr_chips, gpio_base1);
/* gpio part2 */ /* gpio part2 */
gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
if (gpio_base2 == NULL) {
pr_err("unable to ioremap for gpio_base2\n");
goto err_ioremap2;
}
/* need to set base address for gpx */
chip = &exynos4_gpios_2[16];
gpx_base = gpio_base2 + 0xC00;
for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
chip->base = gpx_base;
chip = exynos4_gpios_2; chip = exynos4_gpios_2;
nr_chips = ARRAY_SIZE(exynos4_gpios_2); nr_chips = ARRAY_SIZE(exynos4_gpios_2);
for (i = 0; i < nr_chips; i++, chip++) { for (i = 0; i < nr_chips; i++, chip++) {
if (!chip->config) { if (!chip->config) {
chip->config = &exynos4_gpio_cfg; chip->config = &exynos_gpio_cfg;
chip->group = group++; chip->group = group++;
} }
#ifdef CONFIG_CPU_EXYNOS4210 exynos_gpiolib_attach_ofnode(chip,
exynos4_gpiolib_attach_ofnode(chip,
EXYNOS4_PA_GPIO2, i * 0x20); EXYNOS4_PA_GPIO2, i * 0x20);
#endif
} }
samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2); samsung_gpiolib_add_4bit_chips(exynos4_gpios_2,
nr_chips, gpio_base2);
/* gpio part3 */ /* gpio part3 */
gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256);
if (gpio_base3 == NULL) {
pr_err("unable to ioremap for gpio_base3\n");
goto err_ioremap3;
}
chip = exynos4_gpios_3; chip = exynos4_gpios_3;
nr_chips = ARRAY_SIZE(exynos4_gpios_3); nr_chips = ARRAY_SIZE(exynos4_gpios_3);
for (i = 0; i < nr_chips; i++, chip++) { for (i = 0; i < nr_chips; i++, chip++) {
if (!chip->config) { if (!chip->config) {
chip->config = &exynos4_gpio_cfg; chip->config = &exynos_gpio_cfg;
chip->group = group++; chip->group = group++;
} }
#ifdef CONFIG_CPU_EXYNOS4210 exynos_gpiolib_attach_ofnode(chip,
exynos4_gpiolib_attach_ofnode(chip,
EXYNOS4_PA_GPIO3, i * 0x20); EXYNOS4_PA_GPIO3, i * 0x20);
#endif
} }
samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3); samsung_gpiolib_add_4bit_chips(exynos4_gpios_3,
nr_chips, gpio_base3);
#if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT) #if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT)
s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS); s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS); s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
#endif #endif
#endif /* CONFIG_CPU_EXYNOS4210 */
} else if (soc_is_exynos5250()) {
#ifdef CONFIG_SOC_EXYNOS5250
void __iomem *gpx_base;
/* gpio part1 */
gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
if (gpio_base1 == NULL) {
pr_err("unable to ioremap for gpio_base1\n");
goto err_ioremap1;
}
/* need to set base address for gpx */
chip = &exynos5_gpios_1[20];
gpx_base = gpio_base1 + 0xC00;
for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
chip->base = gpx_base;
chip = exynos5_gpios_1;
nr_chips = ARRAY_SIZE(exynos5_gpios_1);
for (i = 0; i < nr_chips; i++, chip++) {
if (!chip->config) {
chip->config = &exynos_gpio_cfg;
chip->group = group++;
}
exynos_gpiolib_attach_ofnode(chip,
EXYNOS5_PA_GPIO1, i * 0x20);
}
samsung_gpiolib_add_4bit_chips(exynos5_gpios_1,
nr_chips, gpio_base1);
/* gpio part2 */
gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K);
if (gpio_base2 == NULL) {
pr_err("unable to ioremap for gpio_base2\n");
goto err_ioremap2;
}
chip = exynos5_gpios_2;
nr_chips = ARRAY_SIZE(exynos5_gpios_2);
for (i = 0; i < nr_chips; i++, chip++) {
if (!chip->config) {
chip->config = &exynos_gpio_cfg;
chip->group = group++;
}
exynos_gpiolib_attach_ofnode(chip,
EXYNOS5_PA_GPIO2, i * 0x20);
}
samsung_gpiolib_add_4bit_chips(exynos5_gpios_2,
nr_chips, gpio_base2);
/* gpio part3 */
gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K);
if (gpio_base3 == NULL) {
pr_err("unable to ioremap for gpio_base3\n");
goto err_ioremap3;
}
/* need to set base address for gpv */
exynos5_gpios_3[0].base = gpio_base3;
exynos5_gpios_3[1].base = gpio_base3 + 0x20;
exynos5_gpios_3[2].base = gpio_base3 + 0x60;
exynos5_gpios_3[3].base = gpio_base3 + 0x80;
exynos5_gpios_3[4].base = gpio_base3 + 0xC0;
chip = exynos5_gpios_3;
nr_chips = ARRAY_SIZE(exynos5_gpios_3);
for (i = 0; i < nr_chips; i++, chip++) {
if (!chip->config) {
chip->config = &exynos_gpio_cfg;
chip->group = group++;
}
exynos_gpiolib_attach_ofnode(chip,
EXYNOS5_PA_GPIO3, i * 0x20);
}
samsung_gpiolib_add_4bit_chips(exynos5_gpios_3,
nr_chips, gpio_base3);
/* gpio part4 */
gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K);
if (gpio_base4 == NULL) {
pr_err("unable to ioremap for gpio_base4\n");
goto err_ioremap4;
}
chip = exynos5_gpios_4;
nr_chips = ARRAY_SIZE(exynos5_gpios_4);
for (i = 0; i < nr_chips; i++, chip++) {
if (!chip->config) {
chip->config = &exynos_gpio_cfg;
chip->group = group++;
}
exynos_gpiolib_attach_ofnode(chip,
EXYNOS5_PA_GPIO4, i * 0x20);
}
samsung_gpiolib_add_4bit_chips(exynos5_gpios_4,
nr_chips, gpio_base4);
#endif /* CONFIG_SOC_EXYNOS5250 */
} else { } else {
WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n"); WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
return -ENODEV; return -ENODEV;
} }
return 0; return 0;
err_ioremap4:
iounmap(gpio_base3);
err_ioremap3:
iounmap(gpio_base2);
err_ioremap2:
iounmap(gpio_base1);
err_ioremap1:
return -ENOMEM;
} }
core_initcall(samsung_gpiolib_init); core_initcall(samsung_gpiolib_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment