board-omap3beagle.c 13.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
 * 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>
26
#include <linux/opp.h>
27 28 29 30

#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
31
#include <linux/mmc/host.h>
32

33
#include <linux/regulator/machine.h>
34
#include <linux/i2c/twl.h>
35

36 37 38 39 40
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>

41
#include "common.h"
42
#include <video/omapdss.h>
43
#include <video/omap-panel-tfp410.h>
44 45 46
#include <plat/gpmc.h>
#include <plat/nand.h>
#include <plat/usb.h>
47
#include <plat/omap_device.h>
48

49
#include "mux.h"
50
#include "hsmmc.h"
51
#include "pm.h"
52
#include "common-board-devices.h"
53

R
Robert Nelson 已提交
54 55 56 57 58 59 60
/*
 * OMAP3 Beagle revision
 * Run time detection of Beagle revision is done by reading GPIO.
 * GPIO ID -
 *	AXBX	= GPIO173, GPIO172, GPIO171: 1 1 1
 *	C1_3	= GPIO173, GPIO172, GPIO171: 1 1 0
 *	C4	= GPIO173, GPIO172, GPIO171: 1 0 1
61 62
 *	XMA/XMB = GPIO173, GPIO172, GPIO171: 0 0 0
 *	XMC = GPIO173, GPIO172, GPIO171: 0 1 0
R
Robert Nelson 已提交
63 64 65 66 67 68 69
 */
enum {
	OMAP3BEAGLE_BOARD_UNKN = 0,
	OMAP3BEAGLE_BOARD_AXBX,
	OMAP3BEAGLE_BOARD_C1_3,
	OMAP3BEAGLE_BOARD_C4,
	OMAP3BEAGLE_BOARD_XM,
70
	OMAP3BEAGLE_BOARD_XMC,
R
Robert Nelson 已提交
71 72 73 74
};

static u8 omap3_beagle_version;

75 76 77 78 79 80 81
/*
 * Board-specific configuration
 * Defaults to BeagleBoard-xMC
 */
static struct {
	int mmc1_gpio_wp;
	int usb_pwr_level;
82
	int dvi_pd_gpio;
83
	int usr_button_gpio;
84
	int mmc_caps;
85 86 87
} beagle_config = {
	.mmc1_gpio_wp = -EINVAL,
	.usb_pwr_level = GPIOF_OUT_INIT_LOW,
88
	.dvi_pd_gpio = -EINVAL,
89
	.usr_button_gpio = 4,
90
	.mmc_caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
91
};
R
Robert Nelson 已提交
92

I
Igor Grinberg 已提交
93 94 95 96 97 98
static struct gpio omap3_beagle_rev_gpios[] __initdata = {
	{ 171, GPIOF_IN, "rev_id_0"    },
	{ 172, GPIOF_IN, "rev_id_1" },
	{ 173, GPIOF_IN, "rev_id_2"    },
};

