atstk1002.c 8.1 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>
24
#include <asm/arch/at32ap700x.h>
H
Haavard Skinnemoen 已提交
25
#include <asm/arch/board.h>
26
#include <asm/arch/init.h>
27
#include <asm/arch/portmux.h>
H
Haavard Skinnemoen 已提交
28

29
#include "atstk1000.h"
30

31 32 33 34 35 36
/* 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 */
};
37

38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 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 99 100 101 102 103 104 105
/*
 * 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>
#include <asm/arch/smc.h>

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;
}

struct atmel_nand_data atstk1006_nand_data __initdata = {
	.cle		= 21,
	.ale		= 22,
	.rdy_pin	= GPIO_PIN_PB(30),
	.enable_pin	= GPIO_PIN_PB(29),
	.partition_info	= nand_part_info,
};
#endif

106 107 108 109 110
struct eth_addr {
	u8 addr[6];
};

static struct eth_addr __initdata hw_addr[2];
111 112 113 114 115 116 117 118 119 120 121 122 123
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 已提交
124

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

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

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

160 161 162 163 164 165 166 167
/*
 * 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.
 */
168 169 170 171 172
static int __init parse_tag_ethernet(struct tag *tag)
{
	int i;

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

177 178 179 180
	return 0;
}
__tagtable(ATAG_ETHERNET, parse_tag_ethernet);

181 182 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
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);
}

215 216
#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
static void __init atstk1002_setup_extdac(void)
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
{
	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);
234
	at73c213_data.dac_clk = gclk;
235 236 237 238 239 240 241 242

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

}
#endif /* CONFIG_BOARD_ATSTK1000_EXTDAC */
249

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

	at32_setup_serial_console(0);
}

H
Haavard Skinnemoen 已提交
263 264
static int __init atstk1002_init(void)
{
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
	/*
	 * 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 已提交
287 288
	at32_add_system_devices();

289 290 291 292 293 294
#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

295
#ifdef	CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
296
	at32_add_device_usart(1);
297 298
#else
	at32_add_device_usart(0);
299
#endif
300
	at32_add_device_usart(2);
H
Haavard Skinnemoen 已提交
301

302
#ifndef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM
303
	set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
304
#endif
305
#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM
306
	at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
307
#endif
308
#ifdef CONFIG_BOARD_ATSTK100X_SPI1
309 310
	at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
#endif
311 312 313
#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
	at32_add_device_mci(0, NULL);
#endif
314 315 316
#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM
	set_hw_addr(at32_add_device_eth(1, &eth_data[1]));
#else
317
	at32_add_device_lcdc(0, &atstk1000_lcdc_data,
318
			     fbmem_start, fbmem_size, 0);
319
#endif
H
Haavard Skinnemoen 已提交
320
	at32_add_device_usba(0, NULL);
321
#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM
322 323
	at32_add_device_ssc(0, ATMEL_SSC_TX);
#endif
H
Haavard Skinnemoen 已提交
324

325
	atstk1000_setup_j2_leds();
326
	atstk1002_setup_extdac();
327

H
Haavard Skinnemoen 已提交
328 329 330
	return 0;
}
postcore_initcall(atstk1002_init);