atstk1002.c 8.5 KB
Newer Older
H
Haavard Skinnemoen 已提交
1
/*
2
 * ATSTK1002/ATSTK1006 daughterboard-specific init code
H
Haavard Skinnemoen 已提交
3
 *
4
 * Copyright (C) 2005-2007 Atmel Corporation
H
Haavard Skinnemoen 已提交
5 6 7 8 9
 *
 * 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.
 */
10 11
#include <linux/clk.h>
#include <linux/etherdevice.h>
H
Haavard Skinnemoen 已提交
12
#include <linux/init.h>
13
#include <linux/kernel.h>
14
#include <linux/platform_device.h>
15 16
#include <linux/string.h>
#include <linux/types.h>
17
#include <linux/spi/spi.h>
18
#include <linux/spi/at73c213.h>
H
Haavard Skinnemoen 已提交
19

20 21
#include <video/atmel_lcdc.h>

22
#include <asm/io.h>
23
#include <asm/setup.h>
D
David Brownell 已提交
24 25
#include <asm/atmel-mci.h>

26 27 28 29
#include <mach/at32ap700x.h>
#include <mach/board.h>
#include <mach/init.h>
#include <mach/portmux.h>
H
Haavard Skinnemoen 已提交
30

31
#include "atstk1000.h"
32

33 34 35 36 37 38
/* Oscillator frequencies. These are board specific */
unsigned long at32_board_osc_rates[3] = {
	[0] = 32768,	/* 32.768 kHz on RTC osc */
	[1] = 20000000,	/* 20 MHz on osc0 */
	[2] = 12000000,	/* 12 MHz on osc1 */
};
39

40 41 42 43 44 45 46 47 48 49 50 51
/*
 * The ATSTK1006 daughterboard is very similar to the ATSTK1002. Both
 * have the AT32AP7000 chip on board; the difference is that the
 * STK1006 has 128 MB SDRAM (the STK1002 uses the 8 MB SDRAM chip on
 * the STK1000 motherboard) and 256 MB NAND flash (the STK1002 has
 * none.)
 *
 * The RAM difference is handled by the boot loader, so the only
 * difference we end up handling here is the NAND flash.
 */
#ifdef CONFIG_BOARD_ATSTK1006
#include <linux/mtd/partitions.h>
52
#include <mach/smc.h>
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 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

static struct smc_timing nand_timing __initdata = {
	.ncs_read_setup		= 0,
	.nrd_setup		= 10,
	.ncs_write_setup	= 0,
	.nwe_setup		= 10,

	.ncs_read_pulse		= 30,
	.nrd_pulse		= 15,
	.ncs_write_pulse	= 30,
	.nwe_pulse		= 15,

	.read_cycle		= 30,
	.write_cycle		= 30,

	.ncs_read_recover	= 0,
	.nrd_recover		= 15,
	.ncs_write_recover	= 0,
	/* WE# high -> RE# low min 60 ns */
	.nwe_recover		= 50,
};

static struct smc_config nand_config __initdata = {
	.bus_width		= 1,
	.nrd_controlled		= 1,
	.nwe_controlled		= 1,
	.nwait_mode		= 0,
	.byte_write		= 0,
	.tdf_cycles		= 2,
	.tdf_mode		= 0,
};

static struct mtd_partition nand_partitions[] = {
	{
		.name		= "main",
		.offset		= 0x00000000,
		.size		= MTDPART_SIZ_FULL,
	},
};

static struct mtd_partition *nand_part_info(int size, int *num_partitions)
{
	*num_partitions = ARRAY_SIZE(nand_partitions);
	return nand_partitions;
}

99
static struct atmel_nand_data atstk1006_nand_data __initdata = {
100 101 102 103 104 105 106 107
	.cle		= 21,
	.ale		= 22,
	.rdy_pin	= GPIO_PIN_PB(30),
	.enable_pin	= GPIO_PIN_PB(29),
	.partition_info	= nand_part_info,
};
#endif

108 109 110 111 112
struct eth_addr {
	u8 addr[6];
};

