2007-02-16 15:36:55 +01:00
/*
* arch / arm / mach - ns9xxx / board - a9m9750dev . c
*
* Copyright ( C ) 2006 , 2007 by Digi International Inc .
* All rights reserved .
*
* 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 .
*/
# include <linux/irq.h>
# include <asm/mach/map.h>
2007-09-30 20:36:14 +01:00
# include <asm/gpio.h>
2007-02-16 15:36:55 +01:00
2008-08-05 16:14:15 +01:00
# include <mach/board.h>
# include <mach/processor-ns9360.h>
# include <mach/regs-sys-ns9360.h>
# include <mach/regs-mem.h>
# include <mach/regs-bbu.h>
# include <mach/regs-board-a9m9750dev.h>
2007-02-16 15:36:55 +01:00
# include "board-a9m9750dev.h"
static struct map_desc board_a9m9750dev_io_desc [ ] __initdata = {
{ /* FPGA on CS0 */
. virtual = io_p2v ( NS9XXX_CSxSTAT_PHYS ( 0 ) ) ,
. pfn = __phys_to_pfn ( NS9XXX_CSxSTAT_PHYS ( 0 ) ) ,
. length = NS9XXX_CS0STAT_LENGTH ,
. type = MT_DEVICE ,
} ,
} ;
void __init board_a9m9750dev_map_io ( void )
{
iotable_init ( board_a9m9750dev_io_desc ,
ARRAY_SIZE ( board_a9m9750dev_io_desc ) ) ;
}
static void a9m9750dev_fpga_ack_irq ( unsigned int irq )
{
/* nothing */
}
static void a9m9750dev_fpga_mask_irq ( unsigned int irq )
{
2007-09-30 20:36:33 +01:00
u8 ier ;
ier = __raw_readb ( FPGA_IER ) ;
ier & = ~ ( 1 < < ( irq - FPGA_IRQ ( 0 ) ) ) ;
__raw_writeb ( ier , FPGA_IER ) ;
2007-02-16 15:36:55 +01:00
}
static void a9m9750dev_fpga_maskack_irq ( unsigned int irq )
{
a9m9750dev_fpga_mask_irq ( irq ) ;
a9m9750dev_fpga_ack_irq ( irq ) ;
}
static void a9m9750dev_fpga_unmask_irq ( unsigned int irq )
{
2007-09-30 20:36:33 +01:00
u8 ier ;
ier = __raw_readb ( FPGA_IER ) ;
ier | = 1 < < ( irq - FPGA_IRQ ( 0 ) ) ;
__raw_writeb ( ier , FPGA_IER ) ;
2007-02-16 15:36:55 +01:00
}
static struct irq_chip a9m9750dev_fpga_chip = {
. ack = a9m9750dev_fpga_ack_irq ,
. mask = a9m9750dev_fpga_mask_irq ,
. mask_ack = a9m9750dev_fpga_maskack_irq ,
. unmask = a9m9750dev_fpga_unmask_irq ,
} ;
static void a9m9750dev_fpga_demux_handler ( unsigned int irq ,
struct irq_desc * desc )
{
2007-09-30 20:36:33 +01:00
u8 stat = __raw_readb ( FPGA_ISR ) ;
2007-02-16 15:36:55 +01:00
2007-09-30 20:34:41 +01:00
desc - > chip - > mask_ack ( irq ) ;
2007-02-16 15:36:55 +01:00
while ( stat ! = 0 ) {
int irqno = fls ( stat ) - 1 ;
stat & = ~ ( 1 < < irqno ) ;
2008-10-09 13:36:24 +01:00
generic_handle_irq ( FPGA_IRQ ( irqno ) ) ;
2007-02-16 15:36:55 +01:00
}
2007-09-30 20:34:41 +01:00
desc - > chip - > unmask ( irq ) ;
2007-02-16 15:36:55 +01:00
}
void __init board_a9m9750dev_init_irq ( void )
{
2007-09-30 20:36:33 +01:00
u32 eic ;
2007-02-16 15:36:55 +01:00
int i ;
2007-09-30 20:36:14 +01:00
if ( gpio_request ( 11 , " board a9m9750dev extirq2 " ) = = 0 )
2008-02-15 08:41:06 +01:00
ns9360_gpio_configure ( 11 , 0 , 1 ) ;
2007-09-30 20:36:14 +01:00
else
2008-02-15 08:41:06 +01:00
printk ( KERN_ERR " %s: cannot get gpio 11 for IRQ_NS9XXX_EXT2 \n " ,
2007-09-30 20:36:14 +01:00
__func__ ) ;
2007-02-16 15:36:55 +01:00
for ( i = FPGA_IRQ ( 0 ) ; i < = FPGA_IRQ ( 7 ) ; + + i ) {
set_irq_chip ( i , & a9m9750dev_fpga_chip ) ;
set_irq_handler ( i , handle_level_irq ) ;
set_irq_flags ( i , IRQF_VALID ) ;
}
2008-02-15 08:41:06 +01:00
/* IRQ_NS9XXX_EXT2: level sensitive + active low */
2007-09-30 20:36:33 +01:00
eic = __raw_readl ( SYS_EIC ( 2 ) ) ;
REGSET ( eic , SYS_EIC , PLTY , AL ) ;
REGSET ( eic , SYS_EIC , LVEDG , LEVEL ) ;
__raw_writel ( eic , SYS_EIC ( 2 ) ) ;
2007-02-16 15:36:55 +01:00
2008-02-15 08:41:06 +01:00
set_irq_chained_handler ( IRQ_NS9XXX_EXT2 ,
2007-02-16 15:36:55 +01:00
a9m9750dev_fpga_demux_handler ) ;
}
void __init board_a9m9750dev_init_machine ( void )
{
u32 reg ;
/* setup static CS0: memory base ... */
2007-09-30 20:36:33 +01:00
reg = __raw_readl ( SYS_SMCSSMB ( 0 ) ) ;
REGSETIM ( reg , SYS_SMCSSMB , CSxB , NS9XXX_CSxSTAT_PHYS ( 0 ) > > 12 ) ;
__raw_writel ( reg , SYS_SMCSSMB ( 0 ) ) ;
2007-02-16 15:36:55 +01:00
/* ... and mask */
2007-09-30 20:36:33 +01:00
reg = __raw_readl ( SYS_SMCSSMM ( 0 ) ) ;
2007-02-16 15:36:55 +01:00
REGSETIM ( reg , SYS_SMCSSMM , CSxM , 0xfffff ) ;
REGSET ( reg , SYS_SMCSSMM , CSEx , EN ) ;
2007-09-30 20:36:33 +01:00
__raw_writel ( reg , SYS_SMCSSMM ( 0 ) ) ;
2007-02-16 15:36:55 +01:00
/* setup static CS0: memory configuration */
2007-09-30 20:36:33 +01:00
reg = __raw_readl ( MEM_SMC ( 0 ) ) ;
2007-07-17 22:35:52 +01:00
REGSET ( reg , MEM_SMC , PSMC , OFF ) ;
2007-02-16 15:36:55 +01:00
REGSET ( reg , MEM_SMC , BSMC , OFF ) ;
REGSET ( reg , MEM_SMC , EW , OFF ) ;
REGSET ( reg , MEM_SMC , PB , 1 ) ;
REGSET ( reg , MEM_SMC , PC , AL ) ;
REGSET ( reg , MEM_SMC , PM , DIS ) ;
REGSET ( reg , MEM_SMC , MW , 8 ) ;
2007-09-30 20:36:33 +01:00
__raw_writel ( reg , MEM_SMC ( 0 ) ) ;
2007-02-16 15:36:55 +01:00
/* setup static CS0: timing */
2007-09-30 20:36:33 +01:00
__raw_writel ( 0x2 , MEM_SMWED ( 0 ) ) ;
__raw_writel ( 0x2 , MEM_SMOED ( 0 ) ) ;
__raw_writel ( 0x6 , MEM_SMRD ( 0 ) ) ;
__raw_writel ( 0x6 , MEM_SMWD ( 0 ) ) ;
2007-02-16 15:36:55 +01:00
}