Path: blob/master/arch/avr32/boards/atstk1000/atstk1002.c
10819 views
/*1* ATSTK1002/ATSTK1006 daughterboard-specific init code2*3* Copyright (C) 2005-2007 Atmel Corporation4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License version 2 as7* published by the Free Software Foundation.8*/9#include <linux/clk.h>10#include <linux/etherdevice.h>11#include <linux/init.h>12#include <linux/kernel.h>13#include <linux/platform_device.h>14#include <linux/string.h>15#include <linux/types.h>16#include <linux/spi/spi.h>17#include <linux/spi/at73c213.h>18#include <linux/atmel-mci.h>1920#include <video/atmel_lcdc.h>2122#include <asm/io.h>23#include <asm/setup.h>2425#include <mach/at32ap700x.h>26#include <mach/board.h>27#include <mach/init.h>28#include <mach/portmux.h>2930#include "atstk1000.h"3132/* Oscillator frequencies. These are board specific */33unsigned long at32_board_osc_rates[3] = {34[0] = 32768, /* 32.768 kHz on RTC osc */35[1] = 20000000, /* 20 MHz on osc0 */36[2] = 12000000, /* 12 MHz on osc1 */37};3839/*40* The ATSTK1006 daughterboard is very similar to the ATSTK1002. Both41* have the AT32AP7000 chip on board; the difference is that the42* STK1006 has 128 MB SDRAM (the STK1002 uses the 8 MB SDRAM chip on43* the STK1000 motherboard) and 256 MB NAND flash (the STK1002 has44* none.)45*46* The RAM difference is handled by the boot loader, so the only47* difference we end up handling here is the NAND flash.48*/49#ifdef CONFIG_BOARD_ATSTK100650#include <linux/mtd/partitions.h>51#include <mach/smc.h>5253static struct smc_timing nand_timing __initdata = {54.ncs_read_setup = 0,55.nrd_setup = 10,56.ncs_write_setup = 0,57.nwe_setup = 10,5859.ncs_read_pulse = 30,60.nrd_pulse = 15,61.ncs_write_pulse = 30,62.nwe_pulse = 15,6364.read_cycle = 30,65.write_cycle = 30,6667.ncs_read_recover = 0,68.nrd_recover = 15,69.ncs_write_recover = 0,70/* WE# high -> RE# low min 60 ns */71.nwe_recover = 50,72};7374static struct smc_config nand_config __initdata = {75.bus_width = 1,76.nrd_controlled = 1,77.nwe_controlled = 1,78.nwait_mode = 0,79.byte_write = 0,80.tdf_cycles = 2,81.tdf_mode = 0,82};8384static struct mtd_partition nand_partitions[] = {85{86.name = "main",87.offset = 0x00000000,88.size = MTDPART_SIZ_FULL,89},90};9192static struct mtd_partition *nand_part_info(int size, int *num_partitions)93{94*num_partitions = ARRAY_SIZE(nand_partitions);95return nand_partitions;96}9798static struct atmel_nand_data atstk1006_nand_data __initdata = {99.cle = 21,100.ale = 22,101.rdy_pin = GPIO_PIN_PB(30),102.enable_pin = GPIO_PIN_PB(29),103.partition_info = nand_part_info,104};105#endif106107struct eth_addr {108u8 addr[6];109};110111static struct eth_addr __initdata hw_addr[2];112static struct eth_platform_data __initdata eth_data[2] = {113{114/*115* The MDIO pullups on STK1000 are a bit too weak for116* the autodetection to work properly, so we have to117* mask out everything but the correct address.118*/119.phy_mask = ~(1U << 16),120},121{122.phy_mask = ~(1U << 17),123},124};125126#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC127static struct at73c213_board_info at73c213_data = {128.ssc_id = 0,129.shortname = "AVR32 STK1000 external DAC",130};131#endif132133#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM134static struct spi_board_info spi0_board_info[] __initdata = {135#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC136{137/* AT73C213 */138.modalias = "at73c213",139.max_speed_hz = 200000,140.chip_select = 0,141.mode = SPI_MODE_1,142.platform_data = &at73c213_data,143},144#endif145{146/* QVGA display */147.modalias = "ltv350qv",148.max_speed_hz = 16000000,149.chip_select = 1,150.mode = SPI_MODE_3,151},152};153#endif154155#ifdef CONFIG_BOARD_ATSTK100X_SPI1156static struct spi_board_info spi1_board_info[] __initdata = { {157/* patch in custom entries here */158} };159#endif160161/*162* The next two functions should go away as the boot loader is163* supposed to initialize the macb address registers with a valid164* ethernet address. But we need to keep it around for a while until165* we can be reasonably sure the boot loader does this.166*167* The phy_id is ignored as the driver will probe for it.168*/169static int __init parse_tag_ethernet(struct tag *tag)170{171int i;172173i = tag->u.ethernet.mac_index;174if (i < ARRAY_SIZE(hw_addr))175memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,176sizeof(hw_addr[i].addr));177178return 0;179}180__tagtable(ATAG_ETHERNET, parse_tag_ethernet);181182static void __init set_hw_addr(struct platform_device *pdev)183{184struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);185const u8 *addr;186void __iomem *regs;187struct clk *pclk;188189if (!res)190return;191if (pdev->id >= ARRAY_SIZE(hw_addr))192return;193194addr = hw_addr[pdev->id].addr;195if (!is_valid_ether_addr(addr))196return;197198/*199* Since this is board-specific code, we'll cheat and use the200* physical address directly as we happen to know that it's201* the same as the virtual address.202*/203regs = (void __iomem __force *)res->start;204pclk = clk_get(&pdev->dev, "pclk");205if (IS_ERR(pclk))206return;207208clk_enable(pclk);209__raw_writel((addr[3] << 24) | (addr[2] << 16)210| (addr[1] << 8) | addr[0], regs + 0x98);211__raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);212clk_disable(pclk);213clk_put(pclk);214}215216#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC217static void __init atstk1002_setup_extdac(void)218{219struct clk *gclk;220struct clk *pll;221222gclk = clk_get(NULL, "gclk0");223if (IS_ERR(gclk))224goto err_gclk;225pll = clk_get(NULL, "pll0");226if (IS_ERR(pll))227goto err_pll;228229if (clk_set_parent(gclk, pll)) {230pr_debug("STK1000: failed to set pll0 as parent for DAC clock\n");231goto err_set_clk;232}233234at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0);235at73c213_data.dac_clk = gclk;236237err_set_clk:238clk_put(pll);239err_pll:240clk_put(gclk);241err_gclk:242return;243}244#else245static void __init atstk1002_setup_extdac(void)246{247248}249#endif /* CONFIG_BOARD_ATSTK1000_EXTDAC */250251void __init setup_board(void)252{253#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM254at32_map_usart(0, 1, 0); /* USART 0/B: /dev/ttyS1, IRDA */255#else256at32_map_usart(1, 0, 0); /* USART 1/A: /dev/ttyS0, DB9 */257#endif258/* USART 2/unused: expansion connector */259at32_map_usart(3, 2, 0); /* USART 3/C: /dev/ttyS2, DB9 */260261at32_setup_serial_console(0);262}263264#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM265266static struct mci_platform_data __initdata mci0_data = {267.slot[0] = {268.bus_width = 4,269270/* MMC card detect requires MACB0 *NOT* be used */271#ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM272.detect_pin = GPIO_PIN_PC(14), /* gpio30/sdcd */273.wp_pin = GPIO_PIN_PC(15), /* gpio31/sdwp */274#else275.detect_pin = -ENODEV,276.wp_pin = -ENODEV,277#endif /* SW6 for sd{cd,wp} routing */278},279};280281#endif /* SW2 for MMC signal routing */282283static int __init atstk1002_init(void)284{285/*286* ATSTK1000 uses 32-bit SDRAM interface. Reserve the287* SDRAM-specific pins so that nobody messes with them.288*/289at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL);290291#ifdef CONFIG_BOARD_ATSTK1006292smc_set_timing(&nand_config, &nand_timing);293smc_set_configuration(3, &nand_config);294at32_add_device_nand(0, &atstk1006_nand_data);295#endif296297#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM298at32_add_device_usart(1);299#else300at32_add_device_usart(0);301#endif302at32_add_device_usart(2);303304#ifndef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM305set_hw_addr(at32_add_device_eth(0, ð_data[0]));306#endif307#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM308at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));309#endif310#ifdef CONFIG_BOARD_ATSTK100X_SPI1311at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));312#endif313#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM314at32_add_device_mci(0, &mci0_data);315#endif316#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM317set_hw_addr(at32_add_device_eth(1, ð_data[1]));318#else319at32_add_device_lcdc(0, &atstk1000_lcdc_data,320fbmem_start, fbmem_size,321ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL);322#endif323at32_add_device_usba(0, NULL);324#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM325at32_add_device_ssc(0, ATMEL_SSC_TX);326#endif327328atstk1000_setup_j2_leds();329atstk1002_setup_extdac();330331return 0;332}333postcore_initcall(atstk1002_init);334335336