Path: blob/master/arch/m68k/platform/528x/config.c
10819 views
/***************************************************************************/12/*3* linux/arch/m68knommu/platform/528x/config.c4*5* Sub-architcture dependent initialization code for the Freescale6* 5280, 5281 and 5282 CPUs.7*8* Copyright (C) 1999-2003, Greg Ungerer ([email protected])9* Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)10*/1112/***************************************************************************/1314#include <linux/kernel.h>15#include <linux/param.h>16#include <linux/init.h>17#include <linux/platform_device.h>18#include <linux/io.h>19#include <linux/spi/spi.h>20#include <linux/gpio.h>21#include <asm/machdep.h>22#include <asm/coldfire.h>23#include <asm/mcfsim.h>24#include <asm/mcfuart.h>25#include <asm/mcfqspi.h>2627/***************************************************************************/2829static struct mcf_platform_uart m528x_uart_platform[] = {30{31.mapbase = MCFUART_BASE1,32.irq = MCFINT_VECBASE + MCFINT_UART0,33},34{35.mapbase = MCFUART_BASE2,36.irq = MCFINT_VECBASE + MCFINT_UART0 + 1,37},38{39.mapbase = MCFUART_BASE3,40.irq = MCFINT_VECBASE + MCFINT_UART0 + 2,41},42{ },43};4445static struct platform_device m528x_uart = {46.name = "mcfuart",47.id = 0,48.dev.platform_data = m528x_uart_platform,49};5051static struct resource m528x_fec_resources[] = {52{53.start = MCFFEC_BASE,54.end = MCFFEC_BASE + MCFFEC_SIZE - 1,55.flags = IORESOURCE_MEM,56},57{58.start = 64 + 23,59.end = 64 + 23,60.flags = IORESOURCE_IRQ,61},62{63.start = 64 + 27,64.end = 64 + 27,65.flags = IORESOURCE_IRQ,66},67{68.start = 64 + 29,69.end = 64 + 29,70.flags = IORESOURCE_IRQ,71},72};7374static struct platform_device m528x_fec = {75.name = "fec",76.id = 0,77.num_resources = ARRAY_SIZE(m528x_fec_resources),78.resource = m528x_fec_resources,79};8081#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)82static struct resource m528x_qspi_resources[] = {83{84.start = MCFQSPI_IOBASE,85.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,86.flags = IORESOURCE_MEM,87},88{89.start = MCFINT_VECBASE + MCFINT_QSPI,90.end = MCFINT_VECBASE + MCFINT_QSPI,91.flags = IORESOURCE_IRQ,92},93};9495#define MCFQSPI_CS0 14796#define MCFQSPI_CS1 14897#define MCFQSPI_CS2 14998#define MCFQSPI_CS3 15099100static int m528x_cs_setup(struct mcfqspi_cs_control *cs_control)101{102int status;103104status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");105if (status) {106pr_debug("gpio_request for MCFQSPI_CS0 failed\n");107goto fail0;108}109status = gpio_direction_output(MCFQSPI_CS0, 1);110if (status) {111pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");112goto fail1;113}114115status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");116if (status) {117pr_debug("gpio_request for MCFQSPI_CS1 failed\n");118goto fail1;119}120status = gpio_direction_output(MCFQSPI_CS1, 1);121if (status) {122pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");123goto fail2;124}125126status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");127if (status) {128pr_debug("gpio_request for MCFQSPI_CS2 failed\n");129goto fail2;130}131status = gpio_direction_output(MCFQSPI_CS2, 1);132if (status) {133pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");134goto fail3;135}136137status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");138if (status) {139pr_debug("gpio_request for MCFQSPI_CS3 failed\n");140goto fail3;141}142status = gpio_direction_output(MCFQSPI_CS3, 1);143if (status) {144pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");145goto fail4;146}147148return 0;149150fail4:151gpio_free(MCFQSPI_CS3);152fail3:153gpio_free(MCFQSPI_CS2);154fail2:155gpio_free(MCFQSPI_CS1);156fail1:157gpio_free(MCFQSPI_CS0);158fail0:159return status;160}161162static void m528x_cs_teardown(struct mcfqspi_cs_control *cs_control)163{164gpio_free(MCFQSPI_CS3);165gpio_free(MCFQSPI_CS2);166gpio_free(MCFQSPI_CS1);167gpio_free(MCFQSPI_CS0);168}169170static void m528x_cs_select(struct mcfqspi_cs_control *cs_control,171u8 chip_select, bool cs_high)172{173gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);174}175176static void m528x_cs_deselect(struct mcfqspi_cs_control *cs_control,177u8 chip_select, bool cs_high)178{179gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);180}181182static struct mcfqspi_cs_control m528x_cs_control = {183.setup = m528x_cs_setup,184.teardown = m528x_cs_teardown,185.select = m528x_cs_select,186.deselect = m528x_cs_deselect,187};188189static struct mcfqspi_platform_data m528x_qspi_data = {190.bus_num = 0,191.num_chipselect = 4,192.cs_control = &m528x_cs_control,193};194195static struct platform_device m528x_qspi = {196.name = "mcfqspi",197.id = 0,198.num_resources = ARRAY_SIZE(m528x_qspi_resources),199.resource = m528x_qspi_resources,200.dev.platform_data = &m528x_qspi_data,201};202203static void __init m528x_qspi_init(void)204{205/* setup Port QS for QSPI with gpio CS control */206__raw_writeb(0x07, MCFGPIO_PQSPAR);207}208#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */209210static struct platform_device *m528x_devices[] __initdata = {211&m528x_uart,212&m528x_fec,213#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)214&m528x_qspi,215#endif216};217218/***************************************************************************/219220static void __init m528x_uart_init_line(int line, int irq)221{222u8 port;223224if ((line < 0) || (line > 2))225return;226227/* make sure PUAPAR is set for UART0 and UART1 */228if (line < 2) {229port = readb(MCF5282_GPIO_PUAPAR);230port |= (0x03 << (line * 2));231writeb(port, MCF5282_GPIO_PUAPAR);232}233}234235static void __init m528x_uarts_init(void)236{237const int nrlines = ARRAY_SIZE(m528x_uart_platform);238int line;239240for (line = 0; (line < nrlines); line++)241m528x_uart_init_line(line, m528x_uart_platform[line].irq);242}243244/***************************************************************************/245246static void __init m528x_fec_init(void)247{248u16 v16;249250/* Set multi-function pins to ethernet mode for fec0 */251v16 = readw(MCF_IPSBAR + 0x100056);252writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);253writeb(0xc0, MCF_IPSBAR + 0x100058);254}255256/***************************************************************************/257258static void m528x_cpu_reset(void)259{260local_irq_disable();261__raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);262}263264/***************************************************************************/265266#ifdef CONFIG_WILDFIRE267void wildfire_halt(void)268{269writeb(0, 0x30000007);270writeb(0x2, 0x30000007);271}272#endif273274#ifdef CONFIG_WILDFIREMOD275void wildfiremod_halt(void)276{277printk(KERN_INFO "WildFireMod hibernating...\n");278279/* Set portE.5 to Digital IO */280MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2));281282/* Make portE.5 an output */283MCF5282_GPIO_DDRE |= (1 << 5);284285/* Now toggle portE.5 from low to high */286MCF5282_GPIO_PORTE &= ~(1 << 5);287MCF5282_GPIO_PORTE |= (1 << 5);288289printk(KERN_EMERG "Failed to hibernate. Halting!\n");290}291#endif292293void __init config_BSP(char *commandp, int size)294{295#ifdef CONFIG_WILDFIRE296mach_halt = wildfire_halt;297#endif298#ifdef CONFIG_WILDFIREMOD299mach_halt = wildfiremod_halt;300#endif301}302303/***************************************************************************/304305static int __init init_BSP(void)306{307mach_reset = m528x_cpu_reset;308m528x_uarts_init();309m528x_fec_init();310#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)311m528x_qspi_init();312#endif313platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));314return 0;315}316317arch_initcall(init_BSP);318319/***************************************************************************/320321322