dect
/
linux-2.6
Archived
13
0
Fork 0

Merge branch 'omap-upstream' into for-next

Conflicts:
	arch/arm/mach-omap2/Makefile
This commit is contained in:
Tony Lindgren 2009-05-28 15:41:03 -07:00
commit c81592ba1b
21 changed files with 915 additions and 333 deletions

View File

@ -4127,6 +4127,69 @@ S: Maintained
F: drivers/video/riva/
F: drivers/video/nvidia/
OMAP SUPPORT
P: Tony Lindgren <tony@atomide.com>
M: tony@atomide.com
L: linux-omap@vger.kernel.org
W: http://www.muru.com/linux/omap/
W: http://linux.omap.com/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
S: Maintained
F: arch/arm/*omap*
OMAP CLOCK FRAMEWORK SUPPORT
P: Paul Walmsley
M: paul@pwsan.com
L: linux-omap@vger.kernel.org
S: Maintained
F: arch/arm/*omap*/*clock*
OMAP POWER MANAGEMENT SUPPORT
P: Kevin Hilman
M: khilman@deeprootsystems.com
L: linux-omap@vger.kernel.org
S: Maintained
F: arch/arm/*omap*/*pm*
OMAP AUDIO SUPPORT
P: Jarkko Nikula
M: jhnikula@gmail.com
L: alsa-devel@alsa-project.org (subscribers-only)
L: linux-omap@vger.kernel.org
S: Maintained
F: sound/soc/omap/
OMAP FRAMEBUFFER SUPPORT
P: Imre Deak
M: imre.deak@nokia.com
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
L: linux-omap@vger.kernel.org
S: Maintained
F: drivers/video/omap/
OMAP MMC SUPPORT
P: Jarkko Lavinen
M: jarkko.lavinen@nokia.com
L: linux-kernel@vger.kernel.org
L: linux-omap@vger.kernel.org
S: Maintained
F: drivers/mmc/host/*omap*
OMAP RANDOM NUMBER GENERATOR SUPPORT
P: Deepak Saxena
M: dsaxena@plexity.net
S: Maintained
F: drivers/char/hw_random/omap-rng.c
OMAP USB SUPPORT
P: Felipe Balbi
M: felipe.balbi@nokia.com
P: David Brownell
M: dbrownell@users.sourceforge.net
L: linux-usb@vger.kernel.org
L: linux-omap@vger.kernel.org
S: Maintained
OMFS FILESYSTEM
P: Bob Copeland
M: me@bobcopeland.com
@ -5515,20 +5578,6 @@ F: drivers/misc/tifm*
F: drivers/mmc/host/tifm_sd.c
F: include/linux/tifm.h
TI OMAP MMC INTERFACE DRIVER
P: Carlos Aguiar, Anderson Briglia and Syed Khasim
M: linux-omap@vger.kernel.org
W: http://linux.omap.com
W: http://www.muru.com/linux/omap/
S: Maintained
F: drivers/mmc/host/omap.c
TI OMAP RANDOM NUMBER GENERATOR SUPPORT
P: Deepak Saxena
M: dsaxena@plexity.net
S: Maintained
F: drivers/char/hw_random/omap-rng.c
TIPC NETWORK LAYER
P: Per Liden
M: per.liden@ericsson.com

View File

@ -282,7 +282,7 @@ CONFIG_ALIGNMENT_TRAP=y
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="init=/sbin/preinit ubi.mtd=4 root=ubi0:rootfs rootfstype=ubifs rw console=ttyMTD5"
CONFIG_CMDLINE="init=/sbin/preinit ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs rootflags=bulk_read,no_chk_data_crc rw console=ttyMTD,log console=tty0"
# CONFIG_XIP_KERNEL is not set
# CONFIG_KEXEC is not set

View File

@ -46,7 +46,6 @@ config MACH_OMAP_H2
config MACH_OMAP_H3
bool "TI H3 Support"
depends on ARCH_OMAP1 && ARCH_OMAP16XX
# select GPIOEXPANDER_OMAP
help
TI OMAP 1710 H3 board support. Say Y here if you have such
a board.

View File

@ -13,6 +13,10 @@ obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
# Power Management
obj-$(CONFIG_PM) += pm.o sleep.o
# DSP
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
mailbox_mach-objs := mailbox.o
led-y := leds.o
# Specific board support

View File

@ -33,8 +33,11 @@
#include <mach/common.h>
#include <mach/dsp_common.h>
#include <mach/omapfb.h>
#include <mach/hwa742.h>
#include <mach/lcd_mipid.h>
#include <mach/mmc.h>
#include <mach/usb.h>
#include <mach/clock.h>
#define ADS7846_PENDOWN_GPIO 15
@ -162,6 +165,15 @@ static struct spi_board_info nokia770_spi_board_info[] __initdata = {
},
};
static struct hwa742_platform_data nokia770_hwa742_platform_data = {
.te_connected = 1,
};
static void hwa742_dev_init(void)
{
clk_add_alias("hwa_sys_ck", NULL, "bclk", NULL);
omapfb_set_ctrl_platform_data(&nokia770_hwa742_platform_data);
}
/* assume no Mini-AB port */
@ -370,6 +382,7 @@ static void __init omap_nokia770_init(void)
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
omap_dsp_init();
hwa742_dev_init();
ads7846_dev_init();
mipid_dev_init();
omap_usb_init(&nokia770_usb_config);

View File

@ -58,3 +58,9 @@ obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \
# Platform specific device init code
obj-y += usb-musb.o
onenand-$(CONFIG_MTD_ONENAND_OMAP2) := gpmc-onenand.o
obj-y += $(onenand-m) $(onenand-y)
smc91x-$(CONFIG_SMC91X) := gpmc-smc91x.o
obj-y += $(smc91x-m) $(smc91x-y)

View File

