2009-08-06 16:12:43 +04:00
/*
* arch / arm / mach - dove / common . c
*
* Core functions for Marvell Dove 88 AP510 System On Chip
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed " as is " without any
* warranty of any kind , whether express or implied .
*/
# include <linux/kernel.h>
# include <linux/delay.h>
# include <linux/init.h>
# include <linux/platform_device.h>
# include <linux/pci.h>
2011-12-15 11:15:07 +04:00
# include <linux/clk-provider.h>
2009-08-06 16:12:43 +04:00
# include <linux/ata_platform.h>
# include <linux/gpio.h>
2012-08-15 21:07:33 +04:00
# include <linux/of.h>
# include <linux/of_platform.h>
2009-08-06 16:12:43 +04:00
# include <asm/page.h>
# include <asm/setup.h>
# include <asm/timex.h>
2009-11-24 20:33:52 +03:00
# include <asm/hardware/cache-tauros2.h>
2009-08-06 16:12:43 +04:00
# include <asm/mach/map.h>
# include <asm/mach/time.h>
# include <asm/mach/pci.h>
# include <mach/dove.h>
2012-08-15 21:07:31 +04:00
# include <mach/pm.h>
2009-08-06 16:12:43 +04:00
# include <mach/bridge-regs.h>
# include <asm/mach/arch.h>
# include <linux/irq.h>
# include <plat/time.h>
2012-08-24 17:21:54 +04:00
# include <linux/platform_data/usb-ehci-orion.h>
2011-05-15 15:32:41 +04:00
# include <plat/common.h>
2011-12-08 00:48:06 +04:00
# include <plat/addr-map.h>
2009-08-06 16:12:43 +04:00
# include "common.h"
/*****************************************************************************
* I / O Address Mapping
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct map_desc dove_io_desc [ ] __initdata = {
{
2012-09-11 16:27:18 +04:00
. virtual = ( unsigned long ) DOVE_SB_REGS_VIRT_BASE ,
2009-08-06 16:12:43 +04:00
. pfn = __phys_to_pfn ( DOVE_SB_REGS_PHYS_BASE ) ,
. length = DOVE_SB_REGS_SIZE ,
. type = MT_DEVICE ,
} , {
2012-09-11 16:27:18 +04:00
. virtual = ( unsigned long ) DOVE_NB_REGS_VIRT_BASE ,
2009-08-06 16:12:43 +04:00
. pfn = __phys_to_pfn ( DOVE_NB_REGS_PHYS_BASE ) ,
. length = DOVE_NB_REGS_SIZE ,
. type = MT_DEVICE ,
} ,
} ;
void __init dove_map_io ( void )
{
iotable_init ( dove_io_desc , ARRAY_SIZE ( dove_io_desc ) ) ;
}
2011-12-15 11:15:07 +04:00
/*****************************************************************************
* CLK tree
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-08-15 21:07:30 +04:00
static int dove_tclk ;
2012-08-15 21:07:31 +04:00
static DEFINE_SPINLOCK ( gating_lock ) ;
2011-12-15 11:15:07 +04:00
static struct clk * tclk ;
2012-08-15 21:07:31 +04:00
static struct clk __init * dove_register_gate ( const char * name ,
const char * parent , u8 bit_idx )
2011-12-15 11:15:07 +04:00
{
2012-08-15 21:07:31 +04:00
return clk_register_gate ( NULL , name , parent , 0 ,
( void __iomem * ) CLOCK_GATING_CONTROL ,
bit_idx , 0 , & gating_lock ) ;
}
2012-08-15 21:07:30 +04:00
static void __init dove_clk_init ( void )
2011-12-15 11:15:07 +04:00
{
2012-08-15 21:07:31 +04:00
struct clk * usb0 , * usb1 , * sata , * pex0 , * pex1 , * sdio0 , * sdio1 ;
struct clk * nand , * camera , * i2s0 , * i2s1 , * crypto , * ac97 , * pdma ;
struct clk * xor0 , * xor1 , * ge , * gephy ;
2012-04-06 19:17:26 +04:00
2011-12-15 11:15:07 +04:00
tclk = clk_register_fixed_rate ( NULL , " tclk " , NULL , CLK_IS_ROOT ,
2012-08-15 21:07:30 +04:00
dove_tclk ) ;
2012-04-06 19:17:26 +04:00
2012-08-15 21:07:31 +04:00
usb0 = dove_register_gate ( " usb0 " , " tclk " , CLOCK_GATING_BIT_USB0 ) ;
usb1 = dove_register_gate ( " usb1 " , " tclk " , CLOCK_GATING_BIT_USB1 ) ;
sata = dove_register_gate ( " sata " , " tclk " , CLOCK_GATING_BIT_SATA ) ;
pex0 = dove_register_gate ( " pex0 " , " tclk " , CLOCK_GATING_BIT_PCIE0 ) ;
pex1 = dove_register_gate ( " pex1 " , " tclk " , CLOCK_GATING_BIT_PCIE1 ) ;
sdio0 = dove_register_gate ( " sdio0 " , " tclk " , CLOCK_GATING_BIT_SDIO0 ) ;
sdio1 = dove_register_gate ( " sdio1 " , " tclk " , CLOCK_GATING_BIT_SDIO1 ) ;
nand = dove_register_gate ( " nand " , " tclk " , CLOCK_GATING_BIT_NAND ) ;
camera = dove_register_gate ( " camera " , " tclk " , CLOCK_GATING_BIT_CAMERA ) ;
i2s0 = dove_register_gate ( " i2s0 " , " tclk " , CLOCK_GATING_BIT_I2S0 ) ;
i2s1 = dove_register_gate ( " i2s1 " , " tclk " , CLOCK_GATING_BIT_I2S1 ) ;
crypto = dove_register_gate ( " crypto " , " tclk " , CLOCK_GATING_BIT_CRYPTO ) ;
ac97 = dove_register_gate ( " ac97 " , " tclk " , CLOCK_GATING_BIT_AC97 ) ;
pdma = dove_register_gate ( " pdma " , " tclk " , CLOCK_GATING_BIT_PDMA ) ;
xor0 = dove_register_gate ( " xor0 " , " tclk " , CLOCK_GATING_BIT_XOR0 ) ;
xor1 = dove_register_gate ( " xor1 " , " tclk " , CLOCK_GATING_BIT_XOR1 ) ;
gephy = dove_register_gate ( " gephy " , " tclk " , CLOCK_GATING_BIT_GIGA_PHY ) ;
ge = dove_register_gate ( " ge " , " gephy " , CLOCK_GATING_BIT_GBE ) ;
orion_clkdev_add ( NULL , " orion_spi.0 " , tclk ) ;
orion_clkdev_add ( NULL , " orion_spi.1 " , tclk ) ;
orion_clkdev_add ( NULL , " orion_wdt " , tclk ) ;
orion_clkdev_add ( NULL , " mv64xxx_i2c.0 " , tclk ) ;
orion_clkdev_add ( NULL , " orion-ehci.0 " , usb0 ) ;
orion_clkdev_add ( NULL , " orion-ehci.1 " , usb1 ) ;
orion_clkdev_add ( NULL , " mv643xx_eth.0 " , ge ) ;
orion_clkdev_add ( " 0 " , " sata_mv.0 " , sata ) ;
orion_clkdev_add ( " 0 " , " pcie " , pex0 ) ;
orion_clkdev_add ( " 1 " , " pcie " , pex1 ) ;
orion_clkdev_add ( NULL , " sdhci-dove.0 " , sdio0 ) ;
orion_clkdev_add ( NULL , " sdhci-dove.1 " , sdio1 ) ;
orion_clkdev_add ( NULL , " orion_nand " , nand ) ;
orion_clkdev_add ( NULL , " cafe1000-ccic.0 " , camera ) ;
orion_clkdev_add ( NULL , " kirkwood-i2s.0 " , i2s0 ) ;
orion_clkdev_add ( NULL , " kirkwood-i2s.1 " , i2s1 ) ;
orion_clkdev_add ( NULL , " mv_crypto " , crypto ) ;
orion_clkdev_add ( NULL , " dove-ac97 " , ac97 ) ;
orion_clkdev_add ( NULL , " dove-pdma " , pdma ) ;
orion_clkdev_add ( NULL , " mv_xor_shared.0 " , xor0 ) ;
orion_clkdev_add ( NULL , " mv_xor_shared.1 " , xor1 ) ;
2011-12-15 11:15:07 +04:00
}
2009-08-06 16:12:43 +04:00
/*****************************************************************************
* EHCI0
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_ehci0_init ( void )
{
2012-02-08 18:52:47 +04:00
orion_ehci_init ( DOVE_USB0_PHYS_BASE , IRQ_DOVE_USB0 , EHCI_PHY_NA ) ;
2009-08-06 16:12:43 +04:00
}
/*****************************************************************************
* EHCI1
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_ehci1_init ( void )
{
2011-12-08 00:48:08 +04:00
orion_ehci_1_init ( DOVE_USB1_PHYS_BASE , IRQ_DOVE_USB1 ) ;
2009-08-06 16:12:43 +04:00
}
/*****************************************************************************
* GE00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_ge00_init ( struct mv643xx_eth_platform_data * eth_data )
{
2012-06-12 17:59:45 +04:00
orion_ge00_init ( eth_data , DOVE_GE00_PHYS_BASE ,
2012-07-26 14:15:46 +04:00
IRQ_DOVE_GE00_SUM , IRQ_DOVE_GE00_ERR ,
1600 ) ;
2009-08-06 16:12:43 +04:00
}
/*****************************************************************************
* SoC RTC
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_rtc_init ( void )
{
2011-05-15 15:32:42 +04:00
orion_rtc_init ( DOVE_RTC_PHYS_BASE , IRQ_DOVE_RTC ) ;
2009-08-06 16:12:43 +04:00
}
/*****************************************************************************
* SATA
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_sata_init ( struct mv_sata_platform_data * sata_data )
{
2011-12-08 00:48:08 +04:00
orion_sata_init ( sata_data , DOVE_SATA_PHYS_BASE , IRQ_DOVE_SATA ) ;
2011-05-15 15:32:50 +04:00
2009-08-06 16:12:43 +04:00
}
/*****************************************************************************
* UART0
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_uart0_init ( void )
{
2011-05-15 15:32:41 +04:00
orion_uart0_init ( DOVE_UART0_VIRT_BASE , DOVE_UART0_PHYS_BASE ,
2011-12-24 06:06:34 +04:00
IRQ_DOVE_UART_0 , tclk ) ;
2009-08-06 16:12:43 +04:00
}
/*****************************************************************************
* UART1
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_uart1_init ( void )
{
2011-05-15 15:32:41 +04:00
orion_uart1_init ( DOVE_UART1_VIRT_BASE , DOVE_UART1_PHYS_BASE ,
2011-12-24 06:06:34 +04:00
IRQ_DOVE_UART_1 , tclk ) ;
2009-08-06 16:12:43 +04:00
}
/*****************************************************************************
* UART2
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_uart2_init ( void )
{
2011-05-15 15:32:41 +04:00
orion_uart2_init ( DOVE_UART2_VIRT_BASE , DOVE_UART2_PHYS_BASE ,
2011-12-24 06:06:34 +04:00
IRQ_DOVE_UART_2 , tclk ) ;
2009-08-06 16:12:43 +04:00
}
/*****************************************************************************
* UART3
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_uart3_init ( void )
{
2011-05-15 15:32:41 +04:00
orion_uart3_init ( DOVE_UART3_VIRT_BASE , DOVE_UART3_PHYS_BASE ,
2011-12-24 06:06:34 +04:00
IRQ_DOVE_UART_3 , tclk ) ;
2009-08-06 16:12:43 +04:00
}
/*****************************************************************************
2011-05-15 15:32:46 +04:00
* SPI
2009-08-06 16:12:43 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_spi0_init ( void )
{
2012-04-06 19:17:26 +04:00
orion_spi_init ( DOVE_SPI0_PHYS_BASE ) ;
2009-08-06 16:12:43 +04:00
}
void __init dove_spi1_init ( void )
{
2012-04-06 19:17:26 +04:00
orion_spi_1_init ( DOVE_SPI1_PHYS_BASE ) ;
2009-08-06 16:12:43 +04:00
}
/*****************************************************************************
* I2C
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_i2c_init ( void )
{
2011-05-15 15:32:45 +04:00
orion_i2c_init ( DOVE_I2C_PHYS_BASE , IRQ_DOVE_I2C , 10 ) ;
2009-08-06 16:12:43 +04:00
}
/*****************************************************************************
* Time handling
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-15 18:50:26 +04:00
void __init dove_init_early ( void )
{
orion_time_set_base ( TIMER_VIRT_BASE ) ;
}
2012-08-15 21:07:30 +04:00
static int __init dove_find_tclk ( void )
2009-08-06 16:12:43 +04:00
{
return 166666667 ;
}
2012-05-14 13:28:43 +04:00
static void __init dove_timer_init ( void )
2009-08-06 16:12:43 +04:00
{
2012-08-15 21:07:30 +04:00
dove_tclk = dove_find_tclk ( ) ;
2010-10-15 18:50:26 +04:00
orion_time_init ( BRIDGE_VIRT_BASE , BRIDGE_INT_TIMER1_CLR ,
2012-08-15 21:07:30 +04:00
IRQ_DOVE_BRIDGE , dove_tclk ) ;
2009-08-06 16:12:43 +04:00
}
struct sys_timer dove_timer = {
. init = dove_timer_init ,
} ;
2012-08-15 21:07:32 +04:00
/*****************************************************************************
* Cryptographic Engines and Security Accelerator ( CESA )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_crypto_init ( void )
{
orion_crypto_init ( DOVE_CRYPT_PHYS_BASE , DOVE_CESA_PHYS_BASE ,
DOVE_CESA_SIZE , IRQ_DOVE_CRYPTO ) ;
}
2009-08-06 16:12:43 +04:00
/*****************************************************************************
* XOR 0
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_xor0_init ( void )
{
2011-12-08 00:48:08 +04:00
orion_xor0_init ( DOVE_XOR0_PHYS_BASE , DOVE_XOR0_HIGH_PHYS_BASE ,
2011-05-15 15:32:48 +04:00
IRQ_DOVE_XOR_00 , IRQ_DOVE_XOR_01 ) ;
2009-08-06 16:12:43 +04:00
}
/*****************************************************************************
* XOR 1
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void __init dove_xor1_init ( void )
{
2011-05-15 15:32:48 +04:00
orion_xor1_init ( DOVE_XOR1_PHYS_BASE , DOVE_XOR1_HIGH_PHYS_BASE ,
IRQ_DOVE_XOR_10 , IRQ_DOVE_XOR_11 ) ;
2009-08-06 16:12:43 +04:00
}
2010-05-06 17:12:06 +04:00
/*****************************************************************************
* SDIO
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static u64 sdio_dmamask = DMA_BIT_MASK ( 32 ) ;
static struct resource dove_sdio0_resources [ ] = {
{
. start = DOVE_SDIO0_PHYS_BASE ,
. end = DOVE_SDIO0_PHYS_BASE + 0xff ,
. flags = IORESOURCE_MEM ,
} , {
. start = IRQ_DOVE_SDIO0 ,
. end = IRQ_DOVE_SDIO0 ,
. flags = IORESOURCE_IRQ ,
} ,
} ;
static struct platform_device dove_sdio0 = {
2010-10-28 23:23:53 +04:00
. name = " sdhci-dove " ,
2010-05-06 17:12:06 +04:00
. id = 0 ,
. dev = {
. dma_mask = & sdio_dmamask ,
. coherent_dma_mask = DMA_BIT_MASK ( 32 ) ,
} ,
. resource = dove_sdio0_resources ,
. num_resources = ARRAY_SIZE ( dove_sdio0_resources ) ,
} ;
void __init dove_sdio0_init ( void )
{
platform_device_register ( & dove_sdio0 ) ;
}
static struct resource dove_sdio1_resources [ ] = {
{
. start = DOVE_SDIO1_PHYS_BASE ,
. end = DOVE_SDIO1_PHYS_BASE + 0xff ,
. flags = IORESOURCE_MEM ,
} , {
. start = IRQ_DOVE_SDIO1 ,
. end = IRQ_DOVE_SDIO1 ,
. flags = IORESOURCE_IRQ ,
} ,
} ;
static struct platform_device dove_sdio1 = {
2010-10-28 23:23:53 +04:00
. name = " sdhci-dove " ,
2010-05-06 17:12:06 +04:00
. id = 1 ,
. dev = {
. dma_mask = & sdio_dmamask ,
. coherent_dma_mask = DMA_BIT_MASK ( 32 ) ,
} ,
. resource = dove_sdio1_resources ,
. num_resources = ARRAY_SIZE ( dove_sdio1_resources ) ,
} ;
void __init dove_sdio1_init ( void )
{
platform_device_register ( & dove_sdio1 ) ;
}
2009-08-06 16:12:43 +04:00
void __init dove_init ( void )
{
2012-08-15 21:07:30 +04:00
pr_info ( " Dove 88AP510 SoC, TCLK = %d MHz. \n " ,
( dove_tclk + 499999 ) / 1000000 ) ;
2009-08-06 16:12:43 +04:00
2009-11-24 20:33:52 +03:00
# ifdef CONFIG_CACHE_TAUROS2
2012-07-31 10:13:13 +04:00
tauros2_init ( 0 ) ;
2009-11-24 20:33:52 +03:00
# endif
2009-08-06 16:12:43 +04:00
dove_setup_cpu_mbus ( ) ;
2011-12-15 11:15:07 +04:00
/* Setup root of clk tree */
2012-08-15 21:07:30 +04:00
dove_clk_init ( ) ;
2011-12-15 11:15:07 +04:00
2009-08-06 16:12:43 +04:00
/* internal devices that every board has */
dove_rtc_init ( ) ;
dove_xor0_init ( ) ;
dove_xor1_init ( ) ;
}
2011-11-05 13:48:52 +04:00
void dove_restart ( char mode , const char * cmd )
{
/*
* Enable soft reset to assert RSTOUTn .
*/
writel ( SOFT_RESET_OUT_EN , RSTOUTn_MASK ) ;
/*
* Assert soft reset .
*/
writel ( SOFT_RESET , SYSTEM_SOFT_RESET ) ;
while ( 1 )
;
}
2012-08-15 21:07:33 +04:00
# if defined(CONFIG_MACH_DOVE_DT)
/*
* Auxdata required until real OF clock provider
*/
struct of_dev_auxdata dove_auxdata_lookup [ ] __initdata = {
OF_DEV_AUXDATA ( " marvell,orion-spi " , 0xf1010600 , " orion_spi.0 " , NULL ) ,
OF_DEV_AUXDATA ( " marvell,orion-spi " , 0xf1014600 , " orion_spi.1 " , NULL ) ,
OF_DEV_AUXDATA ( " marvell,orion-wdt " , 0xf1020300 , " orion_wdt " , NULL ) ,
OF_DEV_AUXDATA ( " marvell,mv64xxx-i2c " , 0xf1011000 , " mv64xxx_i2c.0 " ,
NULL ) ,
OF_DEV_AUXDATA ( " marvell,orion-sata " , 0xf10a0000 , " sata_mv.0 " , NULL ) ,
OF_DEV_AUXDATA ( " marvell,dove-sdhci " , 0xf1092000 , " sdhci-dove.0 " , NULL ) ,
OF_DEV_AUXDATA ( " marvell,dove-sdhci " , 0xf1090000 , " sdhci-dove.1 " , NULL ) ,
{ } ,
} ;
static struct mv643xx_eth_platform_data dove_dt_ge00_data = {
. phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT ,
} ;
static void __init dove_dt_init ( void )
{
pr_info ( " Dove 88AP510 SoC, TCLK = %d MHz. \n " ,
( dove_tclk + 499999 ) / 1000000 ) ;
# ifdef CONFIG_CACHE_TAUROS2
tauros2_init ( ) ;
# endif
dove_setup_cpu_mbus ( ) ;
/* Setup root of clk tree */
dove_clk_init ( ) ;
/* Internal devices not ported to DT yet */
dove_rtc_init ( ) ;
dove_xor0_init ( ) ;
dove_xor1_init ( ) ;
dove_ge00_init ( & dove_dt_ge00_data ) ;
dove_ehci0_init ( ) ;
dove_ehci1_init ( ) ;
dove_pcie_init ( 1 , 1 ) ;
dove_crypto_init ( ) ;
of_platform_populate ( NULL , of_default_bus_match_table ,
dove_auxdata_lookup , NULL ) ;
}
static const char * const dove_dt_board_compat [ ] = {
" marvell,dove " ,
NULL
} ;
DT_MACHINE_START ( DOVE_DT , " Marvell Dove (Flattened Device Tree) " )
. map_io = dove_map_io ,
. init_early = dove_init_early ,
. init_irq = orion_dt_init_irq ,
. timer = & dove_timer ,
. init_machine = dove_dt_init ,
. restart = dove_restart ,
. dt_compat = dove_dt_board_compat ,
MACHINE_END
# endif