board-nhk8815.c 9.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 *  linux/arch/arm/mach-nomadik/board-8815nhk.c
 *
 *  Copyright (C) STMicroelectronics
 *
 * 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.
 *
 *  NHK15 board specifc driver definition
 */
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/amba/bus.h>
17
#include <linux/amba/mmci.h>
18 19
#include <linux/interrupt.h>
#include <linux/gpio.h>
20 21
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
22
#include <linux/mtd/fsmc.h>
23
#include <linux/mtd/onenand.h>
24
#include <linux/mtd/partitions.h>
25
#include <linux/i2c.h>
26
#include <linux/io.h>
27
#include <linux/pinctrl/machine.h>
28
#include <linux/platform_data/pinctrl-nomadik.h>
29
#include <linux/platform_data/clocksource-nomadik-mtu.h>
30
#include <asm/hardware/vic.h>
31
#include <asm/sizes.h>
32 33
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
34
#include <asm/mach/flash.h>
35
#include <asm/mach/time.h>
36
#include <mach/irqs.h>
37

38 39
#include "cpu-8815.h"

40 41 42 43
/* Initial value for SRC control register: all timers use MXTAL/8 source */
#define SRC_CR_INIT_MASK	0x00007fff
#define SRC_CR_INIT_VAL		0x2aaa8000

44 45 46
#define ALE_OFF 0x1000000
#define CLE_OFF 0x800000

D
Daniel Mack 已提交
47
/* These addresses span 16MB, so use three individual pages */
48 49
static struct resource nhk8815_nand_resources[] = {
	{
50 51 52
		.name = "nand_data",
		.start = 0x40000000,
		.end = 0x40000000 + SZ_16K - 1,
53
		.flags = IORESOURCE_MEM,
54
	}, {
55
		.name = "nand_addr",
56 57
		.start = 0x40000000 + ALE_OFF,
		.end = 0x40000000 +ALE_OFF + SZ_16K - 1,
58 59 60
		.flags = IORESOURCE_MEM,
	}, {
		.name = "nand_cmd",
61 62
		.start = 0x40000000 + CLE_OFF,
		.end = 0x40000000 + CLE_OFF + SZ_16K - 1,
63 64
		.flags = IORESOURCE_MEM,
	}, {
65 66 67
		.name  = "fsmc_regs",
		.start = NOMADIK_FSMC_BASE,
		.end   = NOMADIK_FSMC_BASE + SZ_4K - 1,
68
		.flags = IORESOURCE_MEM,
69
	},
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
};

/*
 * These partitions are the same as those used in the 2.6.20 release
 * shipped by the vendor; the first two partitions are mandated
 * by the boot ROM, and the bootloader area is somehow oversized...
 */
static struct mtd_partition nhk8815_partitions[] = {
	{
		.name	= "X-Loader(NAND)",
		.offset = 0,
		.size	= SZ_256K,
	}, {
		.name	= "MemInit(NAND)",
		.offset	= MTDPART_OFS_APPEND,
		.size	= SZ_256K,
	}, {
		.name	= "BootLoader(NAND)",
		.offset	= MTDPART_OFS_APPEND,
		.size	= SZ_2M,
	}, {
		.name	= "Kernel zImage(NAND)",
		.offset	= MTDPART_OFS_APPEND,
		.size	= 3 * SZ_1M,
	}, {
		.name	= "Root Filesystem(NAND)",
		.offset	= MTDPART_OFS_APPEND,
		.size	= 22 * SZ_1M,
	}, {
		.name	= "User Filesystem(NAND)",
		.offset	= MTDPART_OFS_APPEND,
		.size	= MTDPART_SIZ_FULL,
	}
};

105 106 107 108 109 110 111 112 113 114 115 116
static struct fsmc_nand_timings nhk8815_nand_timings = {
	.thiz	= 0,
	.thold	= 0x10,
	.twait	= 0x0A,
	.tset	= 0,
};

static struct fsmc_nand_platform_data nhk8815_nand_platform_data = {
	.nand_timings = &nhk8815_nand_timings,
	.partitions = nhk8815_partitions,
	.nr_partitions = ARRAY_SIZE(nhk8815_partitions),
	.width = FSMC_NAND_BW8,
117 118 119
};