@ -36,14 +36,12 @@
#include <mach/common.h>
#include <mach/gpmc.h>
#include <mach/usb.h>
#include <mach/gpmc-smc91x.h>
#include "mmc-twl4030.h"
#define SDP2430_CS0_BASE 0x04000000
#define SDP2430_FLASH_CS 0
#define SDP2430_SMC91X_CS 5
#define SDP2430_ETHR_GPIO_IRQ 149
#define SECONDARY_LCD_GPIO 147
static struct mtd_partition sdp2430_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
@ -99,100 +97,53 @@ static struct platform_device sdp2430_flash_device = {
.resource = &sdp2430_flash_resource,
};
static struct resource sdp2430_smc91x_resources[] = {
[0] = {
.start = SDP2430_CS0_BASE,
.end = SDP2430_CS0_BASE + SZ_64M - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = OMAP_GPIO_IRQ(SDP2430_ETHR_GPIO_IRQ),
.end = OMAP_GPIO_IRQ(SDP2430_ETHR_GPIO_IRQ),
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
},
};
static struct platform_device sdp2430_smc91x_device = {
.name = "smc91x",
static struct platform_device sdp2430_lcd_device = {
.name = "sdp2430_lcd",
.id = -1,
.num_resources = ARRAY_SIZE(sdp2430_smc91x_resources),
.resource = sdp2430_smc91x_resources,
};
static struct platform_device *sdp2430_devices[] __initdata = {
&sdp2430_smc91x_device,
&sdp2430_flash_device,
&sdp2430_lcd_device,
};
static inline void __init sdp2430_init_smc91x(void)
static struct omap_lcd_config sdp2430_lcd_config __initdata = {
.ctrl_name = "internal",
};
#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE)
static struct omap_smc91x_platform_data board_smc91x_data = {
.cs = 5,
.gpio_irq = 149,
.flags = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 |
IORESOURCE_IRQ_LOWLEVEL,
};
static void __init board_smc91x_init(void)
{
int eth_cs;
unsigned long cs_mem_base;
unsigned int rate;
struct clk *gpmc_fck;
if (omap_rev() > OMAP3430_REV_ES1_0)
board_smc91x_data.gpio_irq = 6;
else
board_smc91x_data.gpio_irq = 29;
eth_cs = SDP2430_SMC91X_CS;
gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */
if (IS_ERR(gpmc_fck)) {
WARN_ON(1);
return;
}
clk_enable(gpmc_fck);
rate = clk_get_rate(gpmc_fck);
/* Make sure CS1 timings are correct, for 2430 always muxed */
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);
if (rate >= 160000000) {
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
} else if (rate >= 130000000) {
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
} else { /* rate = 100000000 */
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
}
if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
goto out;
}
sdp2430_smc91x_resources[0].start = cs_mem_base + 0x300;
sdp2430_smc91x_resources[0].end = cs_mem_base + 0x30f;
udelay(100);
if (gpio_request(SDP2430_ETHR_GPIO_IRQ, "SMC91x irq") < 0) {
printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
SDP2430_ETHR_GPIO_IRQ);
gpmc_cs_free(eth_cs);
goto out;
}
gpio_direction_input(SDP2430_ETHR_GPIO_IRQ);
out:
clk_disable(gpmc_fck);
clk_put(gpmc_fck);
gpmc_smc91x_init(&board_smc91x_data);
}
#else
static inline void board_smc91x_init(void)
{
}
#endif
static void __init omap_2430sdp_init_irq(void)
{
omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
sdp2430_init_smc91x();
}
static struct omap_uart_config sdp2430_uart_config __initdata = {
@ -201,6 +152,7 @@ static struct omap_uart_config sdp2430_uart_config __initdata = {
static struct omap_board_config_kernel sdp2430_config[] = {
{OMAP_TAG_UART, &sdp2430_uart_config},
{OMAP_TAG_LCD, &sdp2430_lcd_config},
};
@ -248,6 +200,8 @@ static struct twl4030_hsmmc_info mmc[] __initdata = {
static void __init omap_2430sdp_init(void)
{
int ret;
omap2430_i2c_init();
platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
@ -256,6 +210,12 @@ static void __init omap_2430sdp_init(void)
omap_serial_init();
twl4030_mmc_init(mmc);
usb_musb_init();
board_smc91x_init();
/* Turn off secondary LCD backlight */
ret = gpio_request(SECONDARY_LCD_GPIO, "Secondary LCD backlight");
if (ret == 0)
gpio_direction_output(SECONDARY_LCD_GPIO, 0);
}
static void __init omap_2430sdp_map_io(void)

View File

@ -39,15 +39,12 @@
#include <mach/control.h>
#include <mach/keypad.h>
#include <mach/gpmc-smc91x.h>
#include "mmc-twl4030.h"
#define CONFIG_DISABLE_HFCLK 1
#define SDP3430_ETHR_GPIO_IRQ_SDPV1 29
#define SDP3430_ETHR_GPIO_IRQ_SDPV2 6
#define SDP3430_SMC91X_CS 3
#define SDP3430_TS_GPIO_IRQ_SDPV1 3
#define SDP3430_TS_GPIO_IRQ_SDPV2 2
@ -56,24 +53,6 @@
#define TWL4030_MSECURE_GPIO 22
static struct resource sdp3430_smc91x_resources[] = {
[0] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 0,
.end = 0,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
},
};
static struct platform_device sdp3430_smc91x_device = {
.name = "smc91x",
.id = -1,
.num_resources = ARRAY_SIZE(sdp3430_smc91x_resources),
.resource = sdp3430_smc91x_resources,
};
static int sdp3430_keymap[] = {
KEY(0, 0, KEY_LEFT),
KEY(0, 1, KEY_RIGHT),
@ -184,48 +163,14 @@ static struct regulator_consumer_supply sdp3430_vdvi_supply = {
};
static struct platform_device *sdp3430_devices[] __initdata = {
&sdp3430_smc91x_device,
&sdp3430_lcd_device,
};
static inline void __init sdp3430_init_smc91x(void)
{
int eth_cs;
unsigned long cs_mem_base;
int eth_gpio = 0;
eth_cs = SDP3430_SMC91X_CS;
if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
return;
}
sdp3430_smc91x_resources[0].start = cs_mem_base + 0x300;
sdp3430_smc91x_resources[0].end = cs_mem_base + 0x30f;
udelay(100);
if (omap_rev() > OMAP3430_REV_ES1_0)
eth_gpio = SDP3430_ETHR_GPIO_IRQ_SDPV2;
else
eth_gpio = SDP3430_ETHR_GPIO_IRQ_SDPV1;
sdp3430_smc91x_resources[1].start = gpio_to_irq(eth_gpio);
if (gpio_request(eth_gpio, "SMC91x irq") < 0) {
printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
eth_gpio);
return;
}
gpio_direction_input(eth_gpio);
}
static void __init omap_3430sdp_init_irq(void)
{
omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
sdp3430_init_smc91x();
}
static struct omap_uart_config sdp3430_uart_config __initdata = {
@ -506,6 +451,32 @@ static int __init omap3430_i2c_init(void)
return 0;
}
#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
static struct omap_smc91x_platform_data board_smc91x_data = {
.cs = 3,
.flags = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 |
IORESOURCE_IRQ_LOWLEVEL,
};
static void __init board_smc91x_init(void)
{
if (omap_rev() > OMAP3430_REV_ES1_0)
board_smc91x_data.gpio_irq = 6;
else
board_smc91x_data.gpio_irq = 29;
gpmc_smc91x_init(&board_smc91x_data);
}
#else
static inline void board_smc91x_init(void)
{
}
#endif
static void __init omap_3430sdp_init(void)
{
omap3430_i2c_init();
@ -522,6 +493,7 @@ static void __init omap_3430sdp_init(void)
ads7846_dev_init();
omap_serial_init();
usb_musb_init();
board_smc91x_init();
}
static void __init omap_3430sdp_map_io(void)

View File

@ -27,31 +27,11 @@
#include <mach/dma.h>
#include <mach/gpmc.h>
#include <mach/keypad.h>
#include <mach/onenand.h>
#include <mach/gpmc-smc91x.h>
#include "mmc-twl4030.h"
#define SMC91X_CS 1
#define SMC91X_GPIO_IRQ 54
#define SMC91X_GPIO_RESET 164
#define SMC91X_GPIO_PWRDWN 86
static struct resource rx51_smc91x_resources[] = {
[0] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
},
};
static struct platform_device rx51_smc91x_device = {
.name = "smc91x",
.id = -1,
.num_resources = ARRAY_SIZE(rx51_smc91x_resources),
.resource = rx51_smc91x_resources,
};
static int rx51_keymap[] = {
KEY(0, 0, KEY_Q),
KEY(0, 1, KEY_W),
@ -107,98 +87,6 @@ static struct twl4030_keypad_data rx51_kp_data = {
.rep = 1,
};
static struct platform_device *rx51_peripherals_devices[] = {
&rx51_smc91x_device,
};
/*
* Timings are taken from smsc-lan91c96-ms.pdf
*/
static int smc91x_init_gpmc(int cs)
{
struct gpmc_timings t;
const int t2_r = 45; /* t2 in Figure 12.10 */
const int t2_w = 30; /* t2 in Figure 12.11 */
const int t3 = 15; /* t3 in Figure 12.10 */
const int t5_r = 0; /* t5 in Figure 12.10 */
const int t6_r = 45; /* t6 in Figure 12.10 */
const int t6_w = 0; /* t6 in Figure 12.11 */
const int t7_w = 15; /* t7 in Figure 12.11 */
const int t15 = 12; /* t15 in Figure 12.2 */
const int t20 = 185; /* t20 in Figure 12.2 */
memset(&t, 0, sizeof(t));
t.cs_on = t15;
t.cs_rd_off = t3 + t2_r + t5_r; /* Figure 12.10 */
t.cs_wr_off = t3 + t2_w + t6_w; /* Figure 12.11 */
t.adv_on = t3; /* Figure 12.10 */
t.adv_rd_off = t3 + t2_r; /* Figure 12.10 */
t.adv_wr_off = t3 + t2_w; /* Figure 12.11 */
t.oe_off = t3 + t2_r + t5_r; /* Figure 12.10 */
t.oe_on = t.oe_off - t6_r; /* Figure 12.10 */
t.we_off = t3 + t2_w + t6_w; /* Figure 12.11 */
t.we_on = t.we_off - t7_w; /* Figure 12.11 */
t.rd_cycle = t20; /* Figure 12.2 */
t.wr_cycle = t20; /* Figure 12.4 */
t.access = t3 + t2_r + t5_r; /* Figure 12.10 */
t.wr_access = t3 + t2_w + t6_w; /* Figure 12.11 */
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, GPMC_CONFIG1_DEVICESIZE_16);
return gpmc_cs_set_timings(cs, &t);
}
static void __init rx51_init_smc91x(void)
{
unsigned long cs_mem_base;
int ret;
omap_cfg_reg(U8_34XX_GPIO54_DOWN);
omap_cfg_reg(G25_34XX_GPIO86_OUT);
omap_cfg_reg(H19_34XX_GPIO164_OUT);
if (gpmc_cs_request(SMC91X_CS, SZ_16M, &cs_mem_base) < 0) {
printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
return;
}
rx51_smc91x_resources[0].start = cs_mem_base + 0x300;
rx51_smc91x_resources[0].end = cs_mem_base + 0x30f;
smc91x_init_gpmc(SMC91X_CS);
if (gpio_request(SMC91X_GPIO_IRQ, "SMC91X irq") < 0)
goto free1;
gpio_direction_input(SMC91X_GPIO_IRQ);
rx51_smc91x_resources[1].start = gpio_to_irq(SMC91X_GPIO_IRQ);
ret = gpio_request(SMC91X_GPIO_PWRDWN, "SMC91X powerdown");
if (ret)
goto free2;
gpio_direction_output(SMC91X_GPIO_PWRDWN, 0);
ret = gpio_request(SMC91X_GPIO_RESET, "SMC91X reset");
if (ret)
goto free3;
gpio_direction_output(SMC91X_GPIO_RESET, 0);
gpio_set_value(SMC91X_GPIO_RESET, 1);
msleep(100);
gpio_set_value(SMC91X_GPIO_RESET, 0);
return;
free3:
gpio_free(SMC91X_GPIO_PWRDWN);
free2:
gpio_free(SMC91X_GPIO_IRQ);
free1:
gpmc_cs_free(SMC91X_CS);
printk(KERN_ERR "Could not initialize smc91x\n");
}
static struct twl4030_madc_platform_data rx51_madc_data = {
.irq_line = 1,
};
@ -408,12 +296,94 @@ static int __init rx51_i2c_init(void)
return 0;
}
#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
static struct mtd_partition onenand_partitions[] = {
{
.name = "bootloader",
.offset = 0,
.size = 0x20000,
.mask_flags = MTD_WRITEABLE, /* Force read-only */
},
{
.name = "config",
.offset = MTDPART_OFS_APPEND,
.size = 0x60000,
},
{
.name = "log",
.offset = MTDPART_OFS_APPEND,
.size = 0x40000,
},
{
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = 0x200000,
},
{
.name = "initfs",
.offset = MTDPART_OFS_APPEND,
.size = 0x200000,
},
{
.name = "rootfs",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
};
static struct omap_onenand_platform_data board_onenand_data = {
.cs = 0,
.gpio_irq = 65,
.parts = onenand_partitions,
.nr_parts = ARRAY_SIZE(onenand_partitions),
};
static void __init board_onenand_init(void)
{
gpmc_onenand_init(&board_onenand_data);
}
#else
static inline void board_onenand_init(void)
{
}
#endif
#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
static struct omap_smc91x_platform_data board_smc91x_data = {
.cs = 1,
.gpio_irq = 54,
.gpio_pwrdwn = 86,
.gpio_reset = 164,
.flags = GPMC_TIMINGS_SMC91C96 | IORESOURCE_IRQ_HIGHLEVEL,
};
static void __init board_smc91x_init(void)
{
omap_cfg_reg(U8_34XX_GPIO54_DOWN);
omap_cfg_reg(G25_34XX_GPIO86_OUT);
omap_cfg_reg(H19_34XX_GPIO164_OUT);
gpmc_smc91x_init(&board_smc91x_data);
}
#else
static inline void board_smc91x_init(void)
{
}
#endif
void __init rx51_peripherals_init(void)
{
platform_add_devices(rx51_peripherals_devices,
ARRAY_SIZE(rx51_peripherals_devices));
rx51_i2c_init();
rx51_init_smc91x();
board_onenand_init();
board_smc91x_init();
}

View File

@ -0,0 +1,330 @@
/*
* linux/arch/arm/mach-omap2/gpmc-onenand.c
*
* Copyright (C) 2006 - 2009 Nokia Corporation
* Contacts: Juha Yrjola
* Tony Lindgren
*
* 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
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/mtd/onenand_regs.h>
#include <linux/io.h>
#include <asm/mach/flash.h>
#include <mach/onenand.h>
#include <mach/board.h>
#include <mach/gpmc.h>
static struct omap_onenand_platform_data *gpmc_onenand_data;
static struct platform_device gpmc_onenand_device = {
.name = "omap2-onenand",
.id = -1,
};
static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
{
struct gpmc_timings t;
const int t_cer = 15;
const int t_avdp = 12;
const int t_aavdh = 7;
const int t_ce = 76;
const int t_aa = 76;
const int t_oe = 20;
const int t_cez = 20; /* max of t_cez, t_oez */
const int t_ds = 30;
const int t_wpl = 40;
const int t_wph = 30;
memset(&t, 0, sizeof(t));
t.sync_clk = 0;
t.cs_on = 0;
t.adv_on = 0;
/* Read */
t.adv_rd_off = gpmc_round_ns_to_ticks(max_t(int, t_avdp, t_cer));
t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(t_aavdh);
t.access = t.adv_on + gpmc_round_ns_to_ticks(t_aa);
t.access = max_t(int, t.access, t.cs_on + gpmc_round_ns_to_ticks(t_ce));
t.access = max_t(int, t.access, t.oe_on + gpmc_round_ns_to_ticks(t_oe));
t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
t.cs_rd_off = t.oe_off;
t.rd_cycle = t.cs_rd_off + gpmc_round_ns_to_ticks(t_cez);
/* Write */
t.adv_wr_off = t.adv_rd_off;
t.we_on = t.oe_on;
if (cpu_is_omap34xx()) {
t.wr_data_mux_bus = t.we_on;
t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
}
t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
/* Configure GPMC for asynchronous read */
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
GPMC_CONFIG1_DEVICESIZE_16 |
GPMC_CONFIG1_MUXADDDATA);
return gpmc_cs_set_timings(cs, &t);
}
static void set_onenand_cfg(void __iomem *onenand_base, int latency,
int sync_read, int sync_write, int hf)
{
u32 reg;
reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
reg &= ~((0x7 << ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7 << 9));
reg |= (latency << ONENAND_SYS_CFG1_BRL_SHIFT) |
ONENAND_SYS_CFG1_BL_16;
if (sync_read)
reg |= ONENAND_SYS_CFG1_SYNC_READ;
else
reg &= ~ONENAND_SYS_CFG1_SYNC_READ;
if (sync_write)
reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
else
reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE;
if (hf)
reg |= ONENAND_SYS_CFG1_HF;
else
reg &= ~ONENAND_SYS_CFG1_HF;
writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
}
static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
void __iomem *onenand_base,
int freq)
{
struct gpmc_timings t;
const int t_cer = 15;
const int t_avdp = 12;
const int t_cez = 20; /* max of t_cez, t_oez */
const int t_ds = 30;
const int t_wpl = 40;
const int t_wph = 30;
int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
int tick_ns, div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency;
int first_time = 0, hf = 0, sync_read = 0, sync_write = 0;
int err, ticks_cez;
int cs = cfg->cs;
u32 reg;
if (cfg->flags & ONENAND_SYNC_READ) {
sync_read = 1;
} else if (cfg->flags & ONENAND_SYNC_READWRITE) {
sync_read = 1;
sync_write = 1;
}
if (!freq) {
/* Very first call freq is not known */
err = omap2_onenand_set_async_mode(cs, onenand_base);
if (err)
return err;
reg = readw(onenand_base + ONENAND_REG_VERSION_ID);
switch ((reg >> 4) & 0xf) {
case 0:
freq = 40;
break;
case 1:
freq = 54;
break;
case 2:
freq = 66;
break;
case 3:
freq = 83;
break;
case 4:
freq = 104;
break;
default:
freq = 54;
break;
}
first_time = 1;
}
switch (freq) {
case 83:
min_gpmc_clk_period = 12; /* 83 MHz */
t_ces = 5;
t_avds = 4;
t_avdh = 2;
t_ach = 6;
t_aavdh = 6;
t_rdyo = 9;
break;
case 66:
min_gpmc_clk_period = 15; /* 66 MHz */
t_ces = 6;
t_avds = 5;
t_avdh = 2;
t_ach = 6;
t_aavdh = 6;
t_rdyo = 11;
break;
default:
min_gpmc_clk_period = 18; /* 54 MHz */
t_ces = 7;
t_avds = 7;
t_avdh = 7;
t_ach = 9;
t_aavdh = 7;
t_rdyo = 15;
sync_write = 0;
break;
}
tick_ns = gpmc_ticks_to_ns(1);
div = gpmc_cs_calc_divider(cs, min_gpmc_clk_period);
gpmc_clk_ns = gpmc_ticks_to_ns(div);
if (gpmc_clk_ns < 15) /* >66Mhz */
hf = 1;
if (hf)
latency = 6;
else if (gpmc_clk_ns >= 25) /* 40 MHz*/
latency = 3;
else
latency = 4;
if (first_time)
set_onenand_cfg(onenand_base, latency,
sync_read, sync_write, hf);
if (div == 1) {
reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
reg |= (1 << 7);
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
reg |= (1 << 7);
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
reg |= (1 << 7);
reg |= (1 << 23);
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
} else {
reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
reg &= ~(1 << 7);
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
reg &= ~(1 << 7);
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
reg &= ~(1 << 7);
reg &= ~(1 << 23);
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
}
/* Set synchronous read timings */
memset(&t, 0, sizeof(t));
t.sync_clk = min_gpmc_clk_period;
t.cs_on = 0;
t.adv_on = 0;
fclk_offset_ns = gpmc_round_ns_to_ticks(max_t(int, t_ces, t_avds));
fclk_offset = gpmc_ns_to_ticks(fclk_offset_ns);
t.page_burst_access = gpmc_clk_ns;
/* Read */
t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh));
t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach));
t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div);
t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
t.cs_rd_off = t.oe_off;
ticks_cez = ((gpmc_ns_to_ticks(t_cez) + div - 1) / div) * div;
t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
ticks_cez);
/* Write */
if (sync_write) {
t.adv_wr_off = t.adv_rd_off;
t.we_on = 0;
t.we_off = t.cs_rd_off;
t.cs_wr_off = t.cs_rd_off;
t.wr_cycle = t.rd_cycle;
if (cpu_is_omap34xx()) {
t.wr_data_mux_bus = gpmc_ticks_to_ns(fclk_offset +
gpmc_ns_to_ticks(min_gpmc_clk_period +
t_rdyo));
t.wr_access = t.access;
}
} else {
t.adv_wr_off = gpmc_round_ns_to_ticks(max_t(int,
t_avdp, t_cer));
t.we_on = t.adv_wr_off + gpmc_round_ns_to_ticks(t_aavdh);
t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
if (cpu_is_omap34xx()) {
t.wr_data_mux_bus = t.we_on;
t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
}
}
/* Configure GPMC for synchronous read */
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
GPMC_CONFIG1_WRAPBURST_SUPP |
GPMC_CONFIG1_READMULTIPLE_SUPP |
(sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
(sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
(sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
GPMC_CONFIG1_PAGE_LEN(2) |
(cpu_is_omap34xx() ? 0 :
(GPMC_CONFIG1_WAIT_READ_MON |
GPMC_CONFIG1_WAIT_PIN_SEL(0))) |
GPMC_CONFIG1_DEVICESIZE_16 |
GPMC_CONFIG1_DEVICETYPE_NOR |
GPMC_CONFIG1_MUXADDDATA);
err = gpmc_cs_set_timings(cs, &t);
if (err)
return err;
set_onenand_cfg(onenand_base, latency, sync_read, sync_write, hf);
return 0;
}
static int gpmc_onenand_setup(void __iomem *onenand_base, int freq)
{
struct device *dev = &gpmc_onenand_device.dev;
/* Set sync timings in GPMC */
if (omap2_onenand_set_sync_mode(gpmc_onenand_data, onenand_base,
freq) < 0) {
dev_err(dev, "Unable to set synchronous mode\n");
return -EINVAL;
}
return 0;
}
void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
{
gpmc_onenand_data = _onenand_data;
gpmc_onenand_data->onenand_setup = gpmc_onenand_setup;
gpmc_onenand_device.dev.platform_data = gpmc_onenand_data;
if (cpu_is_omap24xx() &&
(gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) {
printk(KERN_ERR "Onenand using only SYNC_READ on 24xx\n");
gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE;
gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
}
if (platform_device_register(&gpmc_onenand_device) < 0) {
printk(KERN_ERR "Unable to register OneNAND device\n");
return;
}
}

View File

@ -0,0 +1,189 @@
/*
* linux/arch/arm/mach-omap2/gpmc-smc91x.c
*
* Copyright (C) 2009 Nokia Corporation
* Contact: Tony Lindgren
*
* 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
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/smc91x.h>
#include <mach/board.h>
#include <mach/gpmc.h>
#include <mach/gpmc-smc91x.h>
static struct omap_smc91x_platform_data *gpmc_cfg;
static struct resource gpmc_smc91x_resources[] = {
[0] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.flags = IORESOURCE_IRQ,
},
};
static struct smc91x_platdata gpmc_smc91x_info = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_0,
};
static struct platform_device gpmc_smc91x_device = {
.name = "smc91x",
.id = -1,
.num_resources = ARRAY_SIZE(gpmc_smc91x_resources),
.resource = gpmc_smc91x_resources,
.dev = {
.platform_data = &gpmc_smc91x_info,
},
};
/*
* Set the gpmc timings for smc91c96. The timings are taken
* from the data sheet available at:
* http://www.smsc.com/main/catalog/lan91c96.html
* REVISIT: Level shifters can add at least to the access latency.
*/
static int smc91c96_gpmc_retime(void)
{
struct gpmc_timings t;
const int t3 = 10; /* Figure 12.2 read and 12.4 write */
const int t4_r = 20; /* Figure 12.2 read */
const int t4_w = 5; /* Figure 12.4 write */
const int t5 = 25; /* Figure 12.2 read */
const int t6 = 15; /* Figure 12.2 read */
const int t7 = 5; /* Figure 12.4 write */
const int t8 = 5; /* Figure 12.4 write */
const int t20 = 185; /* Figure 12.2 read and 12.4 write */
u32 l;
memset(&t, 0, sizeof(t));
/* Read timings */
t.cs_on = 0;
t.adv_on = t.cs_on;
t.oe_on = t.adv_on + t3;
t.access = t.oe_on + t5;
t.oe_off = t.access;
t.adv_rd_off = t.oe_off + max(t4_r, t6);
t.cs_rd_off = t.oe_off;
t.rd_cycle = t20 - t.oe_on;
/* Write timings */
t.we_on = t.adv_on + t3;
if (cpu_is_omap34xx() && (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)) {
t.wr_data_mux_bus = t.we_on;
t.we_off = t.wr_data_mux_bus + t7;
} else
t.we_off = t.we_on + t7;
if (cpu_is_omap34xx())
t.wr_access = t.we_off;
t.adv_wr_off = t.we_off + max(t4_w, t8);
t.cs_wr_off = t.we_off + t4_w;
t.wr_cycle = t20 - t.we_on;
l = GPMC_CONFIG1_DEVICESIZE_16;
if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
l |= GPMC_CONFIG1_MUXADDDATA;
if (gpmc_cfg->flags & GPMC_READ_MON)
l |= GPMC_CONFIG1_WAIT_READ_MON;
if (gpmc_cfg->flags & GPMC_WRITE_MON)
l |= GPMC_CONFIG1_WAIT_WRITE_MON;
if (gpmc_cfg->wait_pin)
l |= GPMC_CONFIG1_WAIT_PIN_SEL(gpmc_cfg->wait_pin);
gpmc_cs_write_reg(gpmc_cfg->cs, GPMC_CS_CONFIG1, l);
/*
* FIXME: Calculate the address and data bus muxed timings.
* Note that at least adv_rd_off needs to be changed according
* to omap3430 TRM Figure 11-11. Are the sdp boards using the
* FPGA in between smc91x and omap as the timings are different
* from above?
*/
if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
return 0;
return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
}
/*
* Initialize smc91x device connected to the GPMC. Note that we
* assume that pin multiplexing is done in the board-*.c file,
* or in the bootloader.
*/
void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data)
{
unsigned long cs_mem_base;
int ret;
gpmc_cfg = board_data;
if (gpmc_cfg->flags & GPMC_TIMINGS_SMC91C96)
gpmc_cfg->retime = smc91c96_gpmc_retime;
if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) {
printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
return;
}
gpmc_smc91x_resources[0].start = cs_mem_base + 0x300;
gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f;
gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK);
if (gpmc_cfg->retime) {
ret = gpmc_cfg->retime();
if (ret != 0)
goto free1;
}
if (gpio_request(gpmc_cfg->gpio_irq, "SMC91X irq") < 0)
goto free1;
gpio_direction_input(gpmc_cfg->gpio_irq);
gpmc_smc91x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq);
if (gpmc_cfg->gpio_pwrdwn) {
ret = gpio_request(gpmc_cfg->gpio_pwrdwn, "SMC91X powerdown");
if (ret)
goto free2;
gpio_direction_output(gpmc_cfg->gpio_pwrdwn, 0);
}
if (gpmc_cfg->gpio_reset) {
ret = gpio_request(gpmc_cfg->gpio_reset, "SMC91X reset");
if (ret)
goto free3;
gpio_direction_output(gpmc_cfg->gpio_reset, 0);
gpio_set_value(gpmc_cfg->gpio_reset, 1);
msleep(100);
gpio_set_value(gpmc_cfg->gpio_reset, 0);
}
if (platform_device_register(&gpmc_smc91x_device) < 0) {
printk(KERN_ERR "Unable to register smc91x device\n");
gpio_free(gpmc_cfg->gpio_reset);
goto free3;
}
return;
free3:
if (gpmc_cfg->gpio_pwrdwn)
gpio_free(gpmc_cfg->gpio_pwrdwn);
free2:
gpio_free(gpmc_cfg->gpio_irq);
free1:
gpmc_cs_free(gpmc_cfg->cs);
printk(KERN_ERR "Could not initialize smc91x\n");
}