R
Robert Nelson 已提交
99 100 101 102 103 104 105 106 107
static void __init omap3_beagle_init_rev(void)
{
	int ret;
	u16 beagle_rev = 0;

	omap_mux_init_gpio(171, OMAP_PIN_INPUT_PULLUP);
	omap_mux_init_gpio(172, OMAP_PIN_INPUT_PULLUP);
	omap_mux_init_gpio(173, OMAP_PIN_INPUT_PULLUP);

I
Igor Grinberg 已提交
108 109 110 111 112 113 114
	ret = gpio_request_array(omap3_beagle_rev_gpios,
				 ARRAY_SIZE(omap3_beagle_rev_gpios));
	if (ret < 0) {
		printk(KERN_ERR "Unable to get revision detection GPIO pins\n");
		omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
		return;
	}
R
Robert Nelson 已提交
115 116 117 118

	beagle_rev = gpio_get_value(171) | (gpio_get_value(172) << 1)
			| (gpio_get_value(173) << 2);

119 120 121
	gpio_free_array(omap3_beagle_rev_gpios,
			ARRAY_SIZE(omap3_beagle_rev_gpios));

R
Robert Nelson 已提交
122 123 124 125
	switch (beagle_rev) {
	case 7:
		printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n");
		omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX;
126
		beagle_config.mmc1_gpio_wp = 29;
127
		beagle_config.dvi_pd_gpio = 170;
128
		beagle_config.usr_button_gpio = 7;
R
Robert Nelson 已提交
129 130 131 132
		break;
	case 6:
		printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n");
		omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3;
133
		beagle_config.mmc1_gpio_wp = 23;
134
		beagle_config.dvi_pd_gpio = 170;
135
		beagle_config.usr_button_gpio = 7;
R
Robert Nelson 已提交
136 137 138 139
		break;
	case 5:
		printk(KERN_INFO "OMAP3 Beagle Rev: C4\n");
		omap3_beagle_version = OMAP3BEAGLE_BOARD_C4;
140
		beagle_config.mmc1_gpio_wp = 23;
141
		beagle_config.dvi_pd_gpio = 170;
142
		beagle_config.usr_button_gpio = 7;
R
Robert Nelson 已提交
143 144
		break;
	case 0:
145
		printk(KERN_INFO "OMAP3 Beagle Rev: xM Ax/Bx\n");
R
Robert Nelson 已提交
146
		omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
147
		beagle_config.usb_pwr_level = GPIOF_OUT_INIT_HIGH;
148
		beagle_config.mmc_caps &= ~MMC_CAP_8_BIT_DATA;
149 150 151 152
		break;
	case 2:
		printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
		omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
153
		beagle_config.mmc_caps &= ~MMC_CAP_8_BIT_DATA;
R
Robert Nelson 已提交
154 155 156 157 158 159 160
		break;
	default:
		printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
		omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
	}
}

161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
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,
	},
};

K
Koen Kooi 已提交
192 193
/* DSS */

194
static struct tfp410_platform_data dvi_panel = {
195
	.i2c_bus_num = 3,
196
	.power_down_gpio = -1,
197 198
};

K
Koen Kooi 已提交
199 200 201
static struct omap_dss_device beagle_dvi_device = {
	.type = OMAP_DISPLAY_TYPE_DPI,
	.name = "dvi",
202
	.driver_name = "tfp410",
203
	.data = &dvi_panel,
K
Koen Kooi 已提交
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
	.phy.dpi.data_lines = 24,
};

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,
};

225 226
#include "sdram-micron-mt46h32m32lf-6.h"

227
static struct omap2_hsmmc_info mmc[] = {
228 229
	{
		.mmc		= 1,
230
		.caps		= MMC_CAP_4_BIT_DATA,
231
		.gpio_wp	= -EINVAL,
232
		.deferred	= true,
233 234 235 236
	},
	{}	/* Terminator */
};

237 238
static struct regulator_consumer_supply beagle_vmmc1_supply[] = {
	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
239 240
};

241 242
static struct regulator_consumer_supply beagle_vsim_supply[] = {
	REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
243 244
};

245 246 247 248 249
static struct gpio_led gpio_leds[];