static struct eth_addr __initdata hw_addr[2];
113 114 115 116 117 118 119 120 121 122 123 124 125
static struct eth_platform_data __initdata eth_data[2] = {
	{
		/*
		 * The MDIO pullups on STK1000 are a bit too weak for
		 * the autodetection to work properly, so we have to
		 * mask out everything but the correct address.
		 */
		.phy_mask	= ~(1U << 16),
	},
	{
		.phy_mask	= ~(1U << 17),
	},
};
H
Haavard Skinnemoen 已提交
126

127
#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
128 129 130 131 132 133
static struct at73c213_board_info at73c213_data = {
	.ssc_id		= 0,
	.shortname	= "AVR32 STK1000 external DAC",
};
#endif

134
#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM
135
static struct spi_board_info spi0_board_info[] __initdata = {
136
#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
137 138 139 140 141 142 143 144 145
	{
		/* AT73C213 */
		.modalias	= "at73c213",
		.max_speed_hz	= 200000,
		.chip_select	= 0,
		.mode		= SPI_MODE_1,
		.platform_data	= &at73c213_data,
	},
#endif
146
	{
147
		/* QVGA display */
148 149 150
		.modalias	= "ltv350qv",
		.max_speed_hz	= 16000000,
		.chip_select	= 1,
151
		.mode		= SPI_MODE_3,
152 153
	},
};
154 155
#endif

156
#ifdef CONFIG_BOARD_ATSTK100X_SPI1
157 158 159 160
static struct spi_board_info spi1_board_info[] __initdata = { {
	/* patch in custom entries here */
} };
#endif
161

162 163 164 165 166 167 168 169
/*
 * The next two functions should go away as the boot loader is
 * supposed to initialize the macb address registers with a valid
 * ethernet address. But we need to keep it around for a while until
 * we can be reasonably sure the boot loader does this.
 *
 * The phy_id is ignored as the driver will probe for it.
 */
170 171 172 173 174
static int __init parse_tag_ethernet(struct tag *tag)
{
	int i;

	i = tag->u.ethernet.mac_index;
175 176 177 178
	if (i < ARRAY_SIZE(hw_addr))
		memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
		       sizeof(hw_addr[i].addr));

179 180 181 182
	return 0;
}
__tagtable(ATAG_ETHERNET, parse_tag_ethernet);

183 184 185 186 187 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
static void __init set_hw_addr(struct platform_device *pdev)
{
	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	const u8 *addr;
	void __iomem *regs;
	struct clk *pclk;

	if (!res)
		return;
	if (pdev->id >= ARRAY_SIZE(hw_addr))
		return;

	addr = hw_addr[pdev->id].addr;
	if (!is_valid_ether_addr(addr))
		return;

	/*
	 * Since this is board-specific code, we'll cheat and use the
	 * physical address directly as we happen to know that it's
	 * the same as the virtual address.
	 */
	regs = (void __iomem __force *)res->start;
	pclk = clk_get(&pdev->dev, "pclk");
	if (!pclk)
		return;

	clk_enable(pclk);
	__raw_writel((addr[3] << 24) | (addr[2] << 16)
		     | (addr[1] << 8) | addr[0], regs + 0x98);
	__raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
	clk_disable(pclk);
	clk_put(pclk);
}

217 218
#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
static void __init atstk1002_setup_extdac(void)
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
{
	struct clk *gclk;
	struct clk *pll;

	gclk = clk_get(NULL, "gclk0");
	if (IS_ERR(gclk))
		goto err_gclk;
	pll = clk_get(NULL, "pll0");
	if (IS_ERR(pll))
		goto err_pll;

	if (clk_set_parent(gclk, pll)) {
		pr_debug("STK1000: failed to set pll0 as parent for DAC clock\n");
		goto err_set_clk;
	}

	at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
236
	at73c213_data.dac_clk = gclk;
237 238 239 240 241 242 243 244

err_set_clk:
	clk_put(pll);
err_pll:
	clk_put(gclk);
err_gclk:
	return;
}
245 246 247 248 249 250
#else
static void __init atstk1002_setup_extdac(void)
{

}
#endif /* CONFIG_BOARD_ATSTK1000_EXTDAC */
251