View File

@ -310,41 +310,62 @@ EXPORT_SYMBOL(omap_set_dma_transfer_params);
void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
{
u16 w;
BUG_ON(omap_dma_in_1510_mode());
if (cpu_class_is_omap1()) {
u16 w;
w = dma_read(CCR2(lch));
w &= ~0x03;
switch (mode) {
case OMAP_DMA_CONSTANT_FILL:
w |= 0x01;
break;
case OMAP_DMA_TRANSPARENT_COPY:
w |= 0x02;
break;
case OMAP_DMA_COLOR_DIS:
break;
default:
BUG();
}
dma_write(w, CCR2(lch));
w = dma_read(LCH_CTRL(lch));
w &= ~0x0f;
/* Default is channel type 2D */
if (mode) {
dma_write((u16)color, COLOR_L(lch));
dma_write((u16)(color >> 16), COLOR_U(lch));
w |= 1; /* Channel type G */
}
dma_write(w, LCH_CTRL(lch));
}
if (cpu_class_is_omap2()) {
REVISIT_24XX();
return;
}
u32 val;
w = dma_read(CCR2(lch));
w &= ~0x03;
val = dma_read(CCR(lch));
val &= ~((1 << 17) | (1 << 16));
switch (mode) {
case OMAP_DMA_CONSTANT_FILL:
w |= 0x01;
break;
case OMAP_DMA_TRANSPARENT_COPY:
w |= 0x02;
break;
case OMAP_DMA_COLOR_DIS:
break;
default:
BUG();
}
dma_write(w, CCR2(lch));
switch (mode) {
case OMAP_DMA_CONSTANT_FILL:
val |= 1 << 16;
break;
case OMAP_DMA_TRANSPARENT_COPY:
val |= 1 << 17;
break;
case OMAP_DMA_COLOR_DIS:
break;
default:
BUG();
}
dma_write(val, CCR(lch));
w = dma_read(LCH_CTRL(lch));
w &= ~0x0f;
/* Default is channel type 2D */
if (mode) {
dma_write((u16)color, COLOR_L(lch));
dma_write((u16)(color >> 16), COLOR_U(lch));
w |= 1; /* Channel type G */
color &= 0xffffff;
dma_write(color, COLOR(lch));
}
dma_write(w, LCH_CTRL(lch));
}
EXPORT_SYMBOL(omap_set_dma_color_mode);
@ -1199,7 +1220,7 @@ static void create_dma_lch_chain(int lch_head, int lch_queue)
* Failure: -EINVAL/-ENOMEM
*/
int omap_request_dma_chain(int dev_id, const char *dev_name,
void (*callback) (int chain_id, u16 ch_status,
void (*callback) (int lch, u16 ch_status,
void *data),
int *chain_id, int no_of_chans, int chain_mode,
struct omap_dma_channel_params params)

View File

@ -5,7 +5,7 @@
*
* Copyright (C) 2007 Nokia Corporation.
*
* Contact: Jarkko Nikula <jarkko.nikula@nokia.com>
* Contact: Jarkko Nikula <jhnikula@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@ -144,6 +144,7 @@
#define OMAP_DMA4_CSSA_U(n) 0
#define OMAP_DMA4_CDSA_L(n) 0
#define OMAP_DMA4_CDSA_U(n) 0
#define OMAP1_DMA_COLOR(n) 0
/*----------------------------------------------------------------------------*/
@ -531,7 +532,7 @@ extern int omap_get_dma_index(int lch, int *ei, int *fi);
/* Chaining APIs */
#ifndef CONFIG_ARCH_OMAP1
extern int omap_request_dma_chain(int dev_id, const char *dev_name,
void (*callback) (int chain_id, u16 ch_status,
void (*callback) (int lch, u16 ch_status,
void *data),
int *chain_id, int no_of_chans,
int chain_mode,

View File

@ -0,0 +1,42 @@
/*
* arch/arm/plat-omap/include/mach/gpmc-smc91x.h
*
* Copyright (C) 2009 Nokia Corporation
*
* 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
* published by the Free Software Foundation.
*/
#ifndef __ASM_ARCH_OMAP_GPMC_SMC91X_H__
#define GPMC_TIMINGS_SMC91C96 (1 << 4)
#define GPMC_MUX_ADD_DATA (1 << 5) /* GPMC_CONFIG1_MUXADDDATA */
#define GPMC_READ_MON (1 << 6) /* GPMC_CONFIG1_WAIT_READ_MON */
#define GPMC_WRITE_MON (1 << 7) /* GPMC_CONFIG1_WAIT_WRITE_MON */
struct omap_smc91x_platform_data {
int cs;
int gpio_irq;
int gpio_pwrdwn;
int gpio_reset;
int wait_pin; /* Optional GPMC_CONFIG1_WAITPINSELECT */
u32 flags;
int (*retime)(void);
};
#if defined(CONFIG_SMC91X) || \
defined(CONFIG_SMC91X_MODULE)
extern void gpmc_smc91x_init(struct omap_smc91x_platform_data *d);
#else
#define board_smc91x_data NULL
static inline void gpmc_smc91x_init(struct omap_smc91x_platform_data *d)
{
}
#endif
#endif

View File

@ -2,10 +2,6 @@
#define _HWA742_H
struct hwa742_platform_data {
void (*power_up)(struct device *dev);
void (*power_down)(struct device *dev);
unsigned long (*get_clock_rate)(struct device *dev);
unsigned te_connected:1;
};

View File

@ -9,8 +9,12 @@
* published by the Free Software Foundation.
*/
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#define ONENAND_SYNC_READ (1 << 0)
#define ONENAND_SYNC_READWRITE (1 << 1)
struct omap_onenand_platform_data {
int cs;
int gpio_irq;
@ -18,8 +22,22 @@ struct omap_onenand_platform_data {
int nr_parts;
int (*onenand_setup)(void __iomem *, int freq);
int dma_channel;
u8 flags;
};
int omap2_onenand_rephase(void);
#define ONENAND_MAX_PARTITIONS 8
#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
#else
#define board_onenand_data NULL
static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
{
}
#endif

View File

@ -17,5 +17,5 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
#define VMALLOC_END (PAGE_OFFSET + 0x18000000)

View File

@ -91,11 +91,20 @@ static void omap_mcbsp_dump_reg(u8 id)
static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
{
struct omap_mcbsp *mcbsp_tx = dev_id;
u16 irqst_spcr2;
dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n",
OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
irqst_spcr2 = OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2);
dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2);
complete(&mcbsp_tx->tx_irq_completion);
if (irqst_spcr2 & XSYNC_ERR) {
dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
irqst_spcr2);
/* Writing zero to XSYNC_ERR clears the IRQ */
OMAP_MCBSP_WRITE(mcbsp_tx->io_base, SPCR2,
irqst_spcr2 & ~(XSYNC_ERR));
} else {
complete(&mcbsp_tx->tx_irq_completion);
}
return IRQ_HANDLED;
}
@ -103,11 +112,20 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
{
struct omap_mcbsp *mcbsp_rx = dev_id;
u16 irqst_spcr1;
dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n",
OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
irqst_spcr1 = OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR1);
dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1);
complete(&mcbsp_rx->rx_irq_completion);
if (irqst_spcr1 & RSYNC_ERR) {
dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
irqst_spcr1);
/* Writing zero to RSYNC_ERR clears the IRQ */
OMAP_MCBSP_WRITE(mcbsp_rx->io_base, SPCR1,
irqst_spcr1 & ~(RSYNC_ERR));
} else {
complete(&mcbsp_rx->tx_irq_completion);
}
return IRQ_HANDLED;
}