static int beagle_twl_gpio_setup(struct device *dev,
		unsigned gpio, unsigned ngpio)
{
250 251 252
	int r;

	mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp;
253
	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
254
	mmc[0].gpio_cd = gpio + 0;
255
	omap_hsmmc_late_init(mmc);
256

257 258 259
	/*
	 * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
	 * high / others active low)
I
Igor Grinberg 已提交
260
	 * DVI reset GPIO is different between beagle revisions
K
Koen Kooi 已提交
261
	 */
262 263
	/* Valid for all -xM revisions */
	if (cpu_is_omap3630()) {
I
Igor Grinberg 已提交
264 265 266 267 268 269 270 271
		/*
		 * gpio + 1 on Xm controls the TFP410's enable line (active low)
		 * gpio + 2 control varies depending on the board rev as below:
		 * P7/P8 revisions(prototype): Camera EN
		 * A2+ revisions (production): LDO (DVI, serial, led blocks)
		 */
		r = gpio_request_one(gpio + 1, GPIOF_OUT_INIT_LOW,
				     "nDVI_PWR_EN");
K
Koen Kooi 已提交
272 273 274
		if (r)
			pr_err("%s: unable to configure nDVI_PWR_EN\n",
				__func__);
275 276 277

		beagle_config.dvi_pd_gpio = gpio + 2;

I
Igor Grinberg 已提交
278 279 280 281 282 283 284
	} else {
		/*
		 * REVISIT: need ehci-omap hooks for external VBUS
		 * power switch and overcurrent detect
		 */
		if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC"))
			pr_err("%s: unable to configure EHCI_nOC\n", __func__);
K
Koen Kooi 已提交
285
	}
286
	dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio;
K
Koen Kooi 已提交
287

288 289
	gpio_request_one(gpio + TWL4030_GPIO_MAX, beagle_config.usb_pwr_level,
			"nEN_USB_PWR");
I
Igor Grinberg 已提交
290 291 292 293

	/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
	gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;

294 295 296 297 298 299 300 301 302 303 304
	return 0;
}

static struct twl4030_gpio_platform_data beagle_gpio_data = {
	.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,
};

305 306 307 308 309 310 311 312 313 314 315
/* 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,
	},
316 317
	.num_consumer_supplies	= ARRAY_SIZE(beagle_vmmc1_supply),
	.consumer_supplies	= beagle_vmmc1_supply,
318 319 320 321 322 323 324 325 326 327 328 329 330
};

/* 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,
	},
331 332
	.num_consumer_supplies	= ARRAY_SIZE(beagle_vsim_supply),
	.consumer_supplies	= beagle_vsim_supply,
333 334
};

335 336 337
static struct twl4030_platform_data beagle_twldata = {
	/* platform_data for children goes here */
	.gpio		= &beagle_gpio_data,
338 339
	.vmmc1		= &beagle_vmmc1,
	.vsim		= &beagle_vsim,
340 341
};

342 343 344 345 346 347
static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
       {
               I2C_BOARD_INFO("eeprom", 0x50),
       },
};

348 349
static int __init omap3_beagle_i2c_init(void)
{
350
	omap3_pmic_get_config(&beagle_twldata,
351 352
			TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_MADC |
			TWL_COMMON_PDATA_AUDIO,
353 354 355 356
			TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2);

	beagle_twldata.vpll2->constraints.name = "VDVI";

357
	omap3_pmic_init("twl4030", &beagle_twldata);
358 359
	/* Bus 3 is attached to the DVI port where devices like the pico DLP
	 * projector don't work reliably with 400kHz */
360
	omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom));
361 362 363
	return 0;
}

364 365 366 367 368 369 370 371 372 373 374
static struct gpio_led gpio_leds[] = {
	{
		.name			= "beagleboard::usr0",
		.default_trigger	= "heartbeat",
		.gpio			= 150,
	},
	{
		.name			= "beagleboard::usr1",
		.default_trigger	= "mmc0",
		.gpio			= 149,
	},
375 376 377 378 379
	{
		.name			= "beagleboard::pmu_stat",
		.gpio			= -EINVAL,	/* gets replaced */
		.active_low		= true,
	},
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
};

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,
398 399
		/* Dynamically assigned depending on board */
		.gpio			= -EINVAL,
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
		.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,
	},
};

418 419 420 421 422
static struct platform_device madc_hwmon = {
	.name	= "twl4030_madc_hwmon",
	.id	= -1,
};

423 424 425
static struct platform_device *omap3_beagle_devices[] __initdata = {
	&leds_gpio,
	&keys_gpio,
426
	&madc_hwmon,
427 428
};

429
static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
430

431
	.port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