252 253
void __init setup_board(void)
{
254
#ifdef	CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
255
	at32_map_usart(0, 1);	/* USART 0/B: /dev/ttyS1, IRDA */
256 257
#else
	at32_map_usart(1, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
258 259 260
#endif
	/* USART 2/unused: expansion connector */
	at32_map_usart(3, 2);	/* USART 3/C: /dev/ttyS2, DB9 */
261 262 263 264

	at32_setup_serial_console(0);
}

D
David Brownell 已提交
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM

/* MMC card detect requires MACB0 *NOT* be used */
#ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM
static struct mci_platform_data __initdata mci0_data = {
	.detect_pin	= GPIO_PIN_PC(14),	/* gpio30/sdcd */
	.wp_pin		= GPIO_PIN_PC(15),	/* gpio31/sdwp */
};
#define MCI_PDATA	&mci0_data
#else
#define MCI_PDATA	NULL
#endif	/* SW6 for sd{cd,wp} routing */

#endif	/* SW2 for MMC signal routing */

H
Haavard Skinnemoen 已提交
280 281
static int __init atstk1002_init(void)
{
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
	/*
	 * ATSTK1000 uses 32-bit SDRAM interface. Reserve the
	 * SDRAM-specific pins so that nobody messes with them.
	 */
	at32_reserve_pin(GPIO_PIN_PE(0));	/* DATA[16]	*/
	at32_reserve_pin(GPIO_PIN_PE(1));	/* DATA[17]	*/
	at32_reserve_pin(GPIO_PIN_PE(2));	/* DATA[18]	*/
	at32_reserve_pin(GPIO_PIN_PE(3));	/* DATA[19]	*/
	at32_reserve_pin(GPIO_PIN_PE(4));	/* DATA[20]	*/
	at32_reserve_pin(GPIO_PIN_PE(5));	/* DATA[21]	*/
	at32_reserve_pin(GPIO_PIN_PE(6));	/* DATA[22]	*/
	at32_reserve_pin(GPIO_PIN_PE(7));	/* DATA[23]	*/
	at32_reserve_pin(GPIO_PIN_PE(8));	/* DATA[24]	*/
	at32_reserve_pin(GPIO_PIN_PE(9));	/* DATA[25]	*/
	at32_reserve_pin(GPIO_PIN_PE(10));	/* DATA[26]	*/
	at32_reserve_pin(GPIO_PIN_PE(11));	/* DATA[27]	*/
	at32_reserve_pin(GPIO_PIN_PE(12));	/* DATA[28]	*/
	at32_reserve_pin(GPIO_PIN_PE(13));	/* DATA[29]	*/
	at32_reserve_pin(GPIO_PIN_PE(14));	/* DATA[30]	*/
	at32_reserve_pin(GPIO_PIN_PE(15));	/* DATA[31]	*/
	at32_reserve_pin(GPIO_PIN_PE(26));	/* SDCS		*/

H
Haavard Skinnemoen 已提交
304 305
	at32_add_system_devices();

306 307 308 309 310 311
#ifdef CONFIG_BOARD_ATSTK1006
	smc_set_timing(&nand_config, &nand_timing);
	smc_set_configuration(3, &nand_config);
	at32_add_device_nand(0, &atstk1006_nand_data);
#endif

312
#ifdef	CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
313
	at32_add_device_usart(1);
314 315
#else
	at32_add_device_usart(0);
316
#endif
317
	at32_add_device_usart(2);
H
Haavard Skinnemoen 已提交
318

319
#ifndef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM
320
	set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
321
#endif
322
#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM
323
	at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
324
#endif
325
#ifdef CONFIG_BOARD_ATSTK100X_SPI1
326 327
	at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
#endif
328
#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
D
David Brownell 已提交
329
	at32_add_device_mci(0, MCI_PDATA);
330
#endif
331 332 333
#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM
	set_hw_addr(at32_add_device_eth(1, &eth_data[1]));
#else
334
	at32_add_device_lcdc(0, &atstk1000_lcdc_data,
335
			     fbmem_start, fbmem_size, 0);
336
#endif
H
Haavard Skinnemoen 已提交
337
	at32_add_device_usba(0, NULL);
338
#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM
339 340
	at32_add_device_ssc(0, ATMEL_SSC_TX);
#endif
H
Haavard Skinnemoen 已提交
341

342
	atstk1000_setup_j2_leds();
343
	atstk1002_setup_extdac();
344

H
Haavard Skinnemoen 已提交
345 346 347
	return 0;
}
postcore_initcall(atstk1002_init);