View File

@ -38,8 +38,8 @@
#define OMAP1_SRAM_VA VMALLOC_END
#define OMAP2_SRAM_PA 0x40200000
#define OMAP2_SRAM_PUB_PA 0x4020f800
#define OMAP2_SRAM_VA VMALLOC_END
#define OMAP2_SRAM_PUB_VA (VMALLOC_END + 0x800)
#define OMAP2_SRAM_VA 0xe3000000
#define OMAP2_SRAM_PUB_VA (OMAP2_SRAM_VA + 0x800)
#define OMAP3_SRAM_PA 0x40200000
#define OMAP3_SRAM_VA 0xd7000000
#define OMAP3_SRAM_PUB_PA 0x40208000

View File

@ -133,8 +133,7 @@ struct {
struct lcd_ctrl_extif *extif;
struct lcd_ctrl *int_ctrl;
void (*power_up)(struct device *dev);
void (*power_down)(struct device *dev);
struct clk *sys_ck;
} hwa742;
struct lcd_ctrl hwa742_ctrl;
@ -915,14 +914,13 @@ static void hwa742_suspend(void)
hwa742_set_update_mode(OMAPFB_UPDATE_DISABLED);
/* Enable sleep mode */
hwa742_write_reg(HWA742_POWER_SAVE, 1 << 1);
if (hwa742.power_down != NULL)
hwa742.power_down(hwa742.fbdev->dev);
clk_disable(hwa742.sys_ck);
}
static void hwa742_resume(void)
{
if (hwa742.power_up != NULL)
hwa742.power_up(hwa742.fbdev->dev);
clk_enable(hwa742.sys_ck);
/* Disable sleep mode */
hwa742_write_reg(HWA742_POWER_SAVE, 0);
while (1) {
@ -955,14 +953,13 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
omapfb_conf = fbdev->dev->platform_data;
ctrl_conf = omapfb_conf->ctrl_platform_data;
if (ctrl_conf == NULL || ctrl_conf->get_clock_rate == NULL) {
if (ctrl_conf == NULL) {
dev_err(fbdev->dev, "HWA742: missing platform data\n");
r = -ENOENT;
goto err1;
}
hwa742.power_down = ctrl_conf->power_down;
hwa742.power_up = ctrl_conf->power_up;
hwa742.sys_ck = clk_get(NULL, "hwa_sys_ck");
spin_lock_init(&hwa742.req_lock);
@ -972,12 +969,11 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
if ((r = hwa742.extif->init(fbdev)) < 0)
goto err2;
ext_clk = ctrl_conf->get_clock_rate(fbdev->dev);
ext_clk = clk_get_rate(hwa742.sys_ck);
if ((r = calc_extif_timings(ext_clk, &extif_mem_div)) < 0)
goto err3;
hwa742.extif->set_timings(&hwa742.reg_timings);
if (hwa742.power_up != NULL)
hwa742.power_up(fbdev->dev);
clk_enable(hwa742.sys_ck);
calc_hwa742_clk_rates(ext_clk, &sys_clk, &pix_clk);
if ((r = calc_extif_timings(sys_clk, &extif_mem_div)) < 0)
@ -1040,8 +1036,7 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
return 0;
err4:
if (hwa742.power_down != NULL)
hwa742.power_down(fbdev->dev);
clk_disable(hwa742.sys_ck);
err3:
hwa742.extif->cleanup();
err2:
@ -1055,8 +1050,7 @@ static void hwa742_cleanup(void)
hwa742_set_update_mode(OMAPFB_UPDATE_DISABLED);
hwa742.extif->cleanup();
hwa742.int_ctrl->cleanup();
if (hwa742.power_down != NULL)
hwa742.power_down(hwa742.fbdev->dev);
clk_disable(hwa742.sys_ck);
}
struct lcd_ctrl hwa742_ctrl = {