From: hackbard Date: Fri, 17 Jul 2015 15:49:49 +0000 (+0200) Subject: added ea313x.c file ... X-Git-Url: https://hackdaworld.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=63332d9d23c401d24aa6f751fc6c412ff54d49c2;p=outofuni%2Fdib.git added ea313x.c file ... --- diff --git a/files/nellboard/ea313x.c b/files/nellboard/ea313x.c new file mode 100644 index 0000000..bbcddaa --- /dev/null +++ b/files/nellboard/ea313x.c @@ -0,0 +1,572 @@ +/* arch/arm/mach-lpc313x/ea313x.c + * + * Author: Durgesh Pattamatta + * Copyright (C) 2009 NXP semiconductors + * + * ea313x board init routines. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +/* +static struct lpc313x_mci_irq_data irq_data = { + .irq = IRQ_SDMMC_CD, +}; +*/ + +static int mci_get_cd(u32 slot_id) +{ + return 0; //gpio_get_value(GPIO_MNAND_RYBN2); +} + +#if 0 +static irqreturn_t ea313x_mci_detect_interrupt(int irq, void *data) +{ + struct lpc313x_mci_irq_data *pdata = data; + + /* select the opposite level senstivity */ + int level = mci_get_cd(0)?IRQ_TYPE_LEVEL_LOW:IRQ_TYPE_LEVEL_HIGH; + + set_irq_type(pdata->irq, level); + + /* change the polarity of irq trigger */ + return pdata->irq_hdlr(irq, pdata->data); +} +#endif + +static int mci_init(u32 slot_id, irq_handler_t irqhdlr, void *data) +{ + //int ret; + //int level; + + /* enable power to the slot */ +// gpio_set_value(GPIO_MI2STX_DATA0, 0); + + /* set cd pins as GPIO pins */ +// gpio_direction_input(GPIO_MNAND_RYBN2); +#if 0 + /* select the opposite level senstivity */ + level = mci_get_cd(0)?IRQ_TYPE_LEVEL_LOW:IRQ_TYPE_LEVEL_HIGH; + /* set card detect irq info */ + irq_data.data = data; + irq_data.irq_hdlr = irqhdlr; + set_irq_type(irq_data.irq, level); + ret = request_irq(irq_data.irq, + ea313x_mci_detect_interrupt, + level, + "mmc-cd", + &irq_data); + /****temporary for PM testing */ + enable_irq_wake(irq_data.irq); + + return irq_data.irq; +#endif + return 0; +} + +static int mci_get_ro(u32 slot_id) +{ + return 0; +} + +static int mci_get_ocr(u32 slot_id) +{ + return MMC_VDD_32_33 | MMC_VDD_33_34; +} + +static void mci_setpower(u32 slot_id, u32 volt) +{ + /* on current version of EA board the card detect + * pull-up in on switched power side. So can't do + * power management so use the always enable power + * jumper. + */ +} +static int mci_get_bus_wd(u32 slot_id) +{ + return 4; +} + +static void mci_exit(u32 slot_id) +{ + //free_irq(irq_data.irq, &irq_data); +} + +static struct resource lpc313x_mci_resources[] = { + [0] = { + .start = IO_SDMMC_PHYS, + .end = IO_SDMMC_PHYS + IO_SDMMC_SIZE, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_MCI, + .end = IRQ_MCI, + .flags = IORESOURCE_IRQ, + }, +}; +static struct lpc313x_mci_board ea313x_mci_platform_data = { + .num_slots = 1, + .detect_delay_ms = 250, + .init = mci_init, + .get_ro = mci_get_ro, + .get_cd = mci_get_cd, + .get_ocr = mci_get_ocr, + .get_bus_wd = mci_get_bus_wd, + .setpower = mci_setpower, + .exit = mci_exit, +}; + +static u64 mci_dmamask = 0xffffffffUL; +static struct platform_device lpc313x_mci_device = { + .name = "lpc313x_mmc", + .num_resources = ARRAY_SIZE(lpc313x_mci_resources), + .dev = { + .dma_mask = &mci_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &ea313x_mci_platform_data, + }, + .resource = lpc313x_mci_resources, +}; + +/* + * DM9000 ethernet device + */ +#if defined(CONFIG_DM9000) +static struct resource dm9000_resource[] = { + [0] = { + .start = EXT_SRAM1_PHYS, + .end = EXT_SRAM1_PHYS + 0xFF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = EXT_SRAM1_PHYS + 0x10000, + .end = EXT_SRAM1_PHYS + 0x100FF, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_DM9000_ETH_INT, + .end = IRQ_DM9000_ETH_INT, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, + } +}; +/* ARM MPMC contoller as part of low power design doesn't de-assert nCS and nOE for consecutive +reads but just changes address. But DM9000 requires nCS and nOE change between address. So access +other chip select area (nCS0) to force de-assertion of nCS1 and nOE1. Or else wait for long time +such as 80 usecs. +LPC313x has external logic outside of MPMC IP to toggle nOE to split consecutive reads. +The latest Apex bootloader pacth makes use of this feture. +For this to work SYS_MPMC_WTD_DEL0 & SYS_MPMC_WTD_DEL1 should be programmed with MPMC_STWTRD0 +& MPMC_STWTRD1 values. The logic only deactivates the nOE for one clock cycle which is +11nsec but DM9000 needs 80nsec between nOEs. So lets add some dummy instructions such as +reading a GPIO register to compensate for extra 70nsec. +*/ +# define DM_IO_DELAY() do { gpio_get_value(GPIO_MNAND_RYBN3);} while(0) + +static void dm9000_dumpblk(void __iomem *reg, int count) +{ + int i; + int tmp; + + count = (count + 1) >> 1; + for (i = 0; i < count; i++) { + DM_IO_DELAY(); + tmp = readw(reg); + } +} + +static void dm9000_inblk(void __iomem *reg, void *data, int count) +{ + int i; + u16* pdata = (u16*)data; + count = (count + 1) >> 1; + for (i = 0; i < count; i++) { + DM_IO_DELAY(); + *pdata++ = readw(reg); + } +} + +static struct dm9000_plat_data dm9000_platdata = { + .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM | DM9000_PLATF_SIMPLE_PHY, + .dumpblk = dm9000_dumpblk, + .inblk = dm9000_inblk, +}; + +static struct platform_device dm9000_device = { + .name = "dm9000", + .id = 0, + .num_resources = ARRAY_SIZE(dm9000_resource), + .resource = dm9000_resource, + .dev = { + .platform_data = &dm9000_platdata, + } +}; +static void __init ea_add_device_dm9000(void) +{ + /* + * Configure Chip-Select 2 on SMC for the DM9000. + * Note: These timings were calculated for MASTER_CLOCK = 90000000 + * according to the DM9000 timings. + */ + MPMC_STCONFIG1 = 0x81; + MPMC_STWTWEN1 = 1; + MPMC_STWTOEN1 = 1; + MPMC_STWTRD1 = 4; + MPMC_STWTPG1 = 1; + MPMC_STWTWR1 = 1; + MPMC_STWTTURN1 = 2; + /* enable oe toggle between consec reads */ + SYS_MPMC_WTD_DEL1 = _BIT(5) | 4; + + /* Configure Interrupt pin as input, no pull-up */ + gpio_direction_input(GPIO_MNAND_RYBN3); + + platform_device_register(&dm9000_device); +} +#else +static void __init ea_add_device_dm9000(void) {} +#endif /* CONFIG_DM9000 */ + + +#if defined (CONFIG_MTD_NAND_LPC313X) +static struct resource lpc313x_nand_resources[] = { + [0] = { + .start = IO_NAND_PHYS, + .end = IO_NAND_PHYS + IO_NAND_SIZE, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IO_NAND_BUF_PHYS, + .end = IO_NAND_BUF_PHYS + IO_NAND_BUF_SIZE, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = IRQ_NAND_FLASH, + .end = IRQ_NAND_FLASH, + .flags = IORESOURCE_IRQ, + } +}; + +#define BLK_SIZE (2048 * 64) +static struct mtd_partition ea313x_nand0_partitions[] = { + /* The EA3131 board uses the following block scheme: + 128K: Blocks 0 - 0 - LPC31xx info and bad block table + 384K: Blocks 1 - 3 - Apex bootloader + 256K: Blocks 4 - 5 - Apex environment + 4M: Blocks 6 - 37 - Kernel image + 16M: Blocks 38 - 165 - Ramdisk image (if used) + ???: Blocks 166 - end - Root filesystem/storage */ + { + .name = "lpc313x-rootfs", + .offset = (BLK_SIZE * 166), + .size = MTDPART_SIZ_FULL + }, +}; + +static struct lpc313x_nand_timing ea313x_nanddev_timing = { + .ns_trsd = 36, + .ns_tals = 36, + .ns_talh = 12, + .ns_tcls = 36, + .ns_tclh = 12, + .ns_tdrd = 36, + .ns_tebidel = 12, + .ns_tch = 12, + .ns_tcs = 48, + .ns_treh = 24, + .ns_trp = 48, + .ns_trw = 24, + .ns_twp = 36 +}; + +static struct lpc313x_nand_dev_info ea313x_ndev[] = { + { + .name = "nand0", + .nr_partitions = ARRAY_SIZE(ea313x_nand0_partitions), + .partitions = ea313x_nand0_partitions + } +}; + +static struct lpc313x_nand_cfg ea313x_plat_nand = { + .nr_devices = ARRAY_SIZE(ea313x_ndev), + .devices = ea313x_ndev, + .timing = &ea313x_nanddev_timing, + .support_16bit = 0, +}; + +static u64 nand_dmamask = 0xffffffffUL; +static struct platform_device lpc313x_nand_device = { + .name = "lpc313x_nand", + .dev = { + .dma_mask = &nand_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &ea313x_plat_nand, + }, + .num_resources = ARRAY_SIZE(lpc313x_nand_resources), + .resource = lpc313x_nand_resources, +}; +#endif + +#if defined(CONFIG_SPI_LPC313X) +static struct resource lpc313x_spi_resources[] = { + [0] = { + .start = SPI_PHYS, + .end = SPI_PHYS + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SPI, + .end = IRQ_SPI, + .flags = IORESOURCE_IRQ, + }, +}; + +static void spi_set_cs_state(int cs_num, int state) +{ + + /* get the correct GPIO mapping */ + if (cs_num == 1) { + cs_num = 0 ; + } else if (cs_num == 0) { + cs_num = 1 ; + } else if ((cs_num > 4) && (cs_num <= 20)) { + cs_num = cs_num - 6 ; + } + + /* DELETE_MAKRO_ASDQWERTZ089 printk("Chipselect Called with cs_pin=%d to value=%d\n",cs_num,state); */ + gpio_set_value(cs_num, state); + /* DELETE_MAKRO_ASDQWERTZ089 printk("Aftercalled\n"); */ + +} + +struct lpc313x_spics_cfg lpc313x_stdspics_cfg[] = +{ + /* SPI CS0 */ + [0] = + { + .spi_spo = 0, /* Low clock between transfers */ + .spi_sph = 0, /* Data capture on first clock edge (high edge with spi_spo=0) */ + .spi_cs_set = spi_set_cs_state, + }, +}; + +struct lpc313x_spi_cfg lpc313x_spidata = +{ + .num_cs = ARRAY_SIZE(lpc313x_stdspics_cfg), + .spics_cfg = lpc313x_stdspics_cfg, +}; + +static u64 lpc313x_spi_dma_mask = 0xffffffffUL; +static struct platform_device lpc313x_spi_device = { + .name = "spi_lpc313x", + .id = 0, + .dev = { + .dma_mask = &lpc313x_spi_dma_mask, + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &lpc313x_spidata, + }, + .num_resources = ARRAY_SIZE(lpc313x_spi_resources), + .resource = lpc313x_spi_resources, +}; + + + + +#if defined(CONFIG_MTD_DATAFLASH) +/* MTD Data FLASH driver registration */ +static int __init lpc313x_spimtd_register(void) +{ + struct spi_board_info info = + { + .modalias = "mtd_dataflash", + .max_speed_hz = 30000000, + .bus_num = 0, + .chip_select = 0, + }; + + return spi_register_board_info(&info, 1); +} +arch_initcall(lpc313x_spimtd_register); +#endif +#endif + +static struct platform_device *devices[] __initdata = { + &lpc313x_mci_device, +#if defined (CONFIG_MTD_NAND_LPC313X) + &lpc313x_nand_device, +#endif +#if defined(CONFIG_SPI_LPC313X) + &lpc313x_spi_device, +#endif +}; + +static struct map_desc ea313x_io_desc[] __initdata = { + { + .virtual = io_p2v(EXT_SRAM0_PHYS), + .pfn = __phys_to_pfn(EXT_SRAM0_PHYS), + .length = SZ_4K, + .type = MT_DEVICE + }, + { + .virtual = io_p2v(EXT_SRAM1_PHYS + 0x10000), + .pfn = __phys_to_pfn(EXT_SRAM1_PHYS + 0x10000), + .length = SZ_4K, + .type = MT_DEVICE + }, + { + .virtual = io_p2v(IO_SDMMC_PHYS), + .pfn = __phys_to_pfn(IO_SDMMC_PHYS), + .length = IO_SDMMC_SIZE, + .type = MT_DEVICE + }, + { + .virtual = io_p2v(IO_USB_PHYS), + .pfn = __phys_to_pfn(IO_USB_PHYS), + .length = IO_USB_SIZE, + .type = MT_DEVICE + }, +}; +/* +struct pca953x_platform_data pca9555_plaform_info = { + .gpio_base = 98, + .invert = 0, + //.setup = pca_9555_setup, +}; +static struct i2c_board_info ea313x_i2c_devices[] __initdata = { + { + I2C_BOARD_INFO("pca9555", 0x20), + .platform_data = &pca9555_plaform_info, + }, +}; +*/ +/* +static struct sc16is7x2_platform_data sc16is7x2_SERIALPORT3_data = { + .uartclk = 1843200, + .uart_base = 0, + .gpio_base = 178, + .label = NULL, + .names = NULL, +}; + +static int __init lpc313x_sc16is7x2_register(void) +{ + struct spi_board_info info = + { + .modalias = "sc16is7x2", + .platform_data = &sc16is7x2_SERIALPORT3_data, + .bus_num = 0, + .irq = gpio_to_irq(14), + .chip_select = 15, + .max_speed_hz = 187500, + .mode = SPI_MODE_0, + //.controller_data = &sc16is7x2_mcspi_config, + //.modalias = "sc16is7x2", + //.max_speed_hz = 10000000, + //.bus_num = 0, + //.irq = IRQ_GPIO_14,//IRQ_GPIO14 + //.chip_select = 1, + }; + + return spi_register_board_info(&info, 1); +} +arch_initcall(lpc313x_sc16is7x2_register); +*/ +#if defined(CONFIG_MACH_EA3152) +static struct i2c_board_info ea3152_i2c1_devices[] __initdata = { + { + I2C_BOARD_INFO("lpc3152-psu", 0x0C), + }, +}; +#endif + + +static void __init ea313x_init(void) +{ + lpc313x_init(); + + platform_add_devices(devices, ARRAY_SIZE(devices)); + + /* register i2cdevices */ + lpc313x_register_i2c_devices(); + //i2c_register_board_info(1, ea313x_i2c_devices, ARRAY_SIZE(ea313x_i2c_devices)); + +#if defined(CONFIG_MACH_EA3152) + i2c_register_board_info(1, ea3152_i2c1_devices, + ARRAY_SIZE(ea3152_i2c1_devices)); +#endif + + +} + +static void __init ea313x_map_io(void) +{ + lpc313x_map_io(); + iotable_init(ea313x_io_desc, ARRAY_SIZE(ea313x_io_desc)); +} + +#if defined(CONFIG_MACH_EA3152) +MACHINE_START(EA3152, "NXP EA3152") + /* Maintainer: Durgesh Pattamatta, NXP */ + .phys_io = IO_APB01_PHYS, + .io_pg_offst = (io_p2v(IO_APB01_PHYS) >> 18) & 0xfffc, + .boot_params = 0x30000100, + .map_io = ea313x_map_io, + .init_irq = lpc313x_init_irq, + .timer = &lpc313x_timer, + .init_machine = ea313x_init, +MACHINE_END +#endif + +#if defined(CONFIG_MACH_EA313X) +MACHINE_START(EA313X, "NXP EA313X") + /* Maintainer: Durgesh Pattamatta, NXP */ + .phys_io = IO_APB01_PHYS, + .io_pg_offst = (io_p2v(IO_APB01_PHYS) >> 18) & 0xfffc, + .boot_params = 0x30000100, + .map_io = ea313x_map_io, + .init_irq = lpc313x_init_irq, + .timer = &lpc313x_timer, + .init_machine = ea313x_init, +MACHINE_END +#endif +