432 433
	.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
	.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
434 435 436 437 438 439 440

	.phy_reset  = true,
	.reset_gpio_port[0]  = -EINVAL,
	.reset_gpio_port[1]  = 147,
	.reset_gpio_port[2]  = -EINVAL
};

441 442 443 444 445 446
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
	{ .reg_offset = OMAP_MUX_TERMINATOR },
};
#endif

447 448 449 450 451 452 453 454 455 456
static void __init beagle_opp_init(void)
{
	int r = 0;

	/* Initialize the omap3 opp table */
	if (omap3_opp_init()) {
		pr_err("%s: opp default init failed\n", __func__);
		return;
	}

457 458
	/* Custom OPP enabled for all xM versions */
	if (cpu_is_omap3630()) {
459
		struct device *mpu_dev, *iva_dev;
460

461 462
		mpu_dev = omap_device_get_by_hwmod_name("mpu");
		iva_dev = omap_device_get_by_hwmod_name("iva");
463 464

		if (!mpu_dev || !iva_dev) {
465
			pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
466
				__func__, mpu_dev, iva_dev);
467 468 469
			return;
		}
		/* Enable MPU 1GHz and lower opps */
470
		r = opp_enable(mpu_dev, 800000000);
471 472 473
		/* TODO: MPU 1GHz needs SR and ABB */

		/* Enable IVA 800MHz and lower opps */
474
		r |= opp_enable(iva_dev, 660000000);
475 476 477 478 479 480 481 482
		/* TODO: DSP 800MHz needs SR and ABB */
		if (r) {
			pr_err("%s: failed to enable higher opp %d\n",
				__func__, r);
			/*
			 * Cleanup - disable the higher freqs - we dont care
			 * about the results
			 */
483 484
			opp_disable(mpu_dev, 800000000);
			opp_disable(iva_dev, 660000000);
485 486 487 488 489
		}
	}
	return;
}

490 491
static void __init omap3_beagle_init(void)
{
492
	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
R
Robert Nelson 已提交
493
	omap3_beagle_init_rev();
494

495
	if (gpio_is_valid(beagle_config.mmc1_gpio_wp))
496
		omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
497
	mmc[0].caps = beagle_config.mmc_caps;
498
	omap_hsmmc_init(mmc);
499

500
	omap3_beagle_i2c_init();
501 502 503

	gpio_buttons[0].gpio = beagle_config.usr_button_gpio;

504 505
	platform_add_devices(omap3_beagle_devices,
			ARRAY_SIZE(omap3_beagle_devices));
506 507
	if (gpio_is_valid(beagle_config.dvi_pd_gpio))
		omap_mux_init_gpio(beagle_config.dvi_pd_gpio, OMAP_PIN_OUTPUT);
508
	omap_display_init(&beagle_dss_data);
509
	omap_serial_init();
510 511
	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
				  mt46h32m32lf6_sdrc_params);
512

513
	usb_musb_init(NULL);
514
	usbhs_init(&usbhs_bdata);
515 516
	omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions,
			     ARRAY_SIZE(omap3beagle_nand_partitions));
517

518 519 520
	/* Ensure msecure is mux'd to be able to set the RTC. */
	omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH);

521
	/* Ensure SDRC pins are mux'd for self-refresh */
522 523
	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
	omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
K
Koen Kooi 已提交
524

525
	beagle_opp_init();
526 527 528 529
}

MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
	/* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
530
	.atag_offset	= 0x100,
531
	.reserve	= omap_reserve,
532
	.map_io		= omap3_map_io,
533
	.init_early	= omap3_init_early,
534
	.init_irq	= omap3_init_irq,
535
	.handle_irq	= omap3_intc_handle_irq,
536
	.init_machine	= omap3_beagle_init,
537
	.init_late	= omap3_init_late,
538
	.timer		= &omap3_secure_timer,
539
	.restart	= omap_prcm_restart,
540
MACHINE_END