board-cpuimx51sd.c 8.9 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 40
/*
 *
 * 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"
#include "devices.h"
E
Eric Bénard 已提交
41
#include "cpu_op-mx51.h"
42

A
Arnaud Patard (Rtp) 已提交
43 44 45 46 47 48 49 50 51 52 53 54 55
#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)
56 57 58 59 60 61 62 63 64

/* 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

65
static iomux_v3_cfg_t eukrea_cpuimx51sd_pads[] = {
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
	/* 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 已提交
85
	MX51_PAD_EIM_CS3__GPIO2_28,		/* PHY nRESET */
86 87

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

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

	/* CAN */
	MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI,
	MX51_PAD_CSPI1_MISO__ECSPI1_MISO,
	MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
S
Sascha Hauer 已提交
98 99 100 101 102 103 104 105
	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,
106 107

	/* Touchscreen */
S
Sascha Hauer 已提交
108
	/* IRQ */
E
Eric Bénard 已提交
109
	_MX51_PAD_GPIO_NAND__GPIO_NAND | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
S
Sascha Hauer 已提交
110 111
			PAD_CTL_PKE | PAD_CTL_SRE_FAST |
			PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
};

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,
		.irq		= gpio_to_irq(TSC2007_IRQGPIO),
	},
};

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;

	usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
151 152
	if (!usb_base)
		return -ENOMEM;
153 154 155 156 157 158 159 160
	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);
161 162 163 164

	mdelay(10);

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

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

	usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
174 175
	if (!usb_base)
		return -ENOMEM;
176 177 178 179 180 181 182
	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);
183 184 185 186 187

	mdelay(10);

	return mx51_initialize_usb_hw(1, MXC_EHCI_POWER_PINS_ENABLED |
			MXC_EHCI_ITC_NO_THRESHOLD);
188 189 190 191 192 193 194 195 196 197 198 199 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 240
}

static struct mxc_usbh_platform_data dr_utmi_config = {
	.init		= initialize_otg_port,
	.portsc	= MXC_EHCI_UTMI_16BIT,
};

static struct fsl_usb2_platform_data usb_pdata = {
	.operating_mode	= FSL_USB2_DR_DEVICE,
	.phy_mode	= FSL_USB2_PHY_UTMI_WIDE,
};

static struct mxc_usbh_platform_data usbh1_config = {
	.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",
241
		.max_speed_hz    = 10000000,
242 243 244 245
		.bus_num         = 0,
		.mode		= SPI_MODE_0,
		.chip_select     = 0,
		.platform_data   = &mcp251x_info,
A
Arnaud Patard (Rtp) 已提交
246
		.irq             = gpio_to_irq(CAN_IRQGPIO)
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
	},
};

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)
{
265 266
	imx51_soc_init();

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

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

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 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
	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)
		mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
	else {
		initialize_otg_port(NULL);
		mxc_register_device(&mxc_usbdr_udc_device, &usb_pdata);
	}

	gpio_request(USBH1_RST, "usb_rst");
	gpio_direction_output(USBH1_RST, 0);
	msleep(20);
	gpio_set_value(USBH1_RST, 1);
	mxc_register_device(&mxc_usbh1_device, &usbh1_config);

#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> */
332
	.boot_params = MX51_PHYS_OFFSET + 0x100,
333
	.map_io = mx51_map_io,
334
	.init_early = imx51_init_early,
335 336
	.init_irq = mx51_init_irq,
	.timer = &mxc_timer,
337
	.init_machine = eukrea_cpuimx51sd_init,
338
MACHINE_END