2007-10-23 20:55:55 +04:00
/*
2011-11-10 16:06:21 +04:00
* MTX - 1 platform devices registration ( Au1500 )
2007-10-23 20:55:55 +04:00
*
2009-08-02 01:51:20 +04:00
* Copyright ( C ) 2007 - 2009 , Florian Fainelli < florian @ openwrt . org >
2007-10-23 20:55:55 +04:00
*
* 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 . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
# include <linux/init.h>
2011-11-10 16:06:21 +04:00
# include <linux/interrupt.h>
# include <linux/kernel.h>
2007-10-23 20:55:55 +04:00
# include <linux/platform_device.h>
# include <linux/leds.h>
2008-04-30 23:30:12 +04:00
# include <linux/gpio.h>
2008-01-07 21:00:46 +03:00
# include <linux/gpio_keys.h>
# include <linux/input.h>
2008-07-11 17:34:48 +04:00
# include <linux/mtd/partitions.h>
# include <linux/mtd/physmap.h>
# include <mtd/mtd-abi.h>
2011-11-10 16:06:21 +04:00
# include <asm/bootinfo.h>
# include <asm/reboot.h>
# include <asm/mach-au1x00/au1000.h>
2015-08-02 19:30:11 +03:00
# include <asm/mach-au1x00/gpio-au1000.h>
2011-02-27 21:53:53 +03:00
# include <asm/mach-au1x00/au1xxx_eth.h>
2011-11-10 16:06:21 +04:00
# include <prom.h>
const char * get_system_type ( void )
{
return " MTX-1 " ;
}
void __init prom_init ( void )
{
unsigned char * memsize_str ;
unsigned long memsize ;
prom_argc = fw_arg0 ;
prom_argv = ( char * * ) fw_arg1 ;
prom_envp = ( char * * ) fw_arg2 ;
prom_init_cmdline ( ) ;
memsize_str = prom_getenv ( " memsize " ) ;
2014-02-20 17:37:40 +04:00
if ( ! memsize_str | | kstrtoul ( memsize_str , 0 , & memsize ) )
2011-11-10 16:06:21 +04:00
memsize = 0x04000000 ;
add_memory_region ( 0 , memsize , BOOT_MEM_RAM ) ;
}
void prom_putchar ( unsigned char c )
{
alchemy_uart_putchar ( AU1000_UART0_PHYS_ADDR , c ) ;
}
static void mtx1_reset ( char * c )
{
/* Jump to the reset vector */
__asm__ __volatile__ ( " jr \t %0 " : : " r " ( 0xbfc00000 ) ) ;
}
static void mtx1_power_off ( void )
{
while ( 1 )
asm volatile (
" .set mips32 \n "
" wait \n "
" .set mips0 \n " ) ;
}
void __init board_setup ( void )
{
2012-01-31 21:19:03 +04:00
# if IS_ENABLED(CONFIG_USB_OHCI_HCD)
2011-11-10 16:06:21 +04:00
/* Enable USB power switch */
alchemy_gpio_direction_output ( 204 , 0 ) ;
2012-01-31 21:19:03 +04:00
# endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */
2011-11-10 16:06:21 +04:00
/* Initialize sys_pinfunc */
2014-07-23 18:36:24 +04:00
alchemy_wrsys ( SYS_PF_NI2 , AU1000_SYS_PINFUNC ) ;
2011-11-10 16:06:21 +04:00
/* Initialize GPIO */
2014-07-23 18:36:24 +04:00
alchemy_wrsys ( ~ 0 , AU1000_SYS_TRIOUTCLR ) ;
2011-11-10 16:06:21 +04:00
alchemy_gpio_direction_output ( 0 , 0 ) ; /* Disable M66EN (PCI 66MHz) */
alchemy_gpio_direction_output ( 3 , 1 ) ; /* Disable PCI CLKRUN# */
alchemy_gpio_direction_output ( 1 , 1 ) ; /* Enable EXT_IO3 */
alchemy_gpio_direction_output ( 5 , 0 ) ; /* Disable eth PHY TX_ER */
/* Enable LED and set it to green */
alchemy_gpio_direction_output ( 211 , 1 ) ; /* green on */
alchemy_gpio_direction_output ( 212 , 0 ) ; /* red off */
pm_power_off = mtx1_power_off ;
_machine_halt = mtx1_power_off ;
_machine_restart = mtx1_reset ;
printk ( KERN_INFO " 4G Systems MTX-1 Board \n " ) ;
}
/******************************************************************************/
2011-02-27 21:53:53 +03:00
2008-01-07 21:00:46 +03:00
static struct gpio_keys_button mtx1_gpio_button [ ] = {
{
. gpio = 207 ,
. code = BTN_0 ,
. desc = " System button " ,
}
} ;
static struct gpio_keys_platform_data mtx1_buttons_data = {
. buttons = mtx1_gpio_button ,
. nbuttons = ARRAY_SIZE ( mtx1_gpio_button ) ,
} ;
static struct platform_device mtx1_button = {
. name = " gpio-keys " ,
. id = - 1 ,
. dev = {
. platform_data = & mtx1_buttons_data ,
}
} ;
2007-10-23 20:55:55 +04:00
static struct resource mtx1_wdt_res [ ] = {
[ 0 ] = {
2011-05-08 12:42:20 +04:00
. start = 215 ,
. end = 215 ,
2007-10-23 20:55:55 +04:00
. name = " mtx1-wdt-gpio " ,
. flags = IORESOURCE_IRQ ,
}
} ;
static struct platform_device mtx1_wdt = {
. name = " mtx1-wdt " ,
. id = 0 ,
. num_resources = ARRAY_SIZE ( mtx1_wdt_res ) ,
. resource = mtx1_wdt_res ,
} ;
static struct gpio_led default_leds [ ] = {
{
. name = " mtx1:green " ,
. gpio = 211 ,
} , {
. name = " mtx1:red " ,
. gpio = 212 ,
} ,
} ;
static struct gpio_led_platform_data mtx1_led_data = {
. num_leds = ARRAY_SIZE ( default_leds ) ,
. leds = default_leds ,
} ;
static struct platform_device mtx1_gpio_leds = {
. name = " leds-gpio " ,
. id = - 1 ,
. dev = {
. platform_data = & mtx1_led_data ,
}
} ;
2008-07-11 17:34:48 +04:00
static struct mtd_partition mtx1_mtd_partitions [ ] = {
{
. name = " filesystem " ,
. size = 0x01C00000 ,
2013-01-22 15:59:30 +04:00
. offset = 0 ,
2008-07-11 17:34:48 +04:00
} ,
{
. name = " yamon " ,
. size = 0x00100000 ,
2013-01-22 15:59:30 +04:00
. offset = MTDPART_OFS_APPEND ,
2008-07-11 17:34:48 +04:00
. mask_flags = MTD_WRITEABLE ,
} ,
{
. name = " kernel " ,
. size = 0x002c0000 ,
2013-01-22 15:59:30 +04:00
. offset = MTDPART_OFS_APPEND ,
2008-07-11 17:34:48 +04:00
} ,
{
. name = " yamon env " ,
. size = 0x00040000 ,
2013-01-22 15:59:30 +04:00
. offset = MTDPART_OFS_APPEND ,
2008-07-11 17:34:48 +04:00
} ,
} ;
static struct physmap_flash_data mtx1_flash_data = {
. width = 4 ,
. nr_parts = 4 ,
. parts = mtx1_mtd_partitions ,
} ;
static struct resource mtx1_mtd_resource = {
. start = 0x1e000000 ,
. end = 0x1fffffff ,
. flags = IORESOURCE_MEM ,
} ;
static struct platform_device mtx1_mtd = {
. name = " physmap-flash " ,
. dev = {
. platform_data = & mtx1_flash_data ,
} ,
. num_resources = 1 ,
. resource = & mtx1_mtd_resource ,
} ;
2011-08-12 13:39:44 +04:00
static struct resource alchemy_pci_host_res [ ] = {
[ 0 ] = {
. start = AU1500_PCI_PHYS_ADDR ,
. end = AU1500_PCI_PHYS_ADDR + 0xfff ,
. flags = IORESOURCE_MEM ,
} ,
} ;
static int mtx1_pci_idsel ( unsigned int devsel , int assert )
{
/* This function is only necessary to support a proprietary Cardbus
* adapter on the mtx - 1 " singleboard " variant . It triggers a custom
* logic chip connected to EXT_IO3 ( GPIO1 ) to suppress IDSEL signals .
*/
2012-07-13 00:54:05 +04:00
udelay ( 1 ) ;
2011-08-12 13:39:44 +04:00
if ( assert & & devsel ! = 0 )
/* Suppress signal to Cardbus */
alchemy_gpio_set_value ( 1 , 0 ) ; /* set EXT_IO3 OFF */
else
alchemy_gpio_set_value ( 1 , 1 ) ; /* set EXT_IO3 ON */
udelay ( 1 ) ;
return 1 ;
}
static const char mtx1_irqtab [ ] [ 5 ] = {
[ 0 ] = { - 1 , AU1500_PCI_INTA , AU1500_PCI_INTA , 0xff , 0xff } , /* IDSEL 00 - AdapterA-Slot0 (top) */
[ 1 ] = { - 1 , AU1500_PCI_INTB , AU1500_PCI_INTA , 0xff , 0xff } , /* IDSEL 01 - AdapterA-Slot1 (bottom) */
[ 2 ] = { - 1 , AU1500_PCI_INTC , AU1500_PCI_INTD , 0xff , 0xff } , /* IDSEL 02 - AdapterB-Slot0 (top) */
[ 3 ] = { - 1 , AU1500_PCI_INTD , AU1500_PCI_INTC , 0xff , 0xff } , /* IDSEL 03 - AdapterB-Slot1 (bottom) */
[ 4 ] = { - 1 , AU1500_PCI_INTA , AU1500_PCI_INTB , 0xff , 0xff } , /* IDSEL 04 - AdapterC-Slot0 (top) */
[ 5 ] = { - 1 , AU1500_PCI_INTB , AU1500_PCI_INTA , 0xff , 0xff } , /* IDSEL 05 - AdapterC-Slot1 (bottom) */
[ 6 ] = { - 1 , AU1500_PCI_INTC , AU1500_PCI_INTD , 0xff , 0xff } , /* IDSEL 06 - AdapterD-Slot0 (top) */
[ 7 ] = { - 1 , AU1500_PCI_INTD , AU1500_PCI_INTC , 0xff , 0xff } , /* IDSEL 07 - AdapterD-Slot1 (bottom) */
} ;
static int mtx1_map_pci_irq ( const struct pci_dev * d , u8 slot , u8 pin )
{
return mtx1_irqtab [ slot ] [ pin ] ;
}
static struct alchemy_pci_platdata mtx1_pci_pd = {
. board_map_irq = mtx1_map_pci_irq ,
. board_pci_idsel = mtx1_pci_idsel ,
. pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H |
PCI_CONFIG_CH |
# if defined(__MIPSEB__)
PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM ,
# else
0 ,
# endif
} ;
static struct platform_device mtx1_pci_host = {
. dev . platform_data = & mtx1_pci_pd ,
. name = " alchemy-pci " ,
. id = 0 ,
. num_resources = ARRAY_SIZE ( alchemy_pci_host_res ) ,
. resource = alchemy_pci_host_res ,
} ;
2013-09-30 17:09:20 +04:00
static struct platform_device * mtx1_devs [ ] __initdata = {
2011-08-12 13:39:44 +04:00
& mtx1_pci_host ,
2007-10-23 20:55:55 +04:00
& mtx1_gpio_leds ,
2008-01-07 21:00:46 +03:00
& mtx1_wdt ,
2008-07-11 17:34:48 +04:00
& mtx1_button ,
& mtx1_mtd ,
2007-10-23 20:55:55 +04:00
} ;
2011-02-27 21:53:53 +03:00
static struct au1000_eth_platform_data mtx1_au1000_eth0_pdata = {
. phy_search_highest_addr = 1 ,
2011-11-10 16:06:21 +04:00
. phy1_search_mac0 = 1 ,
2011-02-27 21:53:53 +03:00
} ;
2007-10-23 20:55:55 +04:00
static int __init mtx1_register_devices ( void )
{
2009-08-02 01:51:20 +04:00
int rc ;
2011-11-10 16:06:21 +04:00
irq_set_irq_type ( AU1500_GPIO204_INT , IRQ_TYPE_LEVEL_HIGH ) ;
irq_set_irq_type ( AU1500_GPIO201_INT , IRQ_TYPE_LEVEL_LOW ) ;
irq_set_irq_type ( AU1500_GPIO202_INT , IRQ_TYPE_LEVEL_LOW ) ;
irq_set_irq_type ( AU1500_GPIO203_INT , IRQ_TYPE_LEVEL_LOW ) ;
irq_set_irq_type ( AU1500_GPIO205_INT , IRQ_TYPE_LEVEL_LOW ) ;
2011-02-27 21:53:53 +03:00
au1xxx_override_eth_cfg ( 0 , & mtx1_au1000_eth0_pdata ) ;
2009-08-02 01:51:20 +04:00
rc = gpio_request ( mtx1_gpio_button [ 0 ] . gpio ,
mtx1_gpio_button [ 0 ] . desc ) ;
if ( rc < 0 ) {
printk ( KERN_INFO " mtx1: failed to request %d \n " ,
mtx1_gpio_button [ 0 ] . gpio ) ;
goto out ;
}
gpio_direction_input ( mtx1_gpio_button [ 0 ] . gpio ) ;
out :
2007-10-23 20:55:55 +04:00
return platform_add_devices ( mtx1_devs , ARRAY_SIZE ( mtx1_devs ) ) ;
}
arch_initcall ( mtx1_register_devices ) ;