diff options
author | Tejun Heo <tj@kernel.org> | 2010-01-05 09:17:33 +0900 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2010-01-05 09:17:33 +0900 |
commit | 32032df6c2f6c9c6b2ada2ce42322231824f70c2 (patch) | |
tree | b1ce838a37044bb38dfc128e2116ca35630e629a /arch/sh/boards | |
parent | 22b737f4c75197372d64afc6ed1bccd58c00e549 (diff) | |
parent | c5974b835a909ff15c3b7e6cf6789b5eb919f419 (diff) | |
download | linux-32032df6c2f6c9c6b2ada2ce42322231824f70c2.tar.bz2 |
Merge branch 'master' into percpu
Conflicts:
arch/powerpc/platforms/pseries/hvCall.S
include/linux/percpu.h
Diffstat (limited to 'arch/sh/boards')
27 files changed, 1475 insertions, 200 deletions
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile index 7baa21090231..ce0f26381784 100644 --- a/arch/sh/boards/Makefile +++ b/arch/sh/boards/Makefile @@ -1,7 +1,6 @@ # # Specific board support, not covered by a mach group. # -obj-$(CONFIG_SH_AP325RXA) += board-ap325rxa.o obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o obj-$(CONFIG_SH_URQUELL) += board-urquell.o diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c index 0a37c8bfc959..99ffc5f1c0dd 100644 --- a/arch/sh/boards/board-magicpanelr2.c +++ b/arch/sh/boards/board-magicpanelr2.c @@ -205,8 +205,6 @@ static void __init setup_port_multiplexing(void) static void __init mpr2_setup(char **cmdline_p) { - __set_io_port_base(0xa0000000); - /* set Pin Select Register A: * /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2, * /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND diff --git a/arch/sh/boards/mach-ap325rxa/Makefile b/arch/sh/boards/mach-ap325rxa/Makefile new file mode 100644 index 000000000000..4cf1774d2613 --- /dev/null +++ b/arch/sh/boards/mach-ap325rxa/Makefile @@ -0,0 +1,2 @@ +obj-y := setup.o sdram.o + diff --git a/arch/sh/boards/mach-ap325rxa/sdram.S b/arch/sh/boards/mach-ap325rxa/sdram.S new file mode 100644 index 000000000000..db24fbed4fca --- /dev/null +++ b/arch/sh/boards/mach-ap325rxa/sdram.S @@ -0,0 +1,69 @@ +/* + * AP325RXA sdram self/auto-refresh setup code + * + * Copyright (C) 2009 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/sys.h> +#include <linux/errno.h> +#include <linux/linkage.h> +#include <asm/asm-offsets.h> +#include <asm/suspend.h> +#include <asm/romimage-macros.h> + +/* code to enter and leave self-refresh. must be self-contained. + * this code will be copied to on-chip memory and executed from there. + */ + .balign 4 +ENTRY(ap325rxa_sdram_enter_start) + + /* SBSC: disable power down and put in self-refresh mode */ + mov.l 1f, r4 + mov.l 2f, r1 + mov.l @r4, r2 + or r1, r2 + mov.l 3f, r3 + and r3, r2 + mov.l r2, @r4 + + rts + nop + + .balign 4 +1: .long 0xfe400008 /* SDCR0 */ +2: .long 0x00000400 +3: .long 0xffff7fff +ENTRY(ap325rxa_sdram_enter_end) + + .balign 4 +ENTRY(ap325rxa_sdram_leave_start) + + /* SBSC: set auto-refresh mode */ + mov.l 1f, r4 + mov.l @r4, r0 + mov.l 4f, r1 + and r1, r0 + mov.l r0, @r4 + mov.l 6f, r4 + mov.l 8f, r0 + mov.l @r4, r1 + mov #-1, r4 + add r4, r1 + or r1, r0 + mov.l 7f, r1 + mov.l r0, @r1 + + rts + nop + + .balign 4 +1: .long 0xfe400008 /* SDCR0 */ +4: .long 0xfffffbff +6: .long 0xfe40001c /* RTCOR */ +7: .long 0xfe400018 /* RTCNT */ +8: .long 0xa55a0000 +ENTRY(ap325rxa_sdram_leave_end) diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/mach-ap325rxa/setup.c index 2d080732a964..1f5fa5c44f6d 100644 --- a/arch/sh/boards/board-ap325rxa.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -20,8 +20,6 @@ #include <linux/i2c.h> #include <linux/smsc911x.h> #include <linux/gpio.h> -#include <linux/spi/spi.h> -#include <linux/spi/spi_gpio.h> #include <media/ov772x.h> #include <media/soc_camera.h> #include <media/soc_camera_platform.h> @@ -29,6 +27,7 @@ #include <video/sh_mobile_lcdc.h> #include <asm/io.h> #include <asm/clock.h> +#include <asm/suspend.h> #include <cpu/sh7723.h> static struct smsc911x_platform_config smsc911x_config = { @@ -317,20 +316,24 @@ static struct soc_camera_platform_info camera_info = { .format_name = "UYVY", .format_depth = 16, .format = { - .pixelformat = V4L2_PIX_FMT_UYVY, + .code = V4L2_MBUS_FMT_YUYV8_2X8_BE, .colorspace = V4L2_COLORSPACE_SMPTE170M, + .field = V4L2_FIELD_NONE, .width = 640, .height = 480, }, .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | - SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, + SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8 | + SOCAM_DATA_ACTIVE_HIGH, .set_capture = camera_set_capture, - .link = { - .bus_id = 0, - .add_device = ap325rxa_camera_add, - .del_device = ap325rxa_camera_del, - .module_name = "soc_camera_platform", - }, +}; + +struct soc_camera_link camera_link = { + .bus_id = 0, + .add_device = ap325rxa_camera_add, + .del_device = ap325rxa_camera_del, + .module_name = "soc_camera_platform", + .priv = &camera_info, }; static void dummy_release(struct device *dev) @@ -348,7 +351,7 @@ static struct platform_device camera_device = { static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev) { - if (icl != &camera_info.link || camera_probe() <= 0) + if (icl != &camera_link || camera_probe() <= 0) return -ENODEV; camera_info.dev = dev; @@ -358,7 +361,7 @@ static int ap325rxa_camera_add(struct soc_camera_link *icl, static void ap325rxa_camera_del(struct soc_camera_link *icl) { - if (icl != &camera_info.link) + if (icl != &camera_link) return; platform_device_unregister(&camera_device); @@ -409,17 +412,49 @@ static struct platform_device ceu_device = { }, }; -struct spi_gpio_platform_data sdcard_cn3_platform_data = { - .sck = GPIO_PTD0, - .mosi = GPIO_PTD1, - .miso = GPIO_PTD2, - .num_chipselect = 1, +static struct resource sdhi0_cn3_resources[] = { + [0] = { + .name = "SDHI0", + .start = 0x04ce0000, + .end = 0x04ce01ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 101, + .flags = IORESOURCE_IRQ, + }, }; -static struct platform_device sdcard_cn3_device = { - .name = "spi_gpio", - .dev = { - .platform_data = &sdcard_cn3_platform_data, +static struct platform_device sdhi0_cn3_device = { + .name = "sh_mobile_sdhi", + .id = 0, /* "sdhi0" clock */ + .num_resources = ARRAY_SIZE(sdhi0_cn3_resources), + .resource = sdhi0_cn3_resources, + .archdata = { + .hwblk_id = HWBLK_SDHI0, + }, +}; + +static struct resource sdhi1_cn7_resources[] = { + [0] = { + .name = "SDHI1", + .start = 0x04cf0000, + .end = 0x04cf01ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 24, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi1_cn7_device = { + .name = "sh_mobile_sdhi", + .id = 1, /* "sdhi1" clock */ + .num_resources = ARRAY_SIZE(sdhi1_cn7_resources), + .resource = sdhi1_cn7_resources, + .archdata = { + .hwblk_id = HWBLK_SDHI1, }, }; @@ -439,13 +474,15 @@ static struct ov772x_camera_info ov7725_info = { .buswidth = SOCAM_DATAWIDTH_8, .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP, .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0), - .link = { - .bus_id = 0, - .power = ov7725_power, - .board_info = &ap325rxa_i2c_camera[0], - .i2c_adapter_id = 0, - .module_name = "ov772x", - }, +}; + +static struct soc_camera_link ov7725_link = { + .bus_id = 0, + .power = ov7725_power, + .board_info = &ap325rxa_i2c_camera[0], + .i2c_adapter_id = 0, + .module_name = "ov772x", + .priv = &ov7725_info, }; static struct platform_device ap325rxa_camera[] = { @@ -453,13 +490,13 @@ static struct platform_device ap325rxa_camera[] = { .name = "soc-camera-pdrv", .id = 0, .dev = { - .platform_data = &ov7725_info.link, + .platform_data = &ov7725_link, }, }, { .name = "soc-camera-pdrv", .id = 1, .dev = { - .platform_data = &camera_info.link, + .platform_data = &camera_link, }, }, }; @@ -470,22 +507,26 @@ static struct platform_device *ap325rxa_devices[] __initdata = { &lcdc_device, &ceu_device, &nand_flash_device, - &sdcard_cn3_device, + &sdhi0_cn3_device, + &sdhi1_cn7_device, &ap325rxa_camera[0], &ap325rxa_camera[1], }; -static struct spi_board_info ap325rxa_spi_devices[] = { - { - .modalias = "mmc_spi", - .max_speed_hz = 5000000, - .chip_select = 0, - .controller_data = (void *) GPIO_PTD5, - }, -}; +extern char ap325rxa_sdram_enter_start; +extern char ap325rxa_sdram_enter_end; +extern char ap325rxa_sdram_leave_start; +extern char ap325rxa_sdram_leave_end; static int __init ap325rxa_devices_setup(void) { + /* register board specific self-refresh code */ + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, + &ap325rxa_sdram_enter_start, + &ap325rxa_sdram_enter_end, + &ap325rxa_sdram_leave_start, + &ap325rxa_sdram_leave_end); + /* LD3 and LD4 LEDs */ gpio_request(GPIO_PTX5, NULL); /* RUN */ gpio_direction_output(GPIO_PTX5, 1); @@ -578,12 +619,28 @@ static int __init ap325rxa_devices_setup(void) platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20); + /* SDHI0 - CN3 - SD CARD */ + gpio_request(GPIO_FN_SDHI0CD_PTD, NULL); + gpio_request(GPIO_FN_SDHI0WP_PTD, NULL); + gpio_request(GPIO_FN_SDHI0D3_PTD, NULL); + gpio_request(GPIO_FN_SDHI0D2_PTD, NULL); + gpio_request(GPIO_FN_SDHI0D1_PTD, NULL); + gpio_request(GPIO_FN_SDHI0D0_PTD, NULL); + gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL); + gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL); + + /* SDHI1 - CN7 - MICRO SD CARD */ + gpio_request(GPIO_FN_SDHI1CD, NULL); + gpio_request(GPIO_FN_SDHI1D3, NULL); + gpio_request(GPIO_FN_SDHI1D2, NULL); + gpio_request(GPIO_FN_SDHI1D1, NULL); + gpio_request(GPIO_FN_SDHI1D0, NULL); + gpio_request(GPIO_FN_SDHI1CMD, NULL); + gpio_request(GPIO_FN_SDHI1CLK, NULL); + i2c_register_board_info(0, ap325rxa_i2c_devices, ARRAY_SIZE(ap325rxa_i2c_devices)); - spi_register_board_info(ap325rxa_spi_devices, - ARRAY_SIZE(ap325rxa_spi_devices)); - return platform_add_devices(ap325rxa_devices, ARRAY_SIZE(ap325rxa_devices)); } diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c index ebe99227d4e6..a4b7402d6176 100644 --- a/arch/sh/boards/mach-dreamcast/setup.c +++ b/arch/sh/boards/mach-dreamcast/setup.c @@ -42,8 +42,6 @@ static void __init dreamcast_setup(char **cmdline_p) /* Acknowledge any previous events */ /* XXX */ - __set_io_port_base(0xa0000000); - /* Assign all virtual IRQs to the System ASIC int. handler */ for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) set_irq_chip_and_handler(i, &systemasic_int, diff --git a/arch/sh/boards/mach-ecovec24/Makefile b/arch/sh/boards/mach-ecovec24/Makefile index 51f852151655..e69bc82208fc 100644 --- a/arch/sh/boards/mach-ecovec24/Makefile +++ b/arch/sh/boards/mach-ecovec24/Makefile @@ -6,4 +6,4 @@ # for more details. # -obj-y := setup.o
\ No newline at end of file +obj-y := setup.o sdram.o
\ No newline at end of file diff --git a/arch/sh/boards/mach-ecovec24/sdram.S b/arch/sh/boards/mach-ecovec24/sdram.S new file mode 100644 index 000000000000..833440044407 --- /dev/null +++ b/arch/sh/boards/mach-ecovec24/sdram.S @@ -0,0 +1,52 @@ +/* + * Ecovec24 sdram self/auto-refresh setup code + * + * Copyright (C) 2009 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/sys.h> +#include <linux/errno.h> +#include <linux/linkage.h> +#include <asm/asm-offsets.h> +#include <asm/suspend.h> +#include <asm/romimage-macros.h> + +/* code to enter and leave self-refresh. must be self-contained. + * this code will be copied to on-chip memory and executed from there. + */ + .balign 4 +ENTRY(ecovec24_sdram_enter_start) + + /* DBSC: put memory in self-refresh mode */ + + ED 0xFD000010, 0x00000000 /* DBEN */ + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ + + rts + nop + +ENTRY(ecovec24_sdram_enter_end) + + .balign 4 +ENTRY(ecovec24_sdram_leave_start) + + /* DBSC: put memory in auto-refresh mode */ + + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + WAIT 1 + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000010, 0x00000001 /* DBEN */ + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ + + rts + nop + +ENTRY(ecovec24_sdram_leave_end) diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 5f9881e16e2f..6a8861b39f05 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -18,13 +18,23 @@ #include <linux/delay.h> #include <linux/usb/r8a66597.h> #include <linux/i2c.h> +#include <linux/i2c/tsc2007.h> +#include <linux/spi/spi.h> +#include <linux/spi/sh_msiof.h> +#include <linux/spi/mmc_spi.h> +#include <linux/mmc/host.h> #include <linux/input.h> +#include <linux/input/sh_keysc.h> +#include <linux/mfd/sh_mobile_sdhi.h> #include <video/sh_mobile_lcdc.h> +#include <sound/sh_fsi.h> #include <media/sh_mobile_ceu.h> +#include <media/tw9910.h> +#include <media/mt9t112.h> #include <asm/heartbeat.h> #include <asm/sh_eth.h> -#include <asm/sh_keysc.h> #include <asm/clock.h> +#include <asm/suspend.h> #include <cpu/sh7724.h> /* @@ -38,6 +48,20 @@ * 0x1800_0000 MFI 16bit */ +/* SWITCH + *------------------------------ + * DS2[1] = FlashROM write protect ON : write protect + * OFF : No write protect + * DS2[2] = RMII / TS, SCIF ON : RMII + * OFF : TS, SCIF3 + * DS2[3] = Camera / Video ON : Camera + * OFF : NTSC/PAL (IN) + * DS2[5] = NTSC_OUT Clock ON : On board OSC + * OFF : SH7724 DV_CLK + * DS2[6-7] = MMC / SD ON-OFF : SD + * OFF-ON : MMC + */ + /* Heartbeat */ static unsigned char led_pos[] = { 0, 1, 2, 3 }; static struct heartbeat_data heartbeat_data = { @@ -70,7 +94,7 @@ static struct mtd_partition nor_flash_partitions[] = { .name = "boot loader", .offset = 0, .size = (5 * 1024 * 1024), - .mask_flags = MTD_CAP_ROM, + .mask_flags = MTD_WRITEABLE, /* force read-only */ }, { .name = "free-area", .offset = MTDPART_OFS_APPEND, @@ -104,8 +128,6 @@ static struct platform_device nor_flash_device = { /* SH Eth */ #define SH_ETH_ADDR (0xA4600000) -#define SH_ETH_MAHR (SH_ETH_ADDR + 0x1C0) -#define SH_ETH_MALR (SH_ETH_ADDR + 0x1C8) static struct resource sh_eth_resources[] = { [0] = { .start = SH_ETH_ADDR, @@ -132,6 +154,9 @@ static struct platform_device sh_eth_device = { }, .num_resources = ARRAY_SIZE(sh_eth_resources), .resource = sh_eth_resources, + .archdata = { + .hwblk_id = HWBLK_ETHER, + }, }; /* USB0 host */ @@ -170,30 +195,18 @@ static struct platform_device usb0_host_device = { .resource = usb0_host_resources, }; -/* - * USB1 - * - * CN5 can use both host/function, - * and we can determine it by checking PTB[3] - * - * This time only USB1 host is supported. - */ +/* USB1 host/function */ void usb1_port_power(int port, int power) { - if (!gpio_get_value(GPIO_PTB3)) { - printk(KERN_ERR "USB1 function is not supported\n"); - return; - } - gpio_set_value(GPIO_PTB5, power); } -static struct r8a66597_platdata usb1_host_data = { +static struct r8a66597_platdata usb1_common_data = { .on_chip = 1, .port_power = usb1_port_power, }; -static struct resource usb1_host_resources[] = { +static struct resource usb1_common_resources[] = { [0] = { .start = 0xa4d90000, .end = 0xa4d90124 - 1, @@ -206,16 +219,16 @@ static struct resource usb1_host_resources[] = { }, }; -static struct platform_device usb1_host_device = { - .name = "r8a66597_hcd", +static struct platform_device usb1_common_device = { + /* .name will be added in arch_setup */ .id = 1, .dev = { .dma_mask = NULL, /* not use dma */ .coherent_dma_mask = 0xffffffff, - .platform_data = &usb1_host_data, + .platform_data = &usb1_common_data, }, - .num_resources = ARRAY_SIZE(usb1_host_resources), - .resource = usb1_host_resources, + .num_resources = ARRAY_SIZE(usb1_common_resources), + .resource = usb1_common_resources, }; /* LCDC */ @@ -330,6 +343,12 @@ static struct platform_device ceu1_device = { }; /* I2C device */ +static struct i2c_board_info i2c0_devices[] = { + { + I2C_BOARD_INFO("da7210", 0x1a), + }, +}; + static struct i2c_board_info i2c1_devices[] = { { I2C_BOARD_INFO("r2025sd", 0x32), @@ -376,16 +395,380 @@ static struct platform_device keysc_device = { }, }; +/* TouchScreen */ +#define IRQ0 32 +static int ts_get_pendown_state(void) +{ + int val = 0; + gpio_free(GPIO_FN_INTC_IRQ0); + gpio_request(GPIO_PTZ0, NULL); + gpio_direction_input(GPIO_PTZ0); + + val = gpio_get_value(GPIO_PTZ0); + + gpio_free(GPIO_PTZ0); + gpio_request(GPIO_FN_INTC_IRQ0, NULL); + + return val ? 0 : 1; +} + +static int ts_init(void) +{ + gpio_request(GPIO_FN_INTC_IRQ0, NULL); + return 0; +} + +struct tsc2007_platform_data tsc2007_info = { + .model = 2007, + .x_plate_ohms = 180, + .get_pendown_state = ts_get_pendown_state, + .init_platform_hw = ts_init, +}; + +static struct i2c_board_info ts_i2c_clients = { + I2C_BOARD_INFO("tsc2007", 0x48), + .type = "tsc2007", + .platform_data = &tsc2007_info, + .irq = IRQ0, +}; + +#ifdef CONFIG_MFD_SH_MOBILE_SDHI +/* SHDI0 */ +static void sdhi0_set_pwr(struct platform_device *pdev, int state) +{ + gpio_set_value(GPIO_PTB6, state); +} + +static struct sh_mobile_sdhi_info sdhi0_info = { + .set_pwr = sdhi0_set_pwr, +}; + +static struct resource sdhi0_resources[] = { + [0] = { + .name = "SDHI0", + .start = 0x04ce0000, + .end = 0x04ce01ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 101, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi0_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi0_resources), + .resource = sdhi0_resources, + .id = 0, + .dev = { + .platform_data = &sdhi0_info, + }, + .archdata = { + .hwblk_id = HWBLK_SDHI0, + }, +}; + +/* SHDI1 */ +static void sdhi1_set_pwr(struct platform_device *pdev, int state) +{ + gpio_set_value(GPIO_PTB7, state); +} + +static struct sh_mobile_sdhi_info sdhi1_info = { + .set_pwr = sdhi1_set_pwr, +}; + +static struct resource sdhi1_resources[] = { + [0] = { + .name = "SDHI1", + .start = 0x04cf0000, + .end = 0x04cf01ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 24, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi1_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi1_resources), + .resource = sdhi1_resources, + .id = 1, + .dev = { + .platform_data = &sdhi1_info, + }, + .archdata = { + .hwblk_id = HWBLK_SDHI1, + }, +}; + +#else + +/* MMC SPI */ +static int mmc_spi_get_ro(struct device *dev) +{ + return gpio_get_value(GPIO_PTY6); +} + +static int mmc_spi_get_cd(struct device *dev) +{ + return !gpio_get_value(GPIO_PTY7); +} + +static void mmc_spi_setpower(struct device *dev, unsigned int maskval) +{ + gpio_set_value(GPIO_PTB6, maskval ? 1 : 0); +} + +static struct mmc_spi_platform_data mmc_spi_info = { + .get_ro = mmc_spi_get_ro, + .get_cd = mmc_spi_get_cd, + .caps = MMC_CAP_NEEDS_POLL, + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* 3.3V only */ + .setpower = mmc_spi_setpower, +}; + +static struct spi_board_info spi_bus[] = { + { + .modalias = "mmc_spi", + .platform_data = &mmc_spi_info, + .max_speed_hz = 5000000, + .mode = SPI_MODE_0, + .controller_data = (void *) GPIO_PTM4, + }, +}; + +/* MSIOF0 */ +static struct sh_msiof_spi_info msiof0_data = { + .num_chipselect = 1, +}; + +static struct resource msiof0_resources[] = { + [0] = { + .name = "MSIOF0", + .start = 0xa4c40000, + .end = 0xa4c40063, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 84, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device msiof0_device = { + .name = "spi_sh_msiof", + .id = 0, /* MSIOF0 */ + .dev = { + .platform_data = &msiof0_data, + }, + .num_resources = ARRAY_SIZE(msiof0_resources), + .resource = msiof0_resources, + .archdata = { + .hwblk_id = HWBLK_MSIOF0, + }, +}; + +#endif + +/* I2C Video/Camera */ +static struct i2c_board_info i2c_camera[] = { + { + I2C_BOARD_INFO("tw9910", 0x45), + }, + { + /* 1st camera */ + I2C_BOARD_INFO("mt9t112", 0x3c), + }, + { + /* 2nd camera */ + I2C_BOARD_INFO("mt9t112", 0x3c), + }, +}; + +/* tw9910 */ +static int tw9910_power(struct device *dev, int mode) +{ + int val = mode ? 0 : 1; + + gpio_set_value(GPIO_PTU2, val); + if (mode) + mdelay(100); + + return 0; +} + +static struct tw9910_video_info tw9910_info = { + .buswidth = SOCAM_DATAWIDTH_8, + .mpout = TW9910_MPO_FIELD, +}; + +static struct soc_camera_link tw9910_link = { + .i2c_adapter_id = 0, + .bus_id = 1, + .power = tw9910_power, + .board_info = &i2c_camera[0], + .module_name = "tw9910", + .priv = &tw9910_info, +}; + +/* mt9t112 */ +static int mt9t112_power1(struct device *dev, int mode) +{ + gpio_set_value(GPIO_PTA3, mode); + if (mode) + mdelay(100); + + return 0; +} + +static struct mt9t112_camera_info mt9t112_info1 = { + .flags = MT9T112_FLAG_PCLK_RISING_EDGE | MT9T112_FLAG_DATAWIDTH_8, + .divider = { 0x49, 0x6, 0, 6, 0, 9, 9, 6, 0 }, /* for 24MHz */ +}; + +static struct soc_camera_link mt9t112_link1 = { + .i2c_adapter_id = 0, + .power = mt9t112_power1, + .bus_id = 0, + .board_info = &i2c_camera[1], + .module_name = "mt9t112", + .priv = &mt9t112_info1, +}; + +static int mt9t112_power2(struct device *dev, int mode) +{ + gpio_set_value(GPIO_PTA4, mode); + if (mode) + mdelay(100); + + return 0; +} + +static struct mt9t112_camera_info mt9t112_info2 = { + .flags = MT9T112_FLAG_PCLK_RISING_EDGE | MT9T112_FLAG_DATAWIDTH_8, + .divider = { 0x49, 0x6, 0, 6, 0, 9, 9, 6, 0 }, /* for 24MHz */ +}; + +static struct soc_camera_link mt9t112_link2 = { + .i2c_adapter_id = 1, + .power = mt9t112_power2, + .bus_id = 1, + .board_info = &i2c_camera[2], + .module_name = "mt9t112", + .priv = &mt9t112_info2, +}; + +static struct platform_device camera_devices[] = { + { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &tw9910_link, + }, + }, + { + .name = "soc-camera-pdrv", + .id = 1, + .dev = { + .platform_data = &mt9t112_link1, + }, + }, + { + .name = "soc-camera-pdrv", + .id = 2, + .dev = { + .platform_data = &mt9t112_link2, + }, + }, +}; + +/* FSI */ +/* + * FSI-B use external clock which came from da7210. + * So, we should change parent of fsi + */ +#define FCLKBCR 0xa415000c +static void fsimck_init(struct clk *clk) +{ + u32 status = ctrl_inl(clk->enable_reg); + + /* use external clock */ + status &= ~0x000000ff; + status |= 0x00000080; + + ctrl_outl(status, clk->enable_reg); +} + +static struct clk_ops fsimck_clk_ops = { + .init = fsimck_init, +}; + +static struct clk fsimckb_clk = { + .name = "fsimckb_clk", + .id = -1, + .ops = &fsimck_clk_ops, + .enable_reg = (void __iomem *)FCLKBCR, + .rate = 0, /* unknown */ +}; + +struct sh_fsi_platform_info fsi_info = { + .portb_flags = SH_FSI_BRS_INV | + SH_FSI_OUT_SLAVE_MODE | + SH_FSI_IN_SLAVE_MODE | + SH_FSI_OFMT(I2S) | + SH_FSI_IFMT(I2S), +}; + +static struct resource fsi_resources[] = { + [0] = { + .name = "FSI", + .start = 0xFE3C0000, + .end = 0xFE3C021d, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 108, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device fsi_device = { + .name = "sh_fsi", + .id = 0, + .num_resources = ARRAY_SIZE(fsi_resources), + .resource = fsi_resources, + .dev = { + .platform_data = &fsi_info, + }, + .archdata = { + .hwblk_id = HWBLK_SPU, /* FSI needs SPU hwblk */ + }, +}; + static struct platform_device *ecovec_devices[] __initdata = { &heartbeat_device, &nor_flash_device, &sh_eth_device, &usb0_host_device, - &usb1_host_device, /* USB1 host support */ + &usb1_common_device, &lcdc_device, &ceu0_device, &ceu1_device, &keysc_device, +#ifdef CONFIG_MFD_SH_MOBILE_SDHI + &sdhi0_device, + &sdhi1_device, +#else + &msiof0_device, +#endif + &camera_devices[0], + &camera_devices[1], + &camera_devices[2], + &fsi_device, }; #define EEPROM_ADDR 0x50 @@ -414,12 +797,9 @@ static u8 mac_read(struct i2c_adapter *a, u8 command) return buf; } -#define MAC_LEN 6 -static void __init sh_eth_init(void) +static void __init sh_eth_init(struct sh_eth_plat_data *pd) { struct i2c_adapter *a = i2c_get_adapter(1); - struct clk *eth_clk; - u8 mac[MAC_LEN]; int i; if (!a) { @@ -427,39 +807,37 @@ static void __init sh_eth_init(void) return; } - eth_clk = clk_get(NULL, "eth0"); - if (!eth_clk) { - pr_err("can not get eth0 clk\n"); - return; - } - /* read MAC address frome EEPROM */ - for (i = 0; i < MAC_LEN; i++) { - mac[i] = mac_read(a, 0x10 + i); + for (i = 0; i < sizeof(pd->mac_addr); i++) { + pd->mac_addr[i] = mac_read(a, 0x10 + i); msleep(10); } - - /* clock enable */ - clk_enable(eth_clk); - - /* reset sh-eth */ - ctrl_outl(0x1, SH_ETH_ADDR + 0x0); - - /* set MAC addr */ - ctrl_outl((mac[0] << 24) | - (mac[1] << 16) | - (mac[2] << 8) | - (mac[3] << 0), SH_ETH_MAHR); - ctrl_outl((mac[4] << 8) | - (mac[5] << 0), SH_ETH_MALR); - - clk_put(eth_clk); } #define PORT_HIZA 0xA4050158 #define IODRIVEA 0xA405018A + +extern char ecovec24_sdram_enter_start; +extern char ecovec24_sdram_enter_end; +extern char ecovec24_sdram_leave_start; +extern char ecovec24_sdram_leave_end; + static int __init arch_setup(void) { + struct clk *clk; + + /* register board specific self-refresh code */ + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, + &ecovec24_sdram_enter_start, + &ecovec24_sdram_enter_end, + &ecovec24_sdram_leave_start, + &ecovec24_sdram_leave_end); + + /* enable STATUS0, STATUS2 and PDSTATUS */ + gpio_request(GPIO_FN_STATUS0, NULL); + gpio_request(GPIO_FN_STATUS2, NULL); + gpio_request(GPIO_FN_PDSTATUS, NULL); + /* enable SCIFA0 */ gpio_request(GPIO_FN_SCIF0_TXD, NULL); gpio_request(GPIO_FN_SCIF0_RXD, NULL); @@ -504,6 +882,14 @@ static int __init arch_setup(void) ctrl_outw(0x0600, 0xa40501d4); ctrl_outw(0x0600, 0xa4050192); + if (gpio_get_value(GPIO_PTB3)) { + printk(KERN_INFO "USB1 function is selected\n"); + usb1_common_device.name = "r8a66597_udc"; + } else { + printk(KERN_INFO "USB1 host is selected\n"); + usb1_common_device.name = "r8a66597_hcd"; + } + /* enable LCDC */ gpio_request(GPIO_FN_LCDD23, NULL); gpio_request(GPIO_FN_LCDD22, NULL); @@ -546,8 +932,8 @@ static int __init arch_setup(void) gpio_direction_output(GPIO_PTR1, 0); gpio_direction_output(GPIO_PTA2, 0); - /* I/O buffer drive ability is low */ - ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0040 , IODRIVEA); + /* I/O buffer drive ability is high */ + ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA); if (gpio_get_value(GPIO_PTE6)) { /* DVI */ @@ -590,6 +976,10 @@ static int __init arch_setup(void) */ gpio_request(GPIO_PTF4, NULL); gpio_direction_output(GPIO_PTF4, 1); + + /* enable TouchScreen */ + i2c_register_board_info(0, &ts_i2c_clients, 1); + set_irq_type(IRQ0, IRQ_TYPE_LEVEL_LOW); } /* enable CEU0 */ @@ -649,7 +1039,86 @@ static int __init arch_setup(void) gpio_direction_input(GPIO_PTR5); gpio_direction_input(GPIO_PTR6); +#ifdef CONFIG_MFD_SH_MOBILE_SDHI + /* enable SDHI0 on CN11 (needs DS2.4 set to ON) */ + gpio_request(GPIO_FN_SDHI0CD, NULL); + gpio_request(GPIO_FN_SDHI0WP, NULL); + gpio_request(GPIO_FN_SDHI0CMD, NULL); + gpio_request(GPIO_FN_SDHI0CLK, NULL); + gpio_request(GPIO_FN_SDHI0D3, NULL); + gpio_request(GPIO_FN_SDHI0D2, NULL); + gpio_request(GPIO_FN_SDHI0D1, NULL); + gpio_request(GPIO_FN_SDHI0D0, NULL); + gpio_request(GPIO_PTB6, NULL); + gpio_direction_output(GPIO_PTB6, 0); + + /* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */ + gpio_request(GPIO_FN_SDHI1CD, NULL); + gpio_request(GPIO_FN_SDHI1WP, NULL); + gpio_request(GPIO_FN_SDHI1CMD, NULL); + gpio_request(GPIO_FN_SDHI1CLK, NULL); + gpio_request(GPIO_FN_SDHI1D3, NULL); + gpio_request(GPIO_FN_SDHI1D2, NULL); + gpio_request(GPIO_FN_SDHI1D1, NULL); + gpio_request(GPIO_FN_SDHI1D0, NULL); + gpio_request(GPIO_PTB7, NULL); + gpio_direction_output(GPIO_PTB7, 0); + + /* I/O buffer drive ability is high for SDHI1 */ + ctrl_outw((ctrl_inw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA); +#else + /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ + gpio_request(GPIO_FN_MSIOF0_TXD, NULL); + gpio_request(GPIO_FN_MSIOF0_RXD, NULL); + gpio_request(GPIO_FN_MSIOF0_TSCK, NULL); + gpio_request(GPIO_PTM4, NULL); /* software CS control of TSYNC pin */ + gpio_direction_output(GPIO_PTM4, 1); /* active low CS */ + gpio_request(GPIO_PTB6, NULL); /* 3.3V power control */ + gpio_direction_output(GPIO_PTB6, 0); /* disable power by default */ + gpio_request(GPIO_PTY6, NULL); /* write protect */ + gpio_direction_input(GPIO_PTY6); + gpio_request(GPIO_PTY7, NULL); /* card detect */ + gpio_direction_input(GPIO_PTY7); + + spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus)); +#endif + + /* enable Video */ + gpio_request(GPIO_PTU2, NULL); + gpio_direction_output(GPIO_PTU2, 1); + + /* enable Camera */ + gpio_request(GPIO_PTA3, NULL); + gpio_request(GPIO_PTA4, NULL); + gpio_direction_output(GPIO_PTA3, 0); + gpio_direction_output(GPIO_PTA4, 0); + + /* enable FSI */ + gpio_request(GPIO_FN_FSIMCKB, NULL); + gpio_request(GPIO_FN_FSIIBSD, NULL); + gpio_request(GPIO_FN_FSIOBSD, NULL); + gpio_request(GPIO_FN_FSIIBBCK, NULL); + gpio_request(GPIO_FN_FSIIBLRCK, NULL); + gpio_request(GPIO_FN_FSIOBBCK, NULL); + gpio_request(GPIO_FN_FSIOBLRCK, NULL); + gpio_request(GPIO_FN_CLKAUDIOBO, NULL); + + /* change parent of FSI B */ + clk = clk_get(NULL, "fsib_clk"); + clk_register(&fsimckb_clk); + clk_set_parent(clk, &fsimckb_clk); + clk_set_rate(clk, 11000); + clk_set_rate(&fsimckb_clk, 11000); + clk_put(clk); + + gpio_request(GPIO_PTU0, NULL); + gpio_direction_output(GPIO_PTU0, 0); + mdelay(20); + /* enable I2C device */ + i2c_register_board_info(0, i2c0_devices, + ARRAY_SIZE(i2c0_devices)); + i2c_register_board_info(1, i2c1_devices, ARRAY_SIZE(i2c1_devices)); @@ -660,12 +1129,11 @@ arch_initcall(arch_setup); static int __init devices_setup(void) { - sh_eth_init(); + sh_eth_init(&sh_eth_plat); return 0; } device_initcall(devices_setup); - static struct sh_machine_vector mv_ecovec __initmv = { .mv_name = "R0P7724 (EcoVec)", }; diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c index 566e69d8d729..f663c14d8885 100644 --- a/arch/sh/boards/mach-highlander/setup.c +++ b/arch/sh/boards/mach-highlander/setup.c @@ -384,7 +384,7 @@ static unsigned char irl2irq[HL_NR_IRL]; static int highlander_irq_demux(int irq) { - if (irq >= HL_NR_IRL || !irl2irq[irq]) + if (irq >= HL_NR_IRL || irq < 0 || !irl2irq[irq]) return irq; return irl2irq[irq]; diff --git a/arch/sh/boards/mach-hp6xx/setup.c b/arch/sh/boards/mach-hp6xx/setup.c index 8f305b36358b..e6dd5e96321e 100644 --- a/arch/sh/boards/mach-hp6xx/setup.c +++ b/arch/sh/boards/mach-hp6xx/setup.c @@ -13,6 +13,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/irq.h> +#include <sound/sh_dac_audio.h> #include <asm/hd64461.h> #include <asm/io.h> #include <mach/hp6xx.h> @@ -51,9 +52,63 @@ static struct platform_device jornadakbd_device = { .id = -1, }; +static void dac_audio_start(struct dac_audio_pdata *pdata) +{ + u16 v; + u8 v8; + + /* HP Jornada 680/690 speaker on */ + v = inw(HD64461_GPADR); + v &= ~HD64461_GPADR_SPEAKER; + outw(v, HD64461_GPADR); + + /* HP Palmtop 620lx/660lx speaker on */ + v8 = inb(PKDR); + v8 &= ~PKDR_SPEAKER; + outb(v8, PKDR); + + sh_dac_enable(pdata->channel); +} + +static void dac_audio_stop(struct dac_audio_pdata *pdata) +{ + u16 v; + u8 v8; + + /* HP Jornada 680/690 speaker off */ + v = inw(HD64461_GPADR); + v |= HD64461_GPADR_SPEAKER; + outw(v, HD64461_GPADR); + + /* HP Palmtop 620lx/660lx speaker off */ + v8 = inb(PKDR); + v8 |= PKDR_SPEAKER; + outb(v8, PKDR); + + sh_dac_output(0, pdata->channel); + sh_dac_disable(pdata->channel); +} + +static struct dac_audio_pdata dac_audio_platform_data = { + .buffer_size = 64000, + .channel = 1, + .start = dac_audio_start, + .stop = dac_audio_stop, +}; + +static struct platform_device dac_audio_device = { + .name = "dac_audio", + .id = -1, + .dev = { + .platform_data = &dac_audio_platform_data, + } + +}; + static struct platform_device *hp6xx_devices[] __initdata = { &cf_ide_device, &jornadakbd_device, + &dac_audio_device, }; static void __init hp6xx_init_irq(void) diff --git a/arch/sh/boards/mach-kfr2r09/Makefile b/arch/sh/boards/mach-kfr2r09/Makefile index 5d5867826e3b..4e577a3bf658 100644 --- a/arch/sh/boards/mach-kfr2r09/Makefile +++ b/arch/sh/boards/mach-kfr2r09/Makefile @@ -1,2 +1,2 @@ -obj-y := setup.o +obj-y := setup.o sdram.o obj-$(CONFIG_FB_SH_MOBILE_LCDC) += lcd_wqvga.o diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c index 8ccb1cc8b589..e9b970846c41 100644 --- a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c +++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c @@ -273,6 +273,12 @@ int kfr2r09_lcd_setup(void *board_data, void *sohandle, return 0; } +void kfr2r09_lcd_start(void *board_data, void *sohandle, + struct sh_mobile_lcdc_sys_bus_ops *so) +{ + write_memory_start(sohandle, so); +} + #define CTRL_CKSW 0x10 #define CTRL_C10 0x20 #define CTRL_CPSW 0x80 diff --git a/arch/sh/boards/mach-kfr2r09/sdram.S b/arch/sh/boards/mach-kfr2r09/sdram.S new file mode 100644 index 000000000000..0c9f55bec2fe --- /dev/null +++ b/arch/sh/boards/mach-kfr2r09/sdram.S @@ -0,0 +1,80 @@ +/* + * KFR2R09 sdram self/auto-refresh setup code + * + * Copyright (C) 2009 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/sys.h> +#include <linux/errno.h> +#include <linux/linkage.h> +#include <asm/asm-offsets.h> +#include <asm/suspend.h> +#include <asm/romimage-macros.h> + +/* code to enter and leave self-refresh. must be self-contained. + * this code will be copied to on-chip memory and executed from there. + */ + .balign 4 +ENTRY(kfr2r09_sdram_enter_start) + + /* DBSC: put memory in self-refresh mode */ + + ED 0xFD000010, 0x00000000 /* DBEN */ + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ + + rts + nop + +ENTRY(kfr2r09_sdram_enter_end) + + .balign 4 +ENTRY(kfr2r09_sdram_leave_start) + + /* DBSC: put memory in auto-refresh mode */ + + mov.l @(SH_SLEEP_MODE, r5), r0 + tst #SUSP_SH_RSTANDBY, r0 + bf resume_rstandby + + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + WAIT 1 + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000010, 0x00000001 /* DBEN */ + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ + + rts + nop + +resume_rstandby: + + /* DBSC: re-initialize and put in auto-refresh */ + + ED 0xFD000108, 0x40000301 /* DBPDCNT0 */ + ED 0xFD000020, 0x011B0002 /* DBCONF */ + ED 0xFD000030, 0x03060E02 /* DBTR0 */ + ED 0xFD000034, 0x01020102 /* DBTR1 */ + ED 0xFD000038, 0x01090406 /* DBTR2 */ + ED 0xFD000008, 0x00000004 /* DBKIND */ + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + ED 0xFD000018, 0x00000001 /* DBCKECNT */ + WAIT 1 + ED 0xFD000010, 0x00000001 /* DBEN */ + ED 0xFD000044, 0x000004AF /* DBRFPDN1 */ + ED 0xFD000048, 0x20CF0037 /* DBRFPDN2 */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000108, 0x40000300 /* DBPDCNT0 */ + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ + + rts + nop + +ENTRY(kfr2r09_sdram_leave_end) diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index c08d33fe2104..5d7b5d92475e 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -16,13 +16,17 @@ #include <linux/clk.h> #include <linux/gpio.h> #include <linux/input.h> +#include <linux/input/sh_keysc.h> #include <linux/i2c.h> #include <linux/usb/r8a66597.h> +#include <media/rj54n1cb0c.h> +#include <media/soc_camera.h> +#include <media/sh_mobile_ceu.h> #include <video/sh_mobile_lcdc.h> +#include <asm/suspend.h> #include <asm/clock.h> #include <asm/machvec.h> #include <asm/io.h> -#include <asm/sh_keysc.h> #include <cpu/sh7724.h> #include <mach/kfr2r09.h> @@ -146,6 +150,7 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = { }, .board_cfg = { .setup_sys = kfr2r09_lcd_setup, + .start_transfer = kfr2r09_lcd_start, .display_on = kfr2r09_lcd_on, .display_off = kfr2r09_lcd_off, }, @@ -212,11 +217,162 @@ static struct platform_device kfr2r09_usb0_gadget_device = { .resource = kfr2r09_usb0_gadget_resources, }; +static struct sh_mobile_ceu_info sh_mobile_ceu_info = { + .flags = SH_CEU_FLAG_USE_8BIT_BUS, +}; + +static struct resource kfr2r09_ceu_resources[] = { + [0] = { + .name = "CEU", + .start = 0xfe910000, + .end = 0xfe91009f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 52, + .end = 52, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* place holder for contiguous memory */ + }, +}; + +static struct platform_device kfr2r09_ceu_device = { + .name = "sh_mobile_ceu", + .id = 0, /* "ceu0" clock */ + .num_resources = ARRAY_SIZE(kfr2r09_ceu_resources), + .resource = kfr2r09_ceu_resources, + .dev = { + .platform_data = &sh_mobile_ceu_info, + }, + .archdata = { + .hwblk_id = HWBLK_CEU0, + }, +}; + +static struct i2c_board_info kfr2r09_i2c_camera = { + I2C_BOARD_INFO("rj54n1cb0c", 0x50), +}; + +static struct clk *camera_clk; + +/* set VIO_CKO clock to 25MHz */ +#define CEU_MCLK_FREQ 25000000 + +#define DRVCRB 0xA405018C +static int camera_power(struct device *dev, int mode) +{ + int ret; + + if (mode) { + long rate; + + camera_clk = clk_get(NULL, "video_clk"); + if (IS_ERR(camera_clk)) + return PTR_ERR(camera_clk); + + rate = clk_round_rate(camera_clk, CEU_MCLK_FREQ); + ret = clk_set_rate(camera_clk, rate); + if (ret < 0) + goto eclkrate; + + /* set DRVCRB + * + * use 1.8 V for VccQ_VIO + * use 2.85V for VccQ_SR + */ + ctrl_outw((ctrl_inw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB); + + /* reset clear */ + ret = gpio_request(GPIO_PTB4, NULL); + if (ret < 0) + goto eptb4; + ret = gpio_request(GPIO_PTB7, NULL); + if (ret < 0) + goto eptb7; + + ret = gpio_direction_output(GPIO_PTB4, 1); + if (!ret) + ret = gpio_direction_output(GPIO_PTB7, 1); + if (ret < 0) + goto egpioout; + msleep(1); + + ret = clk_enable(camera_clk); /* start VIO_CKO */ + if (ret < 0) + goto eclkon; + + return 0; + } + + ret = 0; + + clk_disable(camera_clk); +eclkon: + gpio_set_value(GPIO_PTB7, 0); +egpioout: + gpio_set_value(GPIO_PTB4, 0); + gpio_free(GPIO_PTB7); +eptb7: + gpio_free(GPIO_PTB4); +eptb4: +eclkrate: + clk_put(camera_clk); + return ret; +} + +static struct rj54n1_pdata rj54n1_priv = { + .mclk_freq = CEU_MCLK_FREQ, + .ioctl_high = false, +}; + +static struct soc_camera_link rj54n1_link = { + .power = camera_power, + .board_info = &kfr2r09_i2c_camera, + .i2c_adapter_id = 1, + .module_name = "rj54n1cb0c", + .priv = &rj54n1_priv, +}; + +static struct platform_device kfr2r09_camera = { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .platform_data = &rj54n1_link, + }, +}; + +static struct resource kfr2r09_sh_sdhi0_resources[] = { + [0] = { + .name = "SDHI0", + .start = 0x04ce0000, + .end = 0x04ce01ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 101, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device kfr2r09_sh_sdhi0_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(kfr2r09_sh_sdhi0_resources), + .resource = kfr2r09_sh_sdhi0_resources, + .archdata = { + .hwblk_id = HWBLK_SDHI0, + }, +}; + static struct platform_device *kfr2r09_devices[] __initdata = { &kfr2r09_nor_flash_device, &kfr2r09_nand_flash_device, &kfr2r09_sh_keysc_device, &kfr2r09_sh_lcdc_device, + &kfr2r09_ceu_device, + &kfr2r09_camera, + &kfr2r09_sh_sdhi0_device, }; #define BSC_CS0BCR 0xfec10004 @@ -268,11 +424,59 @@ static int kfr2r09_usb0_gadget_i2c_setup(void) return 0; } + +static int kfr2r09_serial_i2c_setup(void) +{ + struct i2c_adapter *a; + struct i2c_msg msg; + unsigned char buf[2]; + int ret; + + a = i2c_get_adapter(0); + if (!a) + return -ENODEV; + + /* set bit 6 (the 7th bit) of chip at 0x09, register 0x13 */ + buf[0] = 0x13; + msg.addr = 0x09; + msg.buf = buf; + msg.len = 1; + msg.flags = 0; + ret = i2c_transfer(a, &msg, 1); + if (ret != 1) + return -ENODEV; + + buf[0] = 0; + msg.addr = 0x09; + msg.buf = buf; + msg.len = 1; + msg.flags = I2C_M_RD; + ret = i2c_transfer(a, &msg, 1); + if (ret != 1) + return -ENODEV; + + buf[1] = buf[0] | (1 << 6); + buf[0] = 0x13; + msg.addr = 0x09; + msg.buf = buf; + msg.len = 2; + msg.flags = 0; + ret = i2c_transfer(a, &msg, 1); + if (ret != 1) + return -ENODEV; + + return 0; +} #else static int kfr2r09_usb0_gadget_i2c_setup(void) { return -ENODEV; } + +static int kfr2r09_serial_i2c_setup(void) +{ + return -ENODEV; +} #endif static int kfr2r09_usb0_gadget_setup(void) @@ -299,11 +503,27 @@ static int kfr2r09_usb0_gadget_setup(void) return 0; } +extern char kfr2r09_sdram_enter_start; +extern char kfr2r09_sdram_enter_end; +extern char kfr2r09_sdram_leave_start; +extern char kfr2r09_sdram_leave_end; + static int __init kfr2r09_devices_setup(void) { + /* register board specific self-refresh code */ + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF | + SUSP_SH_RSTANDBY, + &kfr2r09_sdram_enter_start, + &kfr2r09_sdram_enter_end, + &kfr2r09_sdram_leave_start, + &kfr2r09_sdram_leave_end); + /* enable SCIF1 serial port for YC401 console support */ gpio_request(GPIO_FN_SCIF1_RXD, NULL); gpio_request(GPIO_FN_SCIF1_TXD, NULL); + kfr2r09_serial_i2c_setup(); /* ECONTMSK(bit6=L10ONEN) set 1 */ + gpio_request(GPIO_PTG3, NULL); /* HPON_ON */ + gpio_direction_output(GPIO_PTG3, 1); /* HPON_ON = H */ /* setup NOR flash at CS0 */ ctrl_outl(0x36db0400, BSC_CS0BCR); @@ -361,6 +581,32 @@ static int __init kfr2r09_devices_setup(void) if (kfr2r09_usb0_gadget_setup() == 0) platform_device_register(&kfr2r09_usb0_gadget_device); + /* CEU */ + gpio_request(GPIO_FN_VIO_CKO, NULL); + gpio_request(GPIO_FN_VIO0_CLK, NULL); + gpio_request(GPIO_FN_VIO0_VD, NULL); + gpio_request(GPIO_FN_VIO0_HD, NULL); + gpio_request(GPIO_FN_VIO0_FLD, NULL); + gpio_request(GPIO_FN_VIO0_D7, NULL); + gpio_request(GPIO_FN_VIO0_D6, NULL); + gpio_request(GPIO_FN_VIO0_D5, NULL); + gpio_request(GPIO_FN_VIO0_D4, NULL); + gpio_request(GPIO_FN_VIO0_D3, NULL); + gpio_request(GPIO_FN_VIO0_D2, NULL); + gpio_request(GPIO_FN_VIO0_D1, NULL); + gpio_request(GPIO_FN_VIO0_D0, NULL); + + platform_resource_setup_memory(&kfr2r09_ceu_device, "ceu", 4 << 20); + + /* SDHI0 connected to yc304 */ + gpio_request(GPIO_FN_SDHI0CD, NULL); + gpio_request(GPIO_FN_SDHI0D3, NULL); + gpio_request(GPIO_FN_SDHI0D2, NULL); + gpio_request(GPIO_FN_SDHI0D1, NULL); + gpio_request(GPIO_FN_SDHI0D0, NULL); + gpio_request(GPIO_FN_SDHI0CMD, NULL); + gpio_request(GPIO_FN_SDHI0CLK, NULL); + return platform_add_devices(kfr2r09_devices, ARRAY_SIZE(kfr2r09_devices)); } diff --git a/arch/sh/boards/mach-landisk/gio.c b/arch/sh/boards/mach-landisk/gio.c index 25cdf7358000..528013188196 100644 --- a/arch/sh/boards/mach-landisk/gio.c +++ b/arch/sh/boards/mach-landisk/gio.c @@ -14,7 +14,6 @@ */ #include <linux/module.h> #include <linux/init.h> -#include <linux/smp_lock.h> #include <linux/kdev_t.h> #include <linux/cdev.h> #include <linux/fs.h> @@ -35,7 +34,7 @@ static int gio_open(struct inode *inode, struct file *filp) int minor; int ret = -ENOENT; - lock_kernel(); + preempt_disable(); minor = MINOR(inode->i_rdev); if (minor < DEVCOUNT) { if (openCnt > 0) { @@ -45,7 +44,7 @@ static int gio_open(struct inode *inode, struct file *filp) ret = 0; } } - unlock_kernel(); + preempt_enable(); return ret; } @@ -60,8 +59,7 @@ static int gio_close(struct inode *inode, struct file *filp) return 0; } -static int gio_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static long gio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { unsigned int data; static unsigned int addr = 0; @@ -129,7 +127,7 @@ static const struct file_operations gio_fops = { .owner = THIS_MODULE, .open = gio_open, /* open */ .release = gio_close, /* release */ - .ioctl = gio_ioctl, /* ioctl */ + .unlocked_ioctl = gio_ioctl, }; static int __init gio_init(void) diff --git a/arch/sh/boards/mach-migor/Makefile b/arch/sh/boards/mach-migor/Makefile index 5f231dd25c0e..4601a89e5ac7 100644 --- a/arch/sh/boards/mach-migor/Makefile +++ b/arch/sh/boards/mach-migor/Makefile @@ -1,2 +1,2 @@ -obj-y := setup.o +obj-y := setup.o sdram.o obj-$(CONFIG_SH_MIGOR_QVGA) += lcd_qvga.o diff --git a/arch/sh/boards/mach-migor/sdram.S b/arch/sh/boards/mach-migor/sdram.S new file mode 100644 index 000000000000..614aa3a1398c --- /dev/null +++ b/arch/sh/boards/mach-migor/sdram.S @@ -0,0 +1,69 @@ +/* + * Migo-R sdram self/auto-refresh setup code + * + * Copyright (C) 2009 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/sys.h> +#include <linux/errno.h> +#include <linux/linkage.h> +#include <asm/asm-offsets.h> +#include <asm/suspend.h> +#include <asm/romimage-macros.h> + +/* code to enter and leave self-refresh. must be self-contained. + * this code will be copied to on-chip memory and executed from there. + */ + .balign 4 +ENTRY(migor_sdram_enter_start) + + /* SBSC: disable power down and put in self-refresh mode */ + mov.l 1f, r4 + mov.l 2f, r1 + mov.l @r4, r2 + or r1, r2 + mov.l 3f, r3 + and r3, r2 + mov.l r2, @r4 + + rts + nop + + .balign 4 +1: .long 0xfe400008 /* SDCR0 */ +2: .long 0x00000400 +3: .long 0xffff7fff +ENTRY(migor_sdram_enter_end) + + .balign 4 +ENTRY(migor_sdram_leave_start) + + /* SBSC: set auto-refresh mode */ + mov.l 1f, r4 + mov.l @r4, r0 + mov.l 4f, r1 + and r1, r0 + mov.l r0, @r4 + mov.l 6f, r4 + mov.l 8f, r0 + mov.l @r4, r1 + mov #-1, r4 + add r4, r1 + or r1, r0 + mov.l 7f, r1 + mov.l r0, @r1 + + rts + nop + + .balign 4 +1: .long 0xfe400008 /* SDCR0 */ +4: .long 0xfffffbff +6: .long 0xfe40001c /* RTCOR */ +7: .long 0xfe400018 /* RTCNT */ +8: .long 0xa55a0000 +ENTRY(migor_sdram_leave_end) diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 6ed1fd32369e..507c77be476d 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -11,6 +11,7 @@ #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/input.h> +#include <linux/input/sh_keysc.h> #include <linux/mtd/physmap.h> #include <linux/mtd/nand.h> #include <linux/i2c.h> @@ -18,8 +19,6 @@ #include <linux/delay.h> #include <linux/clk.h> #include <linux/gpio.h> -#include <linux/spi/spi.h> -#include <linux/spi/spi_gpio.h> #include <video/sh_mobile_lcdc.h> #include <media/sh_mobile_ceu.h> #include <media/ov772x.h> @@ -27,7 +26,7 @@ #include <asm/clock.h> #include <asm/machvec.h> #include <asm/io.h> -#include <asm/sh_keysc.h> +#include <asm/suspend.h> #include <mach/migor.h> #include <cpu/sh7722.h> @@ -390,17 +389,25 @@ static struct platform_device migor_ceu_device = { }, }; -struct spi_gpio_platform_data sdcard_cn9_platform_data = { - .sck = GPIO_PTD0, - .mosi = GPIO_PTD1, - .miso = GPIO_PTD2, - .num_chipselect = 1, +static struct resource sdhi_cn9_resources[] = { + [0] = { + .name = "SDHI", + .start = 0x04ce0000, + .end = 0x04ce01ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 101, + .flags = IORESOURCE_IRQ, + }, }; -static struct platform_device sdcard_cn9_device = { - .name = "spi_gpio", - .dev = { - .platform_data = &sdcard_cn9_platform_data, +static struct platform_device sdhi_cn9_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi_cn9_resources), + .resource = sdhi_cn9_resources, + .archdata = { + .hwblk_id = HWBLK_SDHI, }, }; @@ -425,23 +432,27 @@ static struct i2c_board_info migor_i2c_camera[] = { static struct ov772x_camera_info ov7725_info = { .buswidth = SOCAM_DATAWIDTH_8, - .link = { - .power = ov7725_power, - .board_info = &migor_i2c_camera[0], - .i2c_adapter_id = 0, - .module_name = "ov772x", - }, +}; + +static struct soc_camera_link ov7725_link = { + .power = ov7725_power, + .board_info = &migor_i2c_camera[0], + .i2c_adapter_id = 0, + .module_name = "ov772x", + .priv = &ov7725_info, }; static struct tw9910_video_info tw9910_info = { .buswidth = SOCAM_DATAWIDTH_8, .mpout = TW9910_MPO_FIELD, - .link = { - .power = tw9910_power, - .board_info = &migor_i2c_camera[1], - .i2c_adapter_id = 0, - .module_name = "tw9910", - } +}; + +static struct soc_camera_link tw9910_link = { + .power = tw9910_power, + .board_info = &migor_i2c_camera[1], + .i2c_adapter_id = 0, + .module_name = "tw9910", + .priv = &tw9910_info, }; static struct platform_device migor_camera[] = { @@ -449,13 +460,13 @@ static struct platform_device migor_camera[] = { .name = "soc-camera-pdrv", .id = 0, .dev = { - .platform_data = &ov7725_info.link, + .platform_data = &ov7725_link, }, }, { .name = "soc-camera-pdrv", .id = 1, .dev = { - .platform_data = &tw9910_info.link, + .platform_data = &tw9910_link, }, }, }; @@ -467,23 +478,24 @@ static struct platform_device *migor_devices[] __initdata = { &migor_ceu_device, &migor_nor_flash_device, &migor_nand_flash_device, - &sdcard_cn9_device, + &sdhi_cn9_device, &migor_camera[0], &migor_camera[1], }; -static struct spi_board_info migor_spi_devices[] = { - { - .modalias = "mmc_spi", - .max_speed_hz = 5000000, - .chip_select = 0, - .controller_data = (void *) GPIO_PTD5, - }, -}; +extern char migor_sdram_enter_start; +extern char migor_sdram_enter_end; +extern char migor_sdram_leave_start; +extern char migor_sdram_leave_end; static int __init migor_devices_setup(void) { - + /* register board specific self-refresh code */ + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, + &migor_sdram_enter_start, + &migor_sdram_enter_end, + &migor_sdram_leave_start, + &migor_sdram_leave_end); #ifdef CONFIG_PM /* Let D11 LED show STATUS0 */ gpio_request(GPIO_FN_STATUS0, NULL); @@ -525,6 +537,16 @@ static int __init migor_devices_setup(void) gpio_request(GPIO_PTA1, NULL); gpio_direction_input(GPIO_PTA1); + /* SDHI */ + gpio_request(GPIO_FN_SDHICD, NULL); + gpio_request(GPIO_FN_SDHIWP, NULL); + gpio_request(GPIO_FN_SDHID3, NULL); + gpio_request(GPIO_FN_SDHID2, NULL); + gpio_request(GPIO_FN_SDHID1, NULL); + gpio_request(GPIO_FN_SDHID0, NULL); + gpio_request(GPIO_FN_SDHICMD, NULL); + gpio_request(GPIO_FN_SDHICLK, NULL); + /* Touch Panel */ gpio_request(GPIO_FN_IRQ6, NULL); @@ -612,9 +634,6 @@ static int __init migor_devices_setup(void) i2c_register_board_info(0, migor_i2c_devices, ARRAY_SIZE(migor_i2c_devices)); - spi_register_board_info(migor_spi_devices, - ARRAY_SIZE(migor_spi_devices)); - return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices)); } arch_initcall(migor_devices_setup); diff --git a/arch/sh/boards/mach-r2d/irq.c b/arch/sh/boards/mach-r2d/irq.c index c70fecedcac4..78d7b27c80da 100644 --- a/arch/sh/boards/mach-r2d/irq.c +++ b/arch/sh/boards/mach-r2d/irq.c @@ -116,7 +116,7 @@ static unsigned char irl2irq[R2D_NR_IRL]; int rts7751r2d_irq_demux(int irq) { - if (irq >= R2D_NR_IRL || !irl2irq[irq]) + if (irq >= R2D_NR_IRL || irq < 0 || !irl2irq[irq]) return irq; return irl2irq[irq]; diff --git a/arch/sh/boards/mach-rsk/devices-rsk7203.c b/arch/sh/boards/mach-rsk/devices-rsk7203.c index 4af3a771c058..c37617e63220 100644 --- a/arch/sh/boards/mach-rsk/devices-rsk7203.c +++ b/arch/sh/boards/mach-rsk/devices-rsk7203.c @@ -11,10 +11,6 @@ #include <linux/types.h> #include <linux/platform_device.h> #include <linux/interrupt.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/physmap.h> -#include <linux/mtd/map.h> #include <linux/smsc911x.h> #include <linux/gpio.h> #include <linux/leds.h> diff --git a/arch/sh/boards/mach-rsk/setup.c b/arch/sh/boards/mach-rsk/setup.c index af64d030a5c7..a5c0df785bfe 100644 --- a/arch/sh/boards/mach-rsk/setup.c +++ b/arch/sh/boards/mach-rsk/setup.c @@ -15,14 +15,12 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/physmap.h> +#ifdef CONFIG_MTD #include <linux/mtd/map.h> +#endif #include <asm/machvec.h> #include <asm/io.h> -static const char *probes[] = { "cmdlinepart", NULL }; - -static struct mtd_partition *parsed_partitions; - static struct mtd_partition rsk_partitions[] = { { .name = "Bootloader", @@ -41,6 +39,8 @@ static struct mtd_partition rsk_partitions[] = { }; static struct physmap_flash_data flash_data = { + .parts = rsk_partitions, + .nr_parts = ARRAY_SIZE(rsk_partitions), .width = 2, }; @@ -60,7 +60,8 @@ static struct platform_device flash_device = { }, }; -static struct mtd_info *flash_mtd; +#ifdef CONFIG_MTD +static const char *probes[] = { "cmdlinepart", NULL }; static struct map_info rsk_flash_map = { .name = "RSK+ Flash", @@ -68,6 +69,10 @@ static struct map_info rsk_flash_map = { .bankwidth = 2, }; +static struct mtd_info *flash_mtd; + +static struct mtd_partition *parsed_partitions; + static void __init set_mtd_partitions(void) { int nr_parts = 0; @@ -77,14 +82,14 @@ static void __init set_mtd_partitions(void) nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_partitions, 0); /* If there is no partition table, used the hard coded table */ - if (nr_parts <= 0) { - flash_data.parts = rsk_partitions; - flash_data.nr_parts = ARRAY_SIZE(rsk_partitions); - } else { + if (nr_parts > 0) { flash_data.nr_parts = nr_parts; flash_data.parts = parsed_partitions; } } +#else +static inline void set_mtd_partitions(void) {} +#endif static struct platform_device *rsk_devices[] __initdata = { &flash_device, diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c index 02d21a3e2a8f..b221b6842b0d 100644 --- a/arch/sh/boards/mach-se/7722/irq.c +++ b/arch/sh/boards/mach-se/7722/irq.c @@ -16,15 +16,17 @@ #include <asm/io.h> #include <mach-se/mach/se7722.h> +unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, }; + static void disable_se7722_irq(unsigned int irq) { - unsigned int bit = irq - SE7722_FPGA_IRQ_BASE; + unsigned int bit = (unsigned int)get_irq_chip_data(irq); ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); } static void enable_se7722_irq(unsigned int irq) { - unsigned int bit = irq - SE7722_FPGA_IRQ_BASE; + unsigned int bit = (unsigned int)get_irq_chip_data(irq); ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK); } @@ -38,18 +40,15 @@ static struct irq_chip se7722_irq_chip __read_mostly = { static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) { unsigned short intv = ctrl_inw(IRQ01_STS); - struct irq_desc *ext_desc; - unsigned int ext_irq = SE7722_FPGA_IRQ_BASE; + unsigned int ext_irq = 0; intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; - while (intv) { - if (intv & 1) { - ext_desc = irq_desc + ext_irq; - handle_level_irq(ext_irq, ext_desc); - } - intv >>= 1; - ext_irq++; + for (; intv; intv >>= 1, ext_irq++) { + if (!(intv & 1)) + continue; + + generic_handle_irq(se7722_fpga_irq[ext_irq]); } } @@ -58,16 +57,24 @@ static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) */ void __init init_se7722_IRQ(void) { - int i; + int i, irq; ctrl_outw(0, IRQ01_MASK); /* disable all irqs */ ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ - for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) - set_irq_chip_and_handler_name(SE7722_FPGA_IRQ_BASE + i, + for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { + irq = create_irq(); + if (irq < 0) + return; + se7722_fpga_irq[i] = irq; + + set_irq_chip_and_handler_name(se7722_fpga_irq[i], &se7722_irq_chip, handle_level_irq, "level"); + set_irq_chip_data(se7722_fpga_irq[i], (void *)i); + } + set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux); set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c index 36374078e521..b1cb9425b600 100644 --- a/arch/sh/boards/mach-se/7722/setup.c +++ b/arch/sh/boards/mach-se/7722/setup.c @@ -14,6 +14,7 @@ #include <linux/platform_device.h> #include <linux/ata_platform.h> #include <linux/input.h> +#include <linux/input/sh_keysc.h> #include <linux/smc91x.h> #include <mach-se/mach/se7722.h> #include <mach-se/mach/mrshpc.h> @@ -21,7 +22,6 @@ #include <asm/clock.h> #include <asm/io.h> #include <asm/heartbeat.h> -#include <asm/sh_keysc.h> #include <cpu/sh7722.h> /* Heartbeat */ @@ -60,8 +60,7 @@ static struct resource smc91x_eth_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = SMC_IRQ, - .end = SMC_IRQ, + /* Filled in later */ .flags = IORESOURCE_IRQ, }, }; @@ -90,8 +89,7 @@ static struct resource cf_ide_resources[] = { .flags = IORESOURCE_IO, }, [2] = { - .start = MRSHPC_IRQ0, - .end = MRSHPC_IRQ0, + /* Filled in later */ .flags = IORESOURCE_IRQ, }, }; @@ -153,6 +151,14 @@ static struct platform_device *se7722_devices[] __initdata = { static int __init se7722_devices_setup(void) { mrshpc_setup_windows(); + + /* Wire-up dynamic vectors */ + cf_ide_resources[2].start = cf_ide_resources[2].end = + se7722_fpga_irq[SE7722_FPGA_IRQ_MRSHPC0]; + + smc91x_eth_resources[1].start = smc91x_eth_resources[1].end = + se7722_fpga_irq[SE7722_FPGA_IRQ_SMC]; + return platform_add_devices(se7722_devices, ARRAY_SIZE(se7722_devices)); } device_initcall(se7722_devices_setup); @@ -193,6 +199,5 @@ static void __init se7722_setup(char **cmdline_p) static struct sh_machine_vector mv_se7722 __initmv = { .mv_name = "Solution Engine 7722" , .mv_setup = se7722_setup , - .mv_nr_irqs = SE7722_FPGA_IRQ_BASE + SE7722_FPGA_IRQ_NR, .mv_init_irq = init_se7722_IRQ, }; diff --git a/arch/sh/boards/mach-se/7724/Makefile b/arch/sh/boards/mach-se/7724/Makefile index 349cbd6ce82d..a08b36830f0e 100644 --- a/arch/sh/boards/mach-se/7724/Makefile +++ b/arch/sh/boards/mach-se/7724/Makefile @@ -7,4 +7,4 @@ # # -obj-y := setup.o irq.o
\ No newline at end of file +obj-y := setup.o irq.o sdram.o diff --git a/arch/sh/boards/mach-se/7724/sdram.S b/arch/sh/boards/mach-se/7724/sdram.S new file mode 100644 index 000000000000..9040167d5022 --- /dev/null +++ b/arch/sh/boards/mach-se/7724/sdram.S @@ -0,0 +1,52 @@ +/* + * MS7724SE sdram self/auto-refresh setup code + * + * Copyright (C) 2009 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/sys.h> +#include <linux/errno.h> +#include <linux/linkage.h> +#include <asm/asm-offsets.h> +#include <asm/suspend.h> +#include <asm/romimage-macros.h> + +/* code to enter and leave self-refresh. must be self-contained. + * this code will be copied to on-chip memory and executed from there. + */ + .balign 4 +ENTRY(ms7724se_sdram_enter_start) + + /* DBSC: put memory in self-refresh mode */ + + ED 0xFD000010, 0x00000000 /* DBEN */ + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ + + rts + nop + +ENTRY(ms7724se_sdram_enter_end) + + .balign 4 +ENTRY(ms7724se_sdram_leave_start) + + /* DBSC: put memory in auto-refresh mode */ + + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + WAIT 1 + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000010, 0x00000001 /* DBEN */ + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ + + rts + nop + +ENTRY(ms7724se_sdram_leave_end) diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index e78c3be8ad2f..5d0f70b46c97 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -19,6 +19,7 @@ #include <linux/smc91x.h> #include <linux/gpio.h> #include <linux/input.h> +#include <linux/input/sh_keysc.h> #include <linux/usb/r8a66597.h> #include <video/sh_mobile_lcdc.h> #include <media/sh_mobile_ceu.h> @@ -27,7 +28,7 @@ #include <asm/heartbeat.h> #include <asm/sh_eth.h> #include <asm/clock.h> -#include <asm/sh_keysc.h> +#include <asm/suspend.h> #include <cpu/sh7724.h> #include <mach-se/mach/se7724.h> @@ -313,6 +314,9 @@ static struct platform_device fsi_device = { .dev = { .platform_data = &fsi_info, }, + .archdata = { + .hwblk_id = HWBLK_SPU, /* FSI needs SPU hwblk */ + }, }; /* KEYSC in SoC (Needs SW33-2 set to ON) */ @@ -448,6 +452,52 @@ static struct platform_device sh7724_usb1_gadget_device = { .resource = sh7724_usb1_gadget_resources, }; +static struct resource sdhi0_cn7_resources[] = { + [0] = { + .name = "SDHI0", + .start = 0x04ce0000, + .end = 0x04ce01ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 101, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi0_cn7_device = { + .name = "sh_mobile_sdhi", + .id = 0, + .num_resources = ARRAY_SIZE(sdhi0_cn7_resources), + .resource = sdhi0_cn7_resources, + .archdata = { + .hwblk_id = HWBLK_SDHI0, + }, +}; + +static struct resource sdhi1_cn8_resources[] = { + [0] = { + .name = "SDHI1", + .start = 0x04cf0000, + .end = 0x04cf01ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 24, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi1_cn8_device = { + .name = "sh_mobile_sdhi", + .id = 1, + .num_resources = ARRAY_SIZE(sdhi1_cn8_resources), + .resource = sdhi1_cn8_resources, + .archdata = { + .hwblk_id = HWBLK_SDHI1, + }, +}; + static struct platform_device *ms7724se_devices[] __initdata = { &heartbeat_device, &smc91x_eth_device, @@ -460,6 +510,15 @@ static struct platform_device *ms7724se_devices[] __initdata = { &sh7724_usb0_host_device, &sh7724_usb1_gadget_device, &fsi_device, + &sdhi0_cn7_device, + &sdhi1_cn8_device, +}; + +/* I2C device */ +static struct i2c_board_info i2c0_devices[] = { + { + I2C_BOARD_INFO("ak4642", 0x12), + }, }; #define EEPROM_OP 0xBA206000 @@ -484,7 +543,7 @@ static int __init sh_eth_is_eeprom_ready(void) static void __init sh_eth_init(void) { int i; - u16 mac[3]; + u16 mac; /* check EEPROM status */ if (!sh_eth_is_eeprom_ready()) @@ -498,16 +557,10 @@ static void __init sh_eth_init(void) if (!sh_eth_is_eeprom_ready()) return; - mac[i] = ctrl_inw(EEPROM_DATA); - mac[i] = ((mac[i] & 0xFF) << 8) | (mac[i] >> 8); /* swap */ + mac = ctrl_inw(EEPROM_DATA); + sh_eth_plat.mac_addr[i << 1] = mac & 0xff; + sh_eth_plat.mac_addr[(i << 1) + 1] = mac >> 8; } - - /* reset sh-eth */ - ctrl_outl(0x1, SH_ETH_ADDR + 0x0); - - /* set MAC addr */ - ctrl_outl(((mac[0] << 16) | (mac[1])), SH_ETH_MAHR); - ctrl_outl((mac[2]), SH_ETH_MALR); } #define SW4140 0xBA201000 @@ -524,11 +577,32 @@ static void __init sh_eth_init(void) #define SW41_G 0x4000 #define SW41_H 0x8000 +extern char ms7724se_sdram_enter_start; +extern char ms7724se_sdram_enter_end; +extern char ms7724se_sdram_leave_start; +extern char ms7724se_sdram_leave_end; + + +static int __init arch_setup(void) +{ + /* enable I2C device */ + i2c_register_board_info(0, i2c0_devices, + ARRAY_SIZE(i2c0_devices)); + return 0; +} +arch_initcall(arch_setup); + static int __init devices_setup(void) { u16 sw = ctrl_inw(SW4140); /* select camera, monitor */ struct clk *fsia_clk; + /* register board specific self-refresh code */ + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, + &ms7724se_sdram_enter_start, + &ms7724se_sdram_enter_end, + &ms7724se_sdram_leave_start, + &ms7724se_sdram_leave_end); /* Reset Release */ ctrl_outw(ctrl_inw(FPGA_OUT) & ~((1 << 1) | /* LAN */ @@ -698,6 +772,26 @@ static int __init devices_setup(void) clk_set_rate(&fsimcka_clk, 11000); clk_put(fsia_clk); + /* SDHI0 connected to cn7 */ + gpio_request(GPIO_FN_SDHI0CD, NULL); + gpio_request(GPIO_FN_SDHI0WP, NULL); + gpio_request(GPIO_FN_SDHI0D3, NULL); + gpio_request(GPIO_FN_SDHI0D2, NULL); + gpio_request(GPIO_FN_SDHI0D1, NULL); + gpio_request(GPIO_FN_SDHI0D0, NULL); + gpio_request(GPIO_FN_SDHI0CMD, NULL); + gpio_request(GPIO_FN_SDHI0CLK, NULL); + + /* SDHI1 connected to cn8 */ + gpio_request(GPIO_FN_SDHI1CD, NULL); + gpio_request(GPIO_FN_SDHI1WP, NULL); + gpio_request(GPIO_FN_SDHI1D3, NULL); + gpio_request(GPIO_FN_SDHI1D2, NULL); + gpio_request(GPIO_FN_SDHI1D1, NULL); + gpio_request(GPIO_FN_SDHI1D0, NULL); + gpio_request(GPIO_FN_SDHI1CMD, NULL); + gpio_request(GPIO_FN_SDHI1CLK, NULL); + /* * enable SH-Eth * |