2005-04-17 02:20:36 +04:00
/*
* Carsten Langgaard , carstenl @ mips . com
* Copyright ( C ) 2000 MIPS Technologies , Inc . All rights reserved .
2008-04-01 02:03:24 +04:00
* Copyright ( C ) 2008 Dmitri Vorobiev
2005-04-17 02:20:36 +04:00
*
* This program is free software ; you can distribute it and / or modify it
* under the terms of the GNU General Public License ( Version 2 ) as
* published by the Free Software Foundation .
*
* This program is distributed in the hope 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 .
*/
2008-01-24 19:52:49 +03:00
# include <linux/cpu.h>
2005-04-17 02:20:36 +04:00
# include <linux/init.h>
# include <linux/sched.h>
# include <linux/ioport.h>
2008-01-24 19:52:49 +03:00
# include <linux/irq.h>
2005-04-17 02:20:36 +04:00
# include <linux/pci.h>
2006-07-10 15:44:13 +04:00
# include <linux/screen_info.h>
2008-01-24 19:52:49 +03:00
# include <linux/time.h>
2005-04-17 02:20:36 +04:00
2013-03-25 23:47:05 +04:00
# include <asm/fw/fw.h>
2005-04-17 02:20:36 +04:00
# include <asm/mips-boards/generic.h>
# include <asm/mips-boards/malta.h>
# include <asm/mips-boards/maltaint.h>
# include <asm/dma.h>
# include <asm/traps.h>
2013-03-25 22:47:29 +04:00
# include <asm/gcmpregs.h>
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_VT
# include <linux/console.h>
# endif
2008-04-28 20:14:26 +04:00
extern void malta_be_init ( void ) ;
extern int malta_be_handler ( struct pt_regs * regs , int is_fixup ) ;
2008-04-01 02:03:24 +04:00
static struct resource standard_io_resources [ ] = {
2008-01-24 19:52:41 +03:00
{
. name = " dma1 " ,
. start = 0x00 ,
. end = 0x1f ,
. flags = IORESOURCE_BUSY
} ,
{
. name = " timer " ,
. start = 0x40 ,
. end = 0x5f ,
. flags = IORESOURCE_BUSY
} ,
{
. name = " keyboard " ,
. start = 0x60 ,
. end = 0x6f ,
. flags = IORESOURCE_BUSY
} ,
{
. name = " dma page reg " ,
. start = 0x80 ,
. end = 0x8f ,
. flags = IORESOURCE_BUSY
} ,
{
. name = " dma2 " ,
. start = 0xc0 ,
. end = 0xdf ,
. flags = IORESOURCE_BUSY
} ,
2005-04-17 02:20:36 +04:00
} ;
const char * get_system_type ( void )
{
return " MIPS Malta " ;
}
2007-05-16 19:54:08 +04:00
# if defined(CONFIG_MIPS_MT_SMTC)
2013-01-22 15:59:30 +04:00
const char display_string [ ] = " SMTC LINUX ON MALTA " ;
2007-05-16 19:54:08 +04:00
# else
2013-01-22 15:59:30 +04:00
const char display_string [ ] = " LINUX ON MALTA " ;
2007-05-16 19:54:08 +04:00
# endif /* CONFIG_MIPS_MT_SMTC */
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_BLK_DEV_FD
2008-01-24 19:52:55 +03:00
static void __init fd_activate ( void )
2005-04-17 02:20:36 +04:00
{
/*
* Activate Floppy Controller in the SMSC FDC37M817 Super I / O
* Controller .
* Done by YAMON 2.00 onwards
*/
/* Entering config state. */
SMSC_WRITE ( SMSC_CONFIG_ENTER , SMSC_CONFIG_REG ) ;
/* Activate floppy controller. */
SMSC_WRITE ( SMSC_CONFIG_DEVNUM , SMSC_CONFIG_REG ) ;
SMSC_WRITE ( SMSC_CONFIG_DEVNUM_FLOPPY , SMSC_DATA_REG ) ;
SMSC_WRITE ( SMSC_CONFIG_ACTIVATE , SMSC_CONFIG_REG ) ;
SMSC_WRITE ( SMSC_CONFIG_ACTIVATE_ENABLE , SMSC_DATA_REG ) ;
/* Exit config state. */
SMSC_WRITE ( SMSC_CONFIG_EXIT , SMSC_CONFIG_REG ) ;
}
# endif
2013-03-25 22:47:29 +04:00
static int __init plat_enable_iocoherency ( void )
{
int supported = 0 ;
if ( mips_revision_sconid = = MIPS_REVISION_SCON_BONITO ) {
if ( BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES ) {
BONITO_PCICACHECTRL | = BONITO_PCICACHECTRL_CPUCOH_EN ;
pr_info ( " Enabled Bonito CPU coherency \n " ) ;
supported = 1 ;
}
if ( strstr ( fw_getcmdline ( ) , " iobcuncached " ) ) {
BONITO_PCICACHECTRL & = ~ BONITO_PCICACHECTRL_IOBCCOH_EN ;
BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
~ ( BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
BONITO_PCIMEMBASECFG_MEMBASE1_CACHED ) ;
pr_info ( " Disabled Bonito IOBC coherency \n " ) ;
} else {
BONITO_PCICACHECTRL | = BONITO_PCICACHECTRL_IOBCCOH_EN ;
BONITO_PCIMEMBASECFG | =
( BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
BONITO_PCIMEMBASECFG_MEMBASE1_CACHED ) ;
pr_info ( " Enabled Bonito IOBC coherency \n " ) ;
}
} else if ( gcmp_niocu ( ) ! = 0 ) {
/* Nothing special needs to be done to enable coherency */
pr_info ( " CMP IOCU detected \n " ) ;
if ( ( * ( unsigned int * ) 0xbf403000 & 0x81 ) ! = 0x81 ) {
pr_crit ( " IOCU OPERATION DISABLED BY SWITCH - DEFAULTING TO SW IO COHERENCY \n " ) ;
return 0 ;
}
supported = 1 ;
}
hw_coherentio = supported ;
return supported ;
}
static void __init plat_setup_iocoherency ( void )
{
# ifdef CONFIG_DMA_NONCOHERENT
/*
* Kernel has been configured with software coherency
* but we might choose to turn it off and use hardware
* coherency instead .
*/
if ( plat_enable_iocoherency ( ) ) {
if ( coherentio = = 0 )
pr_info ( " Hardware DMA cache coherency disabled \n " ) ;
else
pr_info ( " Hardware DMA cache coherency enabled \n " ) ;
} else {
if ( coherentio = = 1 )
pr_info ( " Hardware DMA cache coherency unsupported, but enabled from command line! \n " ) ;
else
pr_info ( " Software DMA cache coherency enabled \n " ) ;
}
# else
if ( ! plat_enable_iocoherency ( ) )
panic ( " Hardware DMA cache coherency not supported! " ) ;
# endif
}
2008-01-24 19:52:43 +03:00
# ifdef CONFIG_BLK_DEV_IDE
static void __init pci_clock_check ( void )
{
unsigned int __iomem * jmpr_p =
( unsigned int * ) ioremap ( MALTA_JMPRS_REG , sizeof ( unsigned int ) ) ;
int jmpr = ( __raw_readl ( jmpr_p ) > > 2 ) & 0x07 ;
2012-07-19 11:11:16 +04:00
static const int pciclocks [ ] __initconst = {
2008-01-24 19:52:43 +03:00
33 , 20 , 25 , 30 , 12 , 16 , 37 , 10
} ;
int pciclock = pciclocks [ jmpr ] ;
2013-03-25 23:47:05 +04:00
char * argptr = fw_getcmdline ( ) ;
2008-01-24 19:52:43 +03:00
if ( pciclock ! = 33 & & ! strstr ( argptr , " idebus= " ) ) {
2013-03-26 00:05:40 +04:00
pr_warn ( " WARNING: PCI clock is %dMHz, setting idebus \n " ,
pciclock ) ;
2008-01-24 19:52:43 +03:00
argptr + = strlen ( argptr ) ;
sprintf ( argptr , " idebus=%d " , pciclock ) ;
if ( pciclock < 20 | | pciclock > 66 )
2013-03-26 00:05:40 +04:00
pr_warn ( " WARNING: IDE timing calculations will be incorrect \n " ) ;
2008-01-24 19:52:43 +03:00
}
}
# endif
2008-01-24 19:52:44 +03:00
# if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
static void __init screen_info_setup ( void )
{
screen_info = ( struct screen_info ) {
. orig_x = 0 ,
. orig_y = 25 ,
. ext_mem_k = 0 ,
. orig_video_page = 0 ,
. orig_video_mode = 0 ,
. orig_video_cols = 80 ,
. unused2 = 0 ,
. orig_video_ega_bx = 0 ,
. unused3 = 0 ,
. orig_video_lines = 25 ,
. orig_video_isVGA = VIDEO_TYPE_VGAC ,
. orig_video_points = 16
} ;
}
# endif
2008-01-24 19:52:56 +03:00
static void __init bonito_quirks_setup ( void )
{
char * argptr ;
2013-03-25 23:47:05 +04:00
argptr = fw_getcmdline ( ) ;
2008-01-24 19:52:56 +03:00
if ( strstr ( argptr , " debug " ) ) {
BONITO_BONGENCFG | = BONITO_BONGENCFG_DEBUGMODE ;
2013-03-26 00:05:40 +04:00
pr_info ( " Enabled Bonito debug mode \n " ) ;
2008-01-24 19:52:56 +03:00
} else
BONITO_BONGENCFG & = ~ BONITO_BONGENCFG_DEBUGMODE ;
# ifdef CONFIG_DMA_COHERENT
if ( BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES ) {
BONITO_PCICACHECTRL | = BONITO_PCICACHECTRL_CPUCOH_EN ;
2013-03-26 00:05:40 +04:00
pr_info ( " Enabled Bonito CPU coherency \n " ) ;
2008-01-24 19:52:56 +03:00
2013-03-25 23:47:05 +04:00
argptr = fw_getcmdline ( ) ;
2008-01-24 19:52:56 +03:00
if ( strstr ( argptr , " iobcuncached " ) ) {
BONITO_PCICACHECTRL & = ~ BONITO_PCICACHECTRL_IOBCCOH_EN ;
BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
~ ( BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
BONITO_PCIMEMBASECFG_MEMBASE1_CACHED ) ;
2013-03-26 00:05:40 +04:00
pr_info ( " Disabled Bonito IOBC coherency \n " ) ;
2008-01-24 19:52:56 +03:00
} else {
BONITO_PCICACHECTRL | = BONITO_PCICACHECTRL_IOBCCOH_EN ;
BONITO_PCIMEMBASECFG | =
( BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
BONITO_PCIMEMBASECFG_MEMBASE1_CACHED ) ;
2013-03-26 00:05:40 +04:00
pr_info ( " Enabled Bonito IOBC coherency \n " ) ;
2008-01-24 19:52:56 +03:00
}
} else
panic ( " Hardware DMA cache coherency not supported " ) ;
# endif
}
2006-06-18 04:32:22 +04:00
void __init plat_mem_setup ( void )
2005-04-17 02:20:36 +04:00
{
unsigned int i ;
2005-06-21 17:56:30 +04:00
mips_pcibios_init ( ) ;
2005-04-17 02:20:36 +04:00
/* Request I/O space for devices used on the Malta board. */
for ( i = 0 ; i < ARRAY_SIZE ( standard_io_resources ) ; i + + )
request_resource ( & ioport_resource , standard_io_resources + i ) ;
/*
* Enable DMA channel 4 ( cascade channel ) in the PIIX4 south bridge .
*/
enable_dma ( 4 ) ;
# ifdef CONFIG_DMA_COHERENT
2008-01-24 19:52:56 +03:00
if ( mips_revision_sconid ! = MIPS_REVISION_SCON_BONITO )
2005-04-17 02:20:36 +04:00
panic ( " Hardware DMA cache coherency not supported " ) ;
# endif
2008-01-24 19:52:56 +03:00
if ( mips_revision_sconid = = MIPS_REVISION_SCON_BONITO )
bonito_quirks_setup ( ) ;
2013-03-25 22:47:29 +04:00
plat_setup_iocoherency ( ) ;
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_BLK_DEV_IDE
2008-01-24 19:52:43 +03:00
pci_clock_check ( ) ;
2005-04-17 02:20:36 +04:00
# endif
2008-01-24 19:52:56 +03:00
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_BLK_DEV_FD
2007-10-12 02:46:15 +04:00
fd_activate ( ) ;
2005-04-17 02:20:36 +04:00
# endif
2008-01-24 19:52:56 +03:00
2008-01-24 19:52:44 +03:00
# if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
screen_info_setup ( ) ;
2005-04-17 02:20:36 +04:00
# endif
2008-04-28 20:14:26 +04:00
board_be_init = malta_be_init ;
board_be_handler = malta_be_handler ;
2005-04-17 02:20:36 +04:00
}