static struct platform_device nhk8815_nand_device = {
120 121 122 123 124 125
	.name = "fsmc-nand",
	.id = -1,
	.resource = nhk8815_nand_resources,
	.num_resources = ARRAY_SIZE(nhk8815_nand_resources),
	.dev = {
		.platform_data = &nhk8815_nand_platform_data,
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 151 152 153 154 155 156 157
/* These are the partitions for the OneNand device, different from above */
static struct mtd_partition nhk8815_onenand_partitions[] = {
	{
		.name	= "X-Loader(OneNAND)",
		.offset = 0,
		.size	= SZ_256K,
	}, {
		.name	= "MemInit(OneNAND)",
		.offset	= MTDPART_OFS_APPEND,
		.size	= SZ_256K,
	}, {
		.name	= "BootLoader(OneNAND)",
		.offset	= MTDPART_OFS_APPEND,
		.size	= SZ_2M-SZ_256K,
	}, {
		.name	= "SysImage(OneNAND)",
		.offset	= MTDPART_OFS_APPEND,
		.size	= 4 * SZ_1M,
	}, {
		.name	= "Root Filesystem(OneNAND)",
		.offset	= MTDPART_OFS_APPEND,
		.size	= 22 * SZ_1M,
	}, {
		.name	= "User Filesystem(OneNAND)",
		.offset	= MTDPART_OFS_APPEND,
		.size	= MTDPART_SIZ_FULL,
	}
};

158
static struct onenand_platform_data nhk8815_onenand_data = {
159 160 161 162 163 164 165 166 167 168 169 170 171
	.parts		= nhk8815_onenand_partitions,
	.nr_parts	= ARRAY_SIZE(nhk8815_onenand_partitions),
};

static struct resource nhk8815_onenand_resource[] = {
	{
		.start		= 0x30000000,
		.end		= 0x30000000 + SZ_128K - 1,
		.flags		= IORESOURCE_MEM,
	},
};

static struct platform_device nhk8815_onenand_device = {
172
	.name		= "onenand-flash",
173 174 175 176 177 178 179 180
	.id		= -1,
	.dev		= {
		.platform_data	= &nhk8815_onenand_data,
	},
	.resource	= nhk8815_onenand_resource,
	.num_resources	= ARRAY_SIZE(nhk8815_onenand_resource),
};

181 182 183 184
/* bus control reg. and bus timing reg. for CS0..CS3 */
#define FSMC_BCR(x)	(NOMADIK_FSMC_VA + (x << 3))
#define FSMC_BTR(x)	(NOMADIK_FSMC_VA + (x << 3) + 0x04)

185 186
static void __init nhk8815_onenand_init(void)
{
187
#ifdef CONFIG_MTD_ONENAND
188
       /* Set up SMCS0 for OneNand */
189 190
	writel(0x000030db, FSMC_BCR(0));
	writel(0x02100551, FSMC_BTR(0));
191 192
#endif
}
193

194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
static struct mmci_platform_data mmcsd_plat_data = {
	.ocr_mask = MMC_VDD_29_30,
	.f_max = 48000000,
	.gpio_wp = -1,
	.gpio_cd = 111,
	.cd_invert = true,
	.capabilities = MMC_CAP_MMC_HIGHSPEED |
	MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA,
};

static int __init nhk8815_mmcsd_init(void)
{
	int ret;

	ret = gpio_request(112, "card detect bias");
	if (ret)
		return ret;
	gpio_direction_output(112, 0);
	amba_apb_device_add(NULL, "mmci", NOMADIK_SDI_BASE, SZ_4K, IRQ_SDMMC, 0, &mmcsd_plat_data, 0x10180180);
	return 0;
}
module_init(nhk8815_mmcsd_init);

217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
static struct resource nhk8815_eth_resources[] = {
	{
		.name = "smc91x-regs",
		.start = 0x34000000 + 0x300,
		.end = 0x34000000 + SZ_64K - 1,
		.flags = IORESOURCE_MEM,
	}, {
		.start = NOMADIK_GPIO_TO_IRQ(115),
		.end = NOMADIK_GPIO_TO_IRQ(115),
		.flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
	}
};

static struct platform_device nhk8815_eth_device = {
	.name = "smc91x",
	.resource = nhk8815_eth_resources,
	.num_resources = ARRAY_SIZE(nhk8815_eth_resources),
};

static int __init nhk8815_eth_init(void)
{
	int gpio_nr = 115; /* hardwired in the board */
	int err;

	err = gpio_request(gpio_nr, "eth_irq");
	if (!err) err = nmk_gpio_set_mode(gpio_nr, NMK_GPIO_ALT_GPIO);
	if (!err) err = gpio_direction_input(gpio_nr);
	if (err)
		pr_err("Error %i in %s\n", err, __func__);
	return err;
}
device_initcall(nhk8815_eth_init);

250
static struct platform_device *nhk8815_platform_devices[] __initdata = {
251
	&nhk8815_nand_device,
252
	&nhk8815_onenand_device,
253 254
	&nhk8815_eth_device,
	/* will add more devices */
255 256
};

257 258 259 260 261 262 263 264 265 266
static void __init nomadik_timer_init(void)
{
	u32 src_cr;

	/* Configure timer sources in "system reset controller" ctrl reg */
	src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
	src_cr &= SRC_CR_INIT_MASK;
	src_cr |= SRC_CR_INIT_VAL;
	writel(src_cr, io_p2v(NOMADIK_SRC_BASE));

267
	nmdk_timer_init(io_p2v(NOMADIK_MTU0_BASE), IRQ_MTU0);
268 269
}

270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
static struct i2c_board_info __initdata nhk8815_i2c0_devices[] = {
	{
		I2C_BOARD_INFO("stw4811", 0x2d),
	},
};

static struct i2c_board_info __initdata nhk8815_i2c1_devices[] = {
	{
		I2C_BOARD_INFO("camera", 0x10),
	},
	{
		I2C_BOARD_INFO("stw5095", 0x1a),
	},
	{
		I2C_BOARD_INFO("lis3lv02dl", 0x1d),
	},
};

static struct i2c_board_info __initdata nhk8815_i2c2_devices[] = {
	{
		I2C_BOARD_INFO("stw4811-usb", 0x2d),
	},
};

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
static unsigned long out_low[] = { PIN_OUTPUT_LOW };
static unsigned long out_high[] = { PIN_OUTPUT_HIGH };
static unsigned long in_nopull[] = { PIN_INPUT_NOPULL };
static unsigned long in_pullup[] = { PIN_INPUT_PULLUP };

static struct pinctrl_map __initdata nhk8815_pinmap[] = {
	PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-stn8815", "u0_a_1", "u0"),
	PIN_MAP_MUX_GROUP_DEFAULT("uart1", "pinctrl-stn8815", "u1_a_1", "u1"),
	/* Hog in MMC/SD card mux */
	PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-stn8815", "mmcsd_a_1", "mmcsd"),
	/* MCCLK */
	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO8_B10", out_low),
	/* MCCMD */
	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO9_A10", in_pullup),
	/* MCCMDDIR */
	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO10_C11", out_high),
	/* MCDAT3-0 */
	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO11_B11", in_pullup),
	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO12_A11", in_pullup),
	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO13_C12", in_pullup),
	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO14_B12", in_pullup),
	/* MCDAT0DIR */
	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO15_A12", out_high),
	/* MCDAT31DIR */
	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO16_C13", out_high),
	/* MCMSFBCLK */
	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO24_C15", in_pullup),
	/* CD input GPIO */
	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO111_H21", in_nopull),
	/* CD bias drive */
	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO112_J21", out_low),
};

327 328
static void __init nhk8815_platform_init(void)
{
329
	pinctrl_register_mappings(nhk8815_pinmap, ARRAY_SIZE(nhk8815_pinmap));
330
	cpu8815_platform_init();
331
	nhk8815_onenand_init();
332 333 334
	platform_add_devices(nhk8815_platform_devices,
			     ARRAY_SIZE(nhk8815_platform_devices));

335 336
	amba_apb_device_add(NULL, "uart0", NOMADIK_UART0_BASE, SZ_4K, IRQ_UART0, 0, NULL, 0);
	amba_apb_device_add(NULL, "uart1", NOMADIK_UART1_BASE, SZ_4K, IRQ_UART1, 0, NULL, 0);
337 338 339 340 341 342 343

	i2c_register_board_info(0, nhk8815_i2c0_devices,
				ARRAY_SIZE(nhk8815_i2c0_devices));
	i2c_register_board_info(1, nhk8815_i2c1_devices,
				ARRAY_SIZE(nhk8815_i2c1_devices));
	i2c_register_board_info(2, nhk8815_i2c2_devices,
				ARRAY_SIZE(nhk8815_i2c2_devices));
344 345 346 347
}

MACHINE_START(NOMADIK, "NHK8815")
	/* Maintainer: ST MicroElectronics */
348
	.atag_offset	= 0x100,
349 350
	.map_io		= cpu8815_map_io,
	.init_irq	= cpu8815_init_irq,
351
	.handle_irq	= vic_handle_irq,
S
Stephen Warren 已提交
352
	.init_time	= nomadik_timer_init,
353
	.init_machine	= nhk8815_platform_init,
354
	.restart	= cpu8815_restart,
355
MACHINE_END