1/* 2 * arch/arm/mach-ns9xxx/board-a9m9750dev.c 3 * 4 * Copyright (C) 2006,2007 by Digi International Inc. 5 * All rights reserved. 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 as published by 9 * the Free Software Foundation. 10 */ 11#include <linux/platform_device.h> 12#include <linux/serial_8250.h> 13#include <linux/irq.h> 14 15#include <asm/mach/map.h> 16 17#include <asm/arch-ns9xxx/board.h> 18#include <asm/arch-ns9xxx/regs-sys.h> 19#include <asm/arch-ns9xxx/regs-mem.h> 20#include <asm/arch-ns9xxx/regs-bbu.h> 21#include <asm/arch-ns9xxx/regs-board-a9m9750dev.h> 22 23#include "board-a9m9750dev.h" 24 25static struct map_desc board_a9m9750dev_io_desc[] __initdata = { 26 { /* FPGA on CS0 */ 27 .virtual = io_p2v(NS9XXX_CSxSTAT_PHYS(0)), 28 .pfn = __phys_to_pfn(NS9XXX_CSxSTAT_PHYS(0)), 29 .length = NS9XXX_CS0STAT_LENGTH, 30 .type = MT_DEVICE, 31 }, 32}; 33 34void __init board_a9m9750dev_map_io(void) 35{ 36 iotable_init(board_a9m9750dev_io_desc, 37 ARRAY_SIZE(board_a9m9750dev_io_desc)); 38} 39 40static void a9m9750dev_fpga_ack_irq(unsigned int irq) 41{ 42 /* nothing */ 43} 44 45static void a9m9750dev_fpga_mask_irq(unsigned int irq) 46{ 47 FPGA_IER &= ~(1 << (irq - FPGA_IRQ(0))); 48} 49 50static void a9m9750dev_fpga_maskack_irq(unsigned int irq) 51{ 52 a9m9750dev_fpga_mask_irq(irq); 53 a9m9750dev_fpga_ack_irq(irq); 54} 55 56static void a9m9750dev_fpga_unmask_irq(unsigned int irq) 57{ 58 FPGA_IER |= 1 << (irq - FPGA_IRQ(0)); 59} 60 61static struct irq_chip a9m9750dev_fpga_chip = { 62 .ack = a9m9750dev_fpga_ack_irq, 63 .mask = a9m9750dev_fpga_mask_irq, 64 .mask_ack = a9m9750dev_fpga_maskack_irq, 65 .unmask = a9m9750dev_fpga_unmask_irq, 66}; 67 68static void a9m9750dev_fpga_demux_handler(unsigned int irq, 69 struct irq_desc *desc) 70{ 71 int stat = FPGA_ISR; 72 73 while (stat != 0) { 74 int irqno = fls(stat) - 1; 75 76 stat &= ~(1 << irqno); 77 78 desc = irq_desc + FPGA_IRQ(irqno); 79 80 desc_handle_irq(irqno, desc); 81 } 82} 83 84void __init board_a9m9750dev_init_irq(void) 85{ 86 u32 reg; 87 int i; 88 89 /* 90 * configure gpio for IRQ_EXT2 91 * use GPIO 11, because GPIO 32 is used for the LCD 92 */ 93 BBU_GC(2) &= ~0x2000; 94 95 for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) { 96 set_irq_chip(i, &a9m9750dev_fpga_chip); 97 set_irq_handler(i, handle_level_irq); 98 set_irq_flags(i, IRQF_VALID); 99 } 100 101 /* IRQ_EXT2: level sensitive + active low */ 102 reg = SYS_EIC(2); 103 REGSET(reg, SYS_EIC, PLTY, AL); 104 REGSET(reg, SYS_EIC, LVEDG, LEVEL); 105 SYS_EIC(2) = reg; 106 107 set_irq_chained_handler(IRQ_EXT2, 108 a9m9750dev_fpga_demux_handler); 109} 110 111static struct plat_serial8250_port board_a9m9750dev_serial8250_port[] = { 112 { 113 .iobase = FPGA_UARTA_BASE, 114 .membase = (unsigned char*)FPGA_UARTA_BASE, 115 .mapbase = FPGA_UARTA_BASE, 116 .irq = IRQ_FPGA_UARTA, 117 .iotype = UPIO_MEM, 118 .uartclk = 18432000, 119 .regshift = 0, 120 .flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ, 121 }, { 122 .iobase = FPGA_UARTB_BASE, 123 .membase = (unsigned char*)FPGA_UARTB_BASE, 124 .mapbase = FPGA_UARTB_BASE, 125 .irq = IRQ_FPGA_UARTB, 126 .iotype = UPIO_MEM, 127 .uartclk = 18432000, 128 .regshift = 0, 129 .flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ, 130 }, { 131 .iobase = FPGA_UARTC_BASE, 132 .membase = (unsigned char*)FPGA_UARTC_BASE, 133 .mapbase = FPGA_UARTC_BASE, 134 .irq = IRQ_FPGA_UARTC, 135 .iotype = UPIO_MEM, 136 .uartclk = 18432000, 137 .regshift = 0, 138 .flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ, 139 }, { 140 .iobase = FPGA_UARTD_BASE, 141 .membase = (unsigned char*)FPGA_UARTD_BASE, 142 .mapbase = FPGA_UARTD_BASE, 143 .irq = IRQ_FPGA_UARTD, 144 .iotype = UPIO_MEM, 145 .uartclk = 18432000, 146 .regshift = 0, 147 .flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ, 148 }, { 149 /* end marker */ 150 }, 151}; 152 153static struct platform_device board_a9m9750dev_serial_device = { 154 .name = "serial8250", 155 .dev = { 156 .platform_data = board_a9m9750dev_serial8250_port, 157 }, 158}; 159 160static struct platform_device *board_a9m9750dev_devices[] __initdata = { 161 &board_a9m9750dev_serial_device, 162}; 163 164void __init board_a9m9750dev_init_machine(void) 165{ 166 u32 reg; 167 168 /* setup static CS0: memory base ... */ 169 REGSETIM(SYS_SMCSSMB(0), SYS_SMCSSMB, CSxB, 170 NS9XXX_CSxSTAT_PHYS(0) >> 12); 171 172 /* ... and mask */ 173 reg = SYS_SMCSSMM(0); 174 REGSETIM(reg, SYS_SMCSSMM, CSxM, 0xfffff); 175 REGSET(reg, SYS_SMCSSMM, CSEx, EN); 176 SYS_SMCSSMM(0) = reg; 177 178 /* setup static CS0: memory configuration */ 179 reg = MEM_SMC(0); 180 REGSET(reg, MEM_SMC, WSMC, OFF); 181 REGSET(reg, MEM_SMC, BSMC, OFF); 182 REGSET(reg, MEM_SMC, EW, OFF); 183 REGSET(reg, MEM_SMC, PB, 1); 184 REGSET(reg, MEM_SMC, PC, AL); 185 REGSET(reg, MEM_SMC, PM, DIS); 186 REGSET(reg, MEM_SMC, MW, 8); 187 MEM_SMC(0) = reg; 188 189 /* setup static CS0: timing */ 190 MEM_SMWED(0) = 0x2; 191 MEM_SMOED(0) = 0x2; 192 MEM_SMRD(0) = 0x6; 193 MEM_SMWD(0) = 0x6; 194 195 platform_add_devices(board_a9m9750dev_devices, 196 ARRAY_SIZE(board_a9m9750dev_devices)); 197} 198