board-cpuimx51sd.c 8.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 26 27 28 29 30 31 32 33 34 35 36 37 38 39
/*
 *
 * Copyright (C) 2010 Eric Bénard <eric@eukrea.com>
 *
 * based on board-mx51_babbage.c which is
 * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
 * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
 *
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c/tsc2007.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/i2c-gpio.h>
#include <linux/spi/spi.h>
#include <linux/can/platform/mcp251x.h>

#include <mach/eukrea-baseboards.h>
#include <mach/common.h>
#include <mach/hardware.h>
#include <mach/iomux-mx51.h>

#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>

#include "devices-imx51.h"
E
Eric Bénard 已提交
40
#include "cpu_op-mx51.h"
41

A
Arnaud Patard (Rtp) 已提交
42 43 44 45 46 47 48 49 50 51 52 53 54
#define USBH1_RST		IMX_GPIO_NR(2, 28)
#define ETH_RST			IMX_GPIO_NR(2, 31)
#define TSC2007_IRQGPIO		IMX_GPIO_NR(3, 12)
#define CAN_IRQGPIO		IMX_GPIO_NR(1, 1)
#define CAN_RST			IMX_GPIO_NR(4, 15)
#define CAN_NCS			IMX_GPIO_NR(4, 24)
#define CAN_RXOBF		IMX_GPIO_NR(1, 4)
#define CAN_RX1BF		IMX_GPIO_NR(1, 6)
#define CAN_TXORTS		IMX_GPIO_NR(1, 7)
#define CAN_TX1RTS		IMX_GPIO_NR(1, 8)
#define CAN_TX2RTS		IMX_GPIO_NR(1, 9)
#define I2C_SCL			IMX_GPIO_NR(4, 16)
#define I2C_SDA			IMX_GPIO_NR(4, 17)
55 56 57 58 59 60 61 62 63

/* USB_CTRL_1 */
#define MX51_USB_CTRL_1_OFFSET		0x10
#define MX51_USB_CTRL_UH1_EXT_CLK_EN	(1 << 25)

#define	MX51_USB_PLLDIV_12_MHZ		0x00
#define	MX51_USB_PLL_DIV_19_2_MHZ	0x01
#define	MX51_USB_PLL_DIV_24_MHZ		0x02

64
static iomux_v3_cfg_t eukrea_cpuimx51sd_pads[] = {
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
	/* UART1 */
	MX51_PAD_UART1_RXD__UART1_RXD,
	MX51_PAD_UART1_TXD__UART1_TXD,
	MX51_PAD_UART1_RTS__UART1_RTS,
	MX51_PAD_UART1_CTS__UART1_CTS,

	/* USB HOST1 */
	MX51_PAD_USBH1_CLK__USBH1_CLK,
	MX51_PAD_USBH1_DIR__USBH1_DIR,
	MX51_PAD_USBH1_NXT__USBH1_NXT,
	MX51_PAD_USBH1_DATA0__USBH1_DATA0,
	MX51_PAD_USBH1_DATA1__USBH1_DATA1,
	MX51_PAD_USBH1_DATA2__USBH1_DATA2,
	MX51_PAD_USBH1_DATA3__USBH1_DATA3,
	MX51_PAD_USBH1_DATA4__USBH1_DATA4,
	MX51_PAD_USBH1_DATA5__USBH1_DATA5,
	MX51_PAD_USBH1_DATA6__USBH1_DATA6,
	MX51_PAD_USBH1_DATA7__USBH1_DATA7,
	MX51_PAD_USBH1_STP__USBH1_STP,
S
Sascha Hauer 已提交
84
	MX51_PAD_EIM_CS3__GPIO2_28,		/* PHY nRESET */
85 86

	/* FEC */
S
Sascha Hauer 已提交
87
	MX51_PAD_EIM_DTACK__GPIO2_31,		/* PHY nRESET */
88 89

	/* HSI2C */
S
Sascha Hauer 已提交
90 91
	MX51_PAD_I2C1_CLK__GPIO4_16,
	MX51_PAD_I2C1_DAT__GPIO4_17,
92 93 94 95 96

	/* CAN */
	MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI,
	MX51_PAD_CSPI1_MISO__ECSPI1_MISO,
	MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
S
Sascha Hauer 已提交
97 98 99 100 101 102 103 104
	MX51_PAD_CSPI1_SS0__GPIO4_24,		/* nCS */
	MX51_PAD_CSI2_PIXCLK__GPIO4_15,		/* nReset */
	MX51_PAD_GPIO1_1__GPIO1_1,		/* IRQ */
	MX51_PAD_GPIO1_4__GPIO1_4,		/* Control signals */
	MX51_PAD_GPIO1_6__GPIO1_6,
	MX51_PAD_GPIO1_7__GPIO1_7,
	MX51_PAD_GPIO1_8__GPIO1_8,
	MX51_PAD_GPIO1_9__GPIO1_9,
105 106

	/* Touchscreen */
S
Sascha Hauer 已提交
107
	/* IRQ */
108
	NEW_PAD_CTRL(MX51_PAD_GPIO_NAND__GPIO_NAND, PAD_CTL_PUS_22K_UP |
S
Sascha Hauer 已提交
109 110
			PAD_CTL_PKE | PAD_CTL_SRE_FAST |
			PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
};

static const struct imxuart_platform_data uart_pdata __initconst = {
	.flags = IMXUART_HAVE_RTSCTS,
};

static struct tsc2007_platform_data tsc2007_info = {
	.model			= 2007,
	.x_plate_ohms		= 180,
};

static struct i2c_board_info eukrea_cpuimx51sd_i2c_devices[] = {
	{
		I2C_BOARD_INFO("pcf8563", 0x51),
	}, {
		I2C_BOARD_INFO("tsc2007", 0x49),
		.type		= "tsc2007",
		.platform_data	= &tsc2007_info,
129
		.irq		= IMX_GPIO_TO_IRQ(TSC2007_IRQGPIO),
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
	},
};

static const struct mxc_nand_platform_data
		eukrea_cpuimx51sd_nand_board_info __initconst = {
	.width		= 1,
	.hw_ecc		= 1,
	.flash_bbt	= 1,
};

/* This function is board specific as the bit mask for the plldiv will also
be different for other Freescale SoCs, thus a common bitmask is not
possible and cannot get place in /plat-mxc/ehci.c.*/
static int initialize_otg_port(struct platform_device *pdev)
{
	u32 v;
	void __iomem *usb_base;
	void __iomem *usbother_base;

149
	usb_base = ioremap(MX51_USB_OTG_BASE_ADDR, SZ_4K);
150 151
	if (!usb_base)
		return -ENOMEM;
152 153 154 155 156 157 158 159
	usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;

	/* Set the PHY clock to 19.2MHz */
	v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
	v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK;
	v |= MX51_USB_PLL_DIV_19_2_MHZ;
	__raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
	iounmap(usb_base);
160 161 162 163

	mdelay(10);

	return mx51_initialize_usb_hw(0, MXC_EHCI_INTERNAL_PHY);
164 165 166 167 168 169 170 171
}

static int initialize_usbh1_port(struct platform_device *pdev)
{
	u32 v;
	void __iomem *usb_base;
	void __iomem *usbother_base;

172
	usb_base = ioremap(MX51_USB_OTG_BASE_ADDR, SZ_4K);
173 174
	if (!usb_base)
		return -ENOMEM;
175 176 177 178 179 180 181
	usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;

	/* The clock for the USBH1 ULPI port will come from the PHY. */
	v = __raw_readl(usbother_base + MX51_USB_CTRL_1_OFFSET);
	__raw_writel(v | MX51_USB_CTRL_UH1_EXT_CLK_EN,
			usbother_base + MX51_USB_CTRL_1_OFFSET);
	iounmap(usb_base);
182 183 184 185 186

	mdelay(10);

	return mx51_initialize_usb_hw(1, MXC_EHCI_POWER_PINS_ENABLED |
			MXC_EHCI_ITC_NO_THRESHOLD);
187 188
}

189
static const struct mxc_usbh_platform_data dr_utmi_config __initconst = {
190 191 192 193
	.init		= initialize_otg_port,
	.portsc	= MXC_EHCI_UTMI_16BIT,
};

194
static const struct fsl_usb2_platform_data usb_pdata __initconst = {
195 196 197 198
	.operating_mode	= FSL_USB2_DR_DEVICE,
	.phy_mode	= FSL_USB2_PHY_UTMI_WIDE,
};

199
static const struct mxc_usbh_platform_data usbh1_config __initconst = {
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
	.init		= initialize_usbh1_port,
	.portsc	= MXC_EHCI_MODE_ULPI,
};

static int otg_mode_host;

static int __init eukrea_cpuimx51sd_otg_mode(char *options)
{
	if (!strcmp(options, "host"))
		otg_mode_host = 1;
	else if (!strcmp(options, "device"))
		otg_mode_host = 0;
	else
		pr_info("otg_mode neither \"host\" nor \"device\". "
			"Defaulting to device\n");
	return 0;
}
__setup("otg_mode=", eukrea_cpuimx51sd_otg_mode);

static struct i2c_gpio_platform_data pdata = {
	.sda_pin		= I2C_SDA,
	.sda_is_open_drain	= 0,
	.scl_pin		= I2C_SCL,
	.scl_is_open_drain	= 0,
	.udelay			= 2,
};

static struct platform_device hsi2c_gpio_device = {
	.name			= "i2c-gpio",
	.id			= 0,
	.dev.platform_data	= &pdata,
};

static struct mcp251x_platform_data mcp251x_info = {
	.oscillator_frequency = 24E6,
};

static struct spi_board_info cpuimx51sd_spi_device[] = {
	{
		.modalias        = "mcp2515",
240
		.max_speed_hz    = 10000000,
241 242 243 244
		.bus_num         = 0,
		.mode		= SPI_MODE_0,
		.chip_select     = 0,
		.platform_data   = &mcp251x_info,
245
		.irq             = IMX_GPIO_TO_IRQ(CAN_IRQGPIO)
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
	},
};

static int cpuimx51sd_spi1_cs[] = {
	CAN_NCS,
};

static const struct spi_imx_master cpuimx51sd_ecspi1_pdata __initconst = {
	.chipselect	= cpuimx51sd_spi1_cs,
	.num_chipselect	= ARRAY_SIZE(cpuimx51sd_spi1_cs),
};

static struct platform_device *platform_devices[] __initdata = {
	&hsi2c_gpio_device,
};

static void __init eukrea_cpuimx51sd_init(void)
{
264 265
	imx51_soc_init();

266 267 268
	mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads,
					ARRAY_SIZE(eukrea_cpuimx51sd_pads));

E
Eric Bénard 已提交
269 270 271 272
#if defined(CONFIG_CPU_FREQ_IMX)
	get_cpu_op = mx51_get_cpu_op;
#endif

273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
	imx51_add_imx_uart(0, &uart_pdata);
	imx51_add_mxc_nand(&eukrea_cpuimx51sd_nand_board_info);

	gpio_request(ETH_RST, "eth_rst");
	gpio_set_value(ETH_RST, 1);
	imx51_add_fec(NULL);

	gpio_request(CAN_IRQGPIO, "can_irq");
	gpio_direction_input(CAN_IRQGPIO);
	gpio_free(CAN_IRQGPIO);
	gpio_request(CAN_NCS, "can_ncs");
	gpio_direction_output(CAN_NCS, 1);
	gpio_free(CAN_NCS);
	gpio_request(CAN_RST, "can_rst");
	gpio_direction_output(CAN_RST, 0);
	msleep(20);
	gpio_set_value(CAN_RST, 1);
	imx51_add_ecspi(0, &cpuimx51sd_ecspi1_pdata);
	spi_register_board_info(cpuimx51sd_spi_device,
				ARRAY_SIZE(cpuimx51sd_spi_device));

	gpio_request(TSC2007_IRQGPIO, "tsc2007_irq");
	gpio_direction_input(TSC2007_IRQGPIO);
	gpio_free(TSC2007_IRQGPIO);

	i2c_register_board_info(0, eukrea_cpuimx51sd_i2c_devices,
			ARRAY_SIZE(eukrea_cpuimx51sd_i2c_devices));
	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));

	if (otg_mode_host)
303
		imx51_add_mxc_ehci_otg(&dr_utmi_config);
304 305
	else {
		initialize_otg_port(NULL);
306
		imx51_add_fsl_usb2_udc(&usb_pdata);
307 308 309 310 311 312
	}

	gpio_request(USBH1_RST, "usb_rst");
	gpio_direction_output(USBH1_RST, 0);
	msleep(20);
	gpio_set_value(USBH1_RST, 1);
313
	imx51_add_mxc_ehci_hs(1, &usbh1_config);
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330

#ifdef CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD
	eukrea_mbimxsd51_baseboard_init();
#endif
}

static void __init eukrea_cpuimx51sd_timer_init(void)
{
	mx51_clocks_init(32768, 24000000, 22579200, 0);
}

static struct sys_timer mxc_timer = {
	.init	= eukrea_cpuimx51sd_timer_init,
};

MACHINE_START(EUKREA_CPUIMX51SD, "Eukrea CPUIMX51SD")
	/* Maintainer: Eric Bénard <eric@eukrea.com> */
331
	.atag_offset = 0x100,
332
	.map_io = mx51_map_io,
333
	.init_early = imx51_init_early,
334 335
	.init_irq = mx51_init_irq,
	.timer = &mxc_timer,
336
	.init_machine = eukrea_cpuimx51sd_init,
337
MACHINE_END