board-omap3beagle.c 13.8 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
#include <linux/cpu.h>
28 29 30 31

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

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

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

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

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

R
Robert Nelson 已提交
55 56 57 58 59 60 61
/*
 * 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
62 63
 *	XMA/XMB = GPIO173, GPIO172, GPIO171: 0 0 0
 *	XMC = GPIO173, GPIO172, GPIO171: 0 1 0
R
Robert Nelson 已提交
64 65 66 67 68 69 70
 */
enum {
	OMAP3BEAGLE_BOARD_UNKN = 0,
	OMAP3BEAGLE_BOARD_AXBX,
	OMAP3BEAGLE_BOARD_C1_3,
	OMAP3BEAGLE_BOARD_C4,
	OMAP3BEAGLE_BOARD_XM,
71
	OMAP3BEAGLE_BOARD_XMC,
R
Robert Nelson 已提交
72 73 74 75
};

static u8 omap3_beagle_version;

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

I
Igor Grinberg 已提交
94 95 96 97 98 99
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 已提交
100 101 102 103 104 105 106 107 108
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 已提交
109 110 111 112 113 114 115
	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 已提交
116 117 118 119

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

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

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

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 192
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 已提交
193 194
/* DSS */

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

K
Koen Kooi 已提交
200 201 202
static struct omap_dss_device beagle_dvi_device = {
	.type = OMAP_DISPLAY_TYPE_DPI,
	.name = "dvi",
203
	.driver_name = "tfp410",
204
	.data = &dvi_panel,
K
Koen Kooi 已提交
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
	.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,
};

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

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

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

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

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

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

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

258 259 260
	/*
	 * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
	 * high / others active low)
I
Igor Grinberg 已提交
261
	 * DVI reset GPIO is different between beagle revisions
K
Koen Kooi 已提交
262
	 */
263 264
	/* Valid for all -xM revisions */
	if (cpu_is_omap3630()) {
I
Igor Grinberg 已提交
265 266 267 268 269 270 271 272
		/*
		 * 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 已提交
273 274 275
		if (r)
			pr_err("%s: unable to configure nDVI_PWR_EN\n",
				__func__);
276 277 278

		beagle_config.dvi_pd_gpio = gpio + 2;

I
Igor Grinberg 已提交
279 280 281 282 283 284 285
	} 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 已提交
286
	}
287
	dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio;
K
Koen Kooi 已提交
288

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

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

295 296 297 298 299 300 301 302 303 304 305
	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,
};

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

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

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

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

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

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

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

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

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

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

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

430
static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
431

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

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

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

448
static int __init beagle_opp_init(void)
449 450 451
{
	int r = 0;

452 453 454 455 456 457
	if (!machine_is_omap3_beagle())
		return 0;

	/* Initialize the omap3 opp table if not already created. */
	r = omap3_opp_init();
	if (IS_ERR_VALUE(r) && (r != -EEXIST)) {
458
		pr_err("%s: opp default init failed\n", __func__);
459
		return r;
460 461
	}

462 463
	/* Custom OPP enabled for all xM versions */
	if (cpu_is_omap3630()) {
464
		struct device *mpu_dev, *iva_dev;
465

466
		mpu_dev = get_cpu_device(0);
467
		iva_dev = omap_device_get_by_hwmod_name("iva");
468

469
		if (IS_ERR(mpu_dev) || IS_ERR(iva_dev)) {
470
			pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
471
				__func__, mpu_dev, iva_dev);
472
			return -ENODEV;
473 474
		}
		/* Enable MPU 1GHz and lower opps */
475
		r = opp_enable(mpu_dev, 800000000);
476 477 478
		/* TODO: MPU 1GHz needs SR and ABB */

		/* Enable IVA 800MHz and lower opps */
479
		r |= opp_enable(iva_dev, 660000000);
480 481 482 483 484 485 486 487
		/* 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
			 */
488 489
			opp_disable(mpu_dev, 800000000);
			opp_disable(iva_dev, 660000000);
490 491
		}
	}
492
	return 0;
493
}
494
device_initcall(beagle_opp_init);
495

496 497
static void __init omap3_beagle_init(void)
{
498
	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
R
Robert Nelson 已提交
499
	omap3_beagle_init_rev();
500

501
	if (gpio_is_valid(beagle_config.mmc1_gpio_wp))
502
		omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
503
	mmc[0].caps = beagle_config.mmc_caps;
504
	omap_hsmmc_init(mmc);
505

506
	omap3_beagle_i2c_init();
507 508 509

	gpio_buttons[0].gpio = beagle_config.usr_button_gpio;

510 511
	platform_add_devices(omap3_beagle_devices,
			ARRAY_SIZE(omap3_beagle_devices));
512 513
	if (gpio_is_valid(beagle_config.dvi_pd_gpio))
		omap_mux_init_gpio(beagle_config.dvi_pd_gpio, OMAP_PIN_OUTPUT);
514
	omap_display_init(&beagle_dss_data);
515
	omap_serial_init();
516 517
	omap_sdrc_init(mt46h32m32lf6_sdrc_params,
				  mt46h32m32lf6_sdrc_params);
518

519
	usb_musb_init(NULL);
520
	usbhs_init(&usbhs_bdata);
521 522
	omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions,
			     ARRAY_SIZE(omap3beagle_nand_partitions));
523
	omap_twl4030_audio_init("omap3beagle");
524

525 526 527
	/* Ensure msecure is mux'd to be able to set the RTC. */
	omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH);

528
	/* Ensure SDRC pins are mux'd for self-refresh */
529 530
	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
	omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
531 532 533 534
}

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