forked from Minki/linux
c573bcf96a
The only difference between them is the physical address of the uart4 port, which is only present in 36xx chips. We don't really need to care about keeping these 2 functions, since the decision to use uart4 is more cleanly done later when we do have access to omap_revision variable. Signed-off-by: Sergio Aguirre <saaguirre@ti.com> Acked-by: Kevin Hilman <khilman@deeprootsystems.com> [tony@atomide.com: added comment for the uart4_phys] Signed-off-by: Tony Lindgren <tony@atomide.com>
527 lines
13 KiB
C
527 lines
13 KiB
C
/*
|
|
* linux/arch/arm/mach-omap2/board-omap3beagle.c
|
|
*
|
|
* Copyright (C) 2008 Texas Instruments
|
|
*
|
|
* Modified from mach-omap2/board-3430sdp.c
|
|
*
|
|
* Initial code: Syed Mohammed Khasim
|
|
*
|
|
* 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/init.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/err.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/io.h>
|
|
#include <linux/leds.h>
|
|
#include <linux/gpio.h>
|
|
#include <linux/input.h>
|
|
#include <linux/gpio_keys.h>
|
|
|
|
#include <linux/mtd/mtd.h>
|
|
#include <linux/mtd/partitions.h>
|
|
#include <linux/mtd/nand.h>
|
|
|
|
#include <linux/regulator/machine.h>
|
|
#include <linux/i2c/twl.h>
|
|
|
|
#include <mach/hardware.h>
|
|
#include <asm/mach-types.h>
|
|
#include <asm/mach/arch.h>
|
|
#include <asm/mach/map.h>
|
|
#include <asm/mach/flash.h>
|
|
|
|
#include <plat/board.h>
|
|
#include <plat/common.h>
|
|
#include <plat/display.h>
|
|
#include <plat/gpmc.h>
|
|
#include <plat/nand.h>
|
|
#include <plat/usb.h>
|
|
#include <plat/timer-gp.h>
|
|
|
|
#include "mux.h"
|
|
#include "hsmmc.h"
|
|
|
|
#define GPMC_CS0_BASE 0x60
|
|
#define GPMC_CS_SIZE 0x30
|
|
|
|
#define NAND_BLOCK_SIZE SZ_128K
|
|
|
|
static struct mtd_partition omap3beagle_nand_partitions[] = {
|
|
/* All the partition sizes are listed in terms of NAND block size */
|
|
{
|
|
.name = "X-Loader",
|
|
.offset = 0,
|
|
.size = 4 * NAND_BLOCK_SIZE,
|
|
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
|
},
|
|
{
|
|
.name = "U-Boot",
|
|
.offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
|
|
.size = 15 * NAND_BLOCK_SIZE,
|
|
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
|
},
|
|
{
|
|
.name = "U-Boot Env",
|
|
.offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
|
|
.size = 1 * NAND_BLOCK_SIZE,
|
|
},
|
|
{
|
|
.name = "Kernel",
|
|
.offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
|
|
.size = 32 * NAND_BLOCK_SIZE,
|
|
},
|
|
{
|
|
.name = "File System",
|
|
.offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
|
|
.size = MTDPART_SIZ_FULL,
|
|
},
|
|
};
|
|
|
|
static struct omap_nand_platform_data omap3beagle_nand_data = {
|
|
.options = NAND_BUSWIDTH_16,
|
|
.parts = omap3beagle_nand_partitions,
|
|
.nr_parts = ARRAY_SIZE(omap3beagle_nand_partitions),
|
|
.dma_channel = -1, /* disable DMA in OMAP NAND driver */
|
|
.nand_setup = NULL,
|
|
.dev_ready = NULL,
|
|
};
|
|
|
|
static struct resource omap3beagle_nand_resource = {
|
|
.flags = IORESOURCE_MEM,
|
|
};
|
|
|
|
static struct platform_device omap3beagle_nand_device = {
|
|
.name = "omap2-nand",
|
|
.id = -1,
|
|
.dev = {
|
|
.platform_data = &omap3beagle_nand_data,
|
|
},
|
|
.num_resources = 1,
|
|
.resource = &omap3beagle_nand_resource,
|
|
};
|
|
|
|
/* DSS */
|
|
|
|
static int beagle_enable_dvi(struct omap_dss_device *dssdev)
|
|
{
|
|
if (gpio_is_valid(dssdev->reset_gpio))
|
|
gpio_set_value(dssdev->reset_gpio, 1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void beagle_disable_dvi(struct omap_dss_device *dssdev)
|
|
{
|
|
if (gpio_is_valid(dssdev->reset_gpio))
|
|
gpio_set_value(dssdev->reset_gpio, 0);
|
|
}
|
|
|
|
static struct omap_dss_device beagle_dvi_device = {
|
|
.type = OMAP_DISPLAY_TYPE_DPI,
|
|
.name = "dvi",
|
|
.driver_name = "generic_panel",
|
|
.phy.dpi.data_lines = 24,
|
|
.reset_gpio = 170,
|
|
.platform_enable = beagle_enable_dvi,
|
|
.platform_disable = beagle_disable_dvi,
|
|
};
|
|
|
|
static struct omap_dss_device beagle_tv_device = {
|
|
.name = "tv",
|
|
.driver_name = "venc",
|
|
.type = OMAP_DISPLAY_TYPE_VENC,
|
|
.phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
|
|
};
|
|
|
|
static struct omap_dss_device *beagle_dss_devices[] = {
|
|
&beagle_dvi_device,
|
|
&beagle_tv_device,
|
|
};
|
|
|
|
static struct omap_dss_board_info beagle_dss_data = {
|
|
.num_devices = ARRAY_SIZE(beagle_dss_devices),
|
|
.devices = beagle_dss_devices,
|
|
.default_device = &beagle_dvi_device,
|
|
};
|
|
|
|
static struct platform_device beagle_dss_device = {
|
|
.name = "omapdss",
|
|
.id = -1,
|
|
.dev = {
|
|
.platform_data = &beagle_dss_data,
|
|
},
|
|
};
|
|
|
|
static struct regulator_consumer_supply beagle_vdac_supply =
|
|
REGULATOR_SUPPLY("vdda_dac", "omapdss");
|
|
|
|
static struct regulator_consumer_supply beagle_vdvi_supply =
|
|
REGULATOR_SUPPLY("vdds_dsi", "omapdss");
|
|
|
|
static void __init beagle_display_init(void)
|
|
{
|
|
int r;
|
|
|
|
r = gpio_request(beagle_dvi_device.reset_gpio, "DVI reset");
|
|
if (r < 0) {
|
|
printk(KERN_ERR "Unable to get DVI reset GPIO\n");
|
|
return;
|
|
}
|
|
|
|
gpio_direction_output(beagle_dvi_device.reset_gpio, 0);
|
|
}
|
|
|
|
#include "sdram-micron-mt46h32m32lf-6.h"
|
|
|
|
static struct omap2_hsmmc_info mmc[] = {
|
|
{
|
|
.mmc = 1,
|
|
.wires = 8,
|
|
.gpio_wp = 29,
|
|
},
|
|
{} /* Terminator */
|
|
};
|
|
|
|
static struct regulator_consumer_supply beagle_vmmc1_supply = {
|
|
.supply = "vmmc",
|
|
};
|
|
|
|
static struct regulator_consumer_supply beagle_vsim_supply = {
|
|
.supply = "vmmc_aux",
|
|
};
|
|
|
|
static struct gpio_led gpio_leds[];
|
|
|
|
static int beagle_twl_gpio_setup(struct device *dev,
|
|
unsigned gpio, unsigned ngpio)
|
|
{
|
|
if (system_rev >= 0x20 && system_rev <= 0x34301000) {
|
|
omap_mux_init_gpio(23, OMAP_PIN_INPUT);
|
|
mmc[0].gpio_wp = 23;
|
|
} else {
|
|
omap_mux_init_gpio(29, OMAP_PIN_INPUT);
|
|
}
|
|
/* gpio + 0 is "mmc0_cd" (input/IRQ) */
|
|
mmc[0].gpio_cd = gpio + 0;
|
|
omap2_hsmmc_init(mmc);
|
|
|
|
/* link regulators to MMC adapters */
|
|
beagle_vmmc1_supply.dev = mmc[0].dev;
|
|
beagle_vsim_supply.dev = mmc[0].dev;
|
|
|
|
/* REVISIT: need ehci-omap hooks for external VBUS
|
|
* power switch and overcurrent detect
|
|
*/
|
|
|
|
gpio_request(gpio + 1, "EHCI_nOC");
|
|
gpio_direction_input(gpio + 1);
|
|
|
|
/* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
|
|
gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
|
|
gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
|
|
|
|
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
|
|
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct twl4030_gpio_platform_data beagle_gpio_data = {
|
|
.gpio_base = OMAP_MAX_GPIO_LINES,
|
|
.irq_base = TWL4030_GPIO_IRQ_BASE,
|
|
.irq_end = TWL4030_GPIO_IRQ_END,
|
|
.use_leds = true,
|
|
.pullups = BIT(1),
|
|
.pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
|
|
| BIT(15) | BIT(16) | BIT(17),
|
|
.setup = beagle_twl_gpio_setup,
|
|
};
|
|
|
|
/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
|
|
static struct regulator_init_data beagle_vmmc1 = {
|
|
.constraints = {
|
|
.min_uV = 1850000,
|
|
.max_uV = 3150000,
|
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
|
| REGULATOR_MODE_STANDBY,
|
|
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
|
|
| REGULATOR_CHANGE_MODE
|
|
| REGULATOR_CHANGE_STATUS,
|
|
},
|
|
.num_consumer_supplies = 1,
|
|
.consumer_supplies = &beagle_vmmc1_supply,
|
|
};
|
|
|
|
/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
|
|
static struct regulator_init_data beagle_vsim = {
|
|
.constraints = {
|
|
.min_uV = 1800000,
|
|
.max_uV = 3000000,
|
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
|
| REGULATOR_MODE_STANDBY,
|
|
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
|
|
| REGULATOR_CHANGE_MODE
|
|
| REGULATOR_CHANGE_STATUS,
|
|
},
|
|
.num_consumer_supplies = 1,
|
|
.consumer_supplies = &beagle_vsim_supply,
|
|
};
|
|
|
|
/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
|
|
static struct regulator_init_data beagle_vdac = {
|
|
.constraints = {
|
|
.min_uV = 1800000,
|
|
.max_uV = 1800000,
|
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
|
| REGULATOR_MODE_STANDBY,
|
|
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
|
| REGULATOR_CHANGE_STATUS,
|
|
},
|
|
.num_consumer_supplies = 1,
|
|
.consumer_supplies = &beagle_vdac_supply,
|
|
};
|
|
|
|
/* VPLL2 for digital video outputs */
|
|
static struct regulator_init_data beagle_vpll2 = {
|
|
.constraints = {
|
|
.name = "VDVI",
|
|
.min_uV = 1800000,
|
|
.max_uV = 1800000,
|
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
|
| REGULATOR_MODE_STANDBY,
|
|
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
|
| REGULATOR_CHANGE_STATUS,
|
|
},
|
|
.num_consumer_supplies = 1,
|
|
.consumer_supplies = &beagle_vdvi_supply,
|
|
};
|
|
|
|
static struct twl4030_usb_data beagle_usb_data = {
|
|
.usb_mode = T2_USB_MODE_ULPI,
|
|
};
|
|
|
|
static struct twl4030_codec_audio_data beagle_audio_data = {
|
|
.audio_mclk = 26000000,
|
|
};
|
|
|
|
static struct twl4030_codec_data beagle_codec_data = {
|
|
.audio_mclk = 26000000,
|
|
.audio = &beagle_audio_data,
|
|
};
|
|
|
|
static struct twl4030_platform_data beagle_twldata = {
|
|
.irq_base = TWL4030_IRQ_BASE,
|
|
.irq_end = TWL4030_IRQ_END,
|
|
|
|
/* platform_data for children goes here */
|
|
.usb = &beagle_usb_data,
|
|
.gpio = &beagle_gpio_data,
|
|
.codec = &beagle_codec_data,
|
|
.vmmc1 = &beagle_vmmc1,
|
|
.vsim = &beagle_vsim,
|
|
.vdac = &beagle_vdac,
|
|
.vpll2 = &beagle_vpll2,
|
|
};
|
|
|
|
static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
|
|
{
|
|
I2C_BOARD_INFO("twl4030", 0x48),
|
|
.flags = I2C_CLIENT_WAKE,
|
|
.irq = INT_34XX_SYS_NIRQ,
|
|
.platform_data = &beagle_twldata,
|
|
},
|
|
};
|
|
|
|
static int __init omap3_beagle_i2c_init(void)
|
|
{
|
|
omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
|
|
ARRAY_SIZE(beagle_i2c_boardinfo));
|
|
/* Bus 3 is attached to the DVI port where devices like the pico DLP
|
|
* projector don't work reliably with 400kHz */
|
|
omap_register_i2c_bus(3, 100, NULL, 0);
|
|
return 0;
|
|
}
|
|
|
|
static struct gpio_led gpio_leds[] = {
|
|
{
|
|
.name = "beagleboard::usr0",
|
|
.default_trigger = "heartbeat",
|
|
.gpio = 150,
|
|
},
|
|
{
|
|
.name = "beagleboard::usr1",
|
|
.default_trigger = "mmc0",
|
|
.gpio = 149,
|
|
},
|
|
{
|
|
.name = "beagleboard::pmu_stat",
|
|
.gpio = -EINVAL, /* gets replaced */
|
|
.active_low = true,
|
|
},
|
|
};
|
|
|
|
static struct gpio_led_platform_data gpio_led_info = {
|
|
.leds = gpio_leds,
|
|
.num_leds = ARRAY_SIZE(gpio_leds),
|
|
};
|
|
|
|
static struct platform_device leds_gpio = {
|
|
.name = "leds-gpio",
|
|
.id = -1,
|
|
.dev = {
|
|
.platform_data = &gpio_led_info,
|
|
},
|
|
};
|
|
|
|
static struct gpio_keys_button gpio_buttons[] = {
|
|
{
|
|
.code = BTN_EXTRA,
|
|
.gpio = 7,
|
|
.desc = "user",
|
|
.wakeup = 1,
|
|
},
|
|
};
|
|
|
|
static struct gpio_keys_platform_data gpio_key_info = {
|
|
.buttons = gpio_buttons,
|
|
.nbuttons = ARRAY_SIZE(gpio_buttons),
|
|
};
|
|
|
|
static struct platform_device keys_gpio = {
|
|
.name = "gpio-keys",
|
|
.id = -1,
|
|
.dev = {
|
|
.platform_data = &gpio_key_info,
|
|
},
|
|
};
|
|
|
|
static void __init omap3_beagle_init_irq(void)
|
|
{
|
|
omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
|
|
mt46h32m32lf6_sdrc_params);
|
|
omap_init_irq();
|
|
#ifdef CONFIG_OMAP_32K_TIMER
|
|
omap2_gp_clockevent_set_gptimer(12);
|
|
#endif
|
|
omap_gpio_init();
|
|
}
|
|
|
|
static struct platform_device *omap3_beagle_devices[] __initdata = {
|
|
&leds_gpio,
|
|
&keys_gpio,
|
|
&beagle_dss_device,
|
|
};
|
|
|
|
static void __init omap3beagle_flash_init(void)
|
|
{
|
|
u8 cs = 0;
|
|
u8 nandcs = GPMC_CS_NUM + 1;
|
|
|
|
u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
|
|
|
|
/* find out the chip-select on which NAND exists */
|
|
while (cs < GPMC_CS_NUM) {
|
|
u32 ret = 0;
|
|
ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
|
|
|
|
if ((ret & 0xC00) == 0x800) {
|
|
printk(KERN_INFO "Found NAND on CS%d\n", cs);
|
|
if (nandcs > GPMC_CS_NUM)
|
|
nandcs = cs;
|
|
}
|
|
cs++;
|
|
}
|
|
|
|
if (nandcs > GPMC_CS_NUM) {
|
|
printk(KERN_INFO "NAND: Unable to find configuration "
|
|
"in GPMC\n ");
|
|
return;
|
|
}
|
|
|
|
if (nandcs < GPMC_CS_NUM) {
|
|
omap3beagle_nand_data.cs = nandcs;
|
|
omap3beagle_nand_data.gpmc_cs_baseaddr = (void *)
|
|
(gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE);
|
|
omap3beagle_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add);
|
|
|
|
printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
|
|
if (platform_device_register(&omap3beagle_nand_device) < 0)
|
|
printk(KERN_ERR "Unable to register NAND device\n");
|
|
}
|
|
}
|
|
|
|
static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
|
|
|
|
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
|
|
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
|
|
.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
|
|
|
|
.phy_reset = true,
|
|
.reset_gpio_port[0] = -EINVAL,
|
|
.reset_gpio_port[1] = 147,
|
|
.reset_gpio_port[2] = -EINVAL
|
|
};
|
|
|
|
#ifdef CONFIG_OMAP_MUX
|
|
static struct omap_board_mux board_mux[] __initdata = {
|
|
{ .reg_offset = OMAP_MUX_TERMINATOR },
|
|
};
|
|
#else
|
|
#define board_mux NULL
|
|
#endif
|
|
|
|
static struct omap_musb_board_data musb_board_data = {
|
|
.interface_type = MUSB_INTERFACE_ULPI,
|
|
.mode = MUSB_OTG,
|
|
.power = 100,
|
|
};
|
|
|
|
static void __init omap3_beagle_init(void)
|
|
{
|
|
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
|
|
omap3_beagle_i2c_init();
|
|
platform_add_devices(omap3_beagle_devices,
|
|
ARRAY_SIZE(omap3_beagle_devices));
|
|
omap_serial_init();
|
|
|
|
omap_mux_init_gpio(170, OMAP_PIN_INPUT);
|
|
gpio_request(170, "DVI_nPD");
|
|
/* REVISIT leave DVI powered down until it's needed ... */
|
|
gpio_direction_output(170, true);
|
|
|
|
usb_musb_init(&musb_board_data);
|
|
usb_ehci_init(&ehci_pdata);
|
|
omap3beagle_flash_init();
|
|
|
|
/* Ensure SDRC pins are mux'd for self-refresh */
|
|
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
|
|
omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
|
|
|
|
beagle_display_init();
|
|
}
|
|
|
|
static void __init omap3_beagle_map_io(void)
|
|
{
|
|
omap2_set_globals_3xxx();
|
|
omap34xx_map_common_io();
|
|
}
|
|
|
|
MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
|
|
/* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
|
|
.phys_io = 0x48000000,
|
|
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
|
|
.boot_params = 0x80000100,
|
|
.map_io = omap3_beagle_map_io,
|
|
.reserve = omap_reserve,
|
|
.init_irq = omap3_beagle_init_irq,
|
|
.init_machine = omap3_beagle_init,
|
|
.timer = &omap_timer,
|
|
MACHINE_END
|