2005-11-10 17:26:51 +03:00
/*
* linux / arch / arm / mach - omap2 / io . c
*
* OMAP2 I / O mapping code
*
* Copyright ( C ) 2005 Nokia Corporation
2009-05-29 01:16:04 +04:00
* Copyright ( C ) 2007 - 2009 Texas Instruments
2008-10-06 16:49:36 +04:00
*
* Author :
* Juha Yrjola < juha . yrjola @ nokia . com >
* Syed Khasim < x0khasim @ ti . com >
2005-11-10 17:26:51 +03:00
*
2009-05-29 01:16:04 +04:00
* Added OMAP4 support - Santosh Shilimkar < santosh . shilimkar @ ti . com >
*
2005-11-10 17:26:51 +03:00
* 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/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
2008-09-06 15:10:45 +04:00
# include <linux/io.h>
2009-06-20 05:08:25 +04:00
# include <linux/clk.h>
2005-11-10 17:26:51 +03:00
2006-04-02 20:46:27 +04:00
# include <asm/tlb.h>
# include <asm/mach/map.h>
2008-08-05 19:14:15 +04:00
# include <mach/mux.h>
# include <mach/omapfb.h>
2008-10-06 16:49:36 +04:00
# include <mach/sram.h>
2009-01-28 22:27:31 +03:00
# include <mach/sdrc.h>
# include <mach/gpmc.h>
2009-09-03 21:14:02 +04:00
# include <mach/serial.h>
2008-10-06 16:49:36 +04:00
2009-05-29 01:16:04 +04:00
# ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdev is ready */
2008-10-06 16:49:36 +04:00
# include "clock.h"
2005-11-10 17:26:51 +03:00
2009-09-03 21:14:01 +04:00
# include <mach/omap-pm.h>
2008-08-19 12:08:40 +04:00
# include <mach/powerdomain.h>
# include "powerdomains.h"
2005-11-10 17:26:51 +03:00
2008-08-19 12:08:44 +04:00
# include <mach/clockdomain.h>
# include "clockdomains.h"
2009-05-29 01:16:04 +04:00
# endif
2005-11-10 17:26:51 +03:00
/*
* The machine specific code may provide the extra mapping besides the
* default mapping provided here .
*/
2008-10-09 18:51:41 +04:00
# ifdef CONFIG_ARCH_OMAP24XX
static struct map_desc omap24xx_io_desc [ ] __initdata = {
2005-11-10 17:26:51 +03:00
{
. virtual = L3_24XX_VIRT ,
. pfn = __phys_to_pfn ( L3_24XX_PHYS ) ,
. length = L3_24XX_SIZE ,
. type = MT_DEVICE
} ,
2008-02-21 02:30:06 +03:00
{
2008-10-09 18:51:41 +04:00
. virtual = L4_24XX_VIRT ,
. pfn = __phys_to_pfn ( L4_24XX_PHYS ) ,
. length = L4_24XX_SIZE ,
. type = MT_DEVICE
2008-02-21 02:30:06 +03:00
} ,
2008-10-09 18:51:41 +04:00
} ;
# ifdef CONFIG_ARCH_OMAP2420
static struct map_desc omap242x_io_desc [ ] __initdata = {
{
. virtual = DSP_MEM_24XX_VIRT ,
. pfn = __phys_to_pfn ( DSP_MEM_24XX_PHYS ) ,
. length = DSP_MEM_24XX_SIZE ,
. type = MT_DEVICE
} ,
{
. virtual = DSP_IPI_24XX_VIRT ,
. pfn = __phys_to_pfn ( DSP_IPI_24XX_PHYS ) ,
. length = DSP_IPI_24XX_SIZE ,
. type = MT_DEVICE
2008-02-21 02:30:06 +03:00
} ,
2008-10-09 18:51:41 +04:00
{
. virtual = DSP_MMU_24XX_VIRT ,
. pfn = __phys_to_pfn ( DSP_MMU_24XX_PHYS ) ,
. length = DSP_MMU_24XX_SIZE ,
. type = MT_DEVICE
} ,
} ;
# endif
2006-12-07 04:14:05 +03:00
# ifdef CONFIG_ARCH_OMAP2430
2008-10-09 18:51:41 +04:00
static struct map_desc omap243x_io_desc [ ] __initdata = {
2006-12-07 04:14:05 +03:00
{
. virtual = L4_WK_243X_VIRT ,
. pfn = __phys_to_pfn ( L4_WK_243X_PHYS ) ,
. length = L4_WK_243X_SIZE ,
. type = MT_DEVICE
} ,
{
. virtual = OMAP243X_GPMC_VIRT ,
. pfn = __phys_to_pfn ( OMAP243X_GPMC_PHYS ) ,
. length = OMAP243X_GPMC_SIZE ,
. type = MT_DEVICE
} ,
2008-10-09 18:51:41 +04:00
{
. virtual = OMAP243X_SDRC_VIRT ,
. pfn = __phys_to_pfn ( OMAP243X_SDRC_PHYS ) ,
. length = OMAP243X_SDRC_SIZE ,
. type = MT_DEVICE
} ,
{
. virtual = OMAP243X_SMS_VIRT ,
. pfn = __phys_to_pfn ( OMAP243X_SMS_PHYS ) ,
. length = OMAP243X_SMS_SIZE ,
. type = MT_DEVICE
} ,
} ;
2006-12-07 04:14:05 +03:00
# endif
# endif
2008-10-09 18:51:41 +04:00
# ifdef CONFIG_ARCH_OMAP34XX
static struct map_desc omap34xx_io_desc [ ] __initdata = {
2005-11-10 17:26:51 +03:00
{
2008-10-09 18:51:41 +04:00
. virtual = L3_34XX_VIRT ,
. pfn = __phys_to_pfn ( L3_34XX_PHYS ) ,
. length = L3_34XX_SIZE ,
2006-12-08 00:58:10 +03:00
. type = MT_DEVICE
} ,
{
2008-10-09 18:51:41 +04:00
. virtual = L4_34XX_VIRT ,
. pfn = __phys_to_pfn ( L4_34XX_PHYS ) ,
. length = L4_34XX_SIZE ,
2006-12-08 00:58:10 +03:00
. type = MT_DEVICE
} ,
{
2008-10-09 18:51:41 +04:00
. virtual = L4_WK_34XX_VIRT ,
. pfn = __phys_to_pfn ( L4_WK_34XX_PHYS ) ,
. length = L4_WK_34XX_SIZE ,
. type = MT_DEVICE
} ,
{
. virtual = OMAP34XX_GPMC_VIRT ,
. pfn = __phys_to_pfn ( OMAP34XX_GPMC_PHYS ) ,
. length = OMAP34XX_GPMC_SIZE ,
2005-11-10 17:26:51 +03:00
. type = MT_DEVICE
2008-10-09 18:51:41 +04:00
} ,
{
. virtual = OMAP343X_SMS_VIRT ,
. pfn = __phys_to_pfn ( OMAP343X_SMS_PHYS ) ,
. length = OMAP343X_SMS_SIZE ,
. type = MT_DEVICE
} ,
{
. virtual = OMAP343X_SDRC_VIRT ,
. pfn = __phys_to_pfn ( OMAP343X_SDRC_PHYS ) ,
. length = OMAP343X_SDRC_SIZE ,
2005-11-10 17:26:51 +03:00
. type = MT_DEVICE
2008-10-09 18:51:41 +04:00
} ,
{
. virtual = L4_PER_34XX_VIRT ,
. pfn = __phys_to_pfn ( L4_PER_34XX_PHYS ) ,
. length = L4_PER_34XX_SIZE ,
. type = MT_DEVICE
} ,
{
. virtual = L4_EMU_34XX_VIRT ,
. pfn = __phys_to_pfn ( L4_EMU_34XX_PHYS ) ,
. length = L4_EMU_34XX_SIZE ,
. type = MT_DEVICE
} ,
2005-11-10 17:26:51 +03:00
} ;
2008-10-09 18:51:41 +04:00
# endif
2009-05-29 01:16:04 +04:00
# ifdef CONFIG_ARCH_OMAP4
static struct map_desc omap44xx_io_desc [ ] __initdata = {
{
. virtual = L3_44XX_VIRT ,
. pfn = __phys_to_pfn ( L3_44XX_PHYS ) ,
. length = L3_44XX_SIZE ,
. type = MT_DEVICE ,
} ,
{
. virtual = L4_44XX_VIRT ,
. pfn = __phys_to_pfn ( L4_44XX_PHYS ) ,
. length = L4_44XX_SIZE ,
. type = MT_DEVICE ,
} ,
{
. virtual = L4_WK_44XX_VIRT ,
. pfn = __phys_to_pfn ( L4_WK_44XX_PHYS ) ,
. length = L4_WK_44XX_SIZE ,
. type = MT_DEVICE ,
} ,
{
. virtual = OMAP44XX_GPMC_VIRT ,
. pfn = __phys_to_pfn ( OMAP44XX_GPMC_PHYS ) ,
. length = OMAP44XX_GPMC_SIZE ,
. type = MT_DEVICE ,
} ,
{
. virtual = L4_PER_44XX_VIRT ,
. pfn = __phys_to_pfn ( L4_PER_44XX_PHYS ) ,
. length = L4_PER_44XX_SIZE ,
. type = MT_DEVICE ,
} ,
{
. virtual = L4_EMU_44XX_VIRT ,
. pfn = __phys_to_pfn ( L4_EMU_44XX_PHYS ) ,
. length = L4_EMU_44XX_SIZE ,
. type = MT_DEVICE ,
} ,
} ;
# endif
2005-11-10 17:26:51 +03:00
2006-04-02 20:46:27 +04:00
void __init omap2_map_common_io ( void )
2005-11-10 17:26:51 +03:00
{
2008-10-09 18:51:41 +04:00
# if defined(CONFIG_ARCH_OMAP2420)
iotable_init ( omap24xx_io_desc , ARRAY_SIZE ( omap24xx_io_desc ) ) ;
iotable_init ( omap242x_io_desc , ARRAY_SIZE ( omap242x_io_desc ) ) ;
# endif
# if defined(CONFIG_ARCH_OMAP2430)
iotable_init ( omap24xx_io_desc , ARRAY_SIZE ( omap24xx_io_desc ) ) ;
iotable_init ( omap243x_io_desc , ARRAY_SIZE ( omap243x_io_desc ) ) ;
# endif
# if defined(CONFIG_ARCH_OMAP34XX)
iotable_init ( omap34xx_io_desc , ARRAY_SIZE ( omap34xx_io_desc ) ) ;
# endif
2006-04-02 20:46:27 +04:00
2009-05-29 01:16:04 +04:00
# if defined(CONFIG_ARCH_OMAP4)
iotable_init ( omap44xx_io_desc , ARRAY_SIZE ( omap44xx_io_desc ) ) ;
# endif
2006-04-02 20:46:27 +04:00
/* Normally devicemaps_init() would flush caches and tlb after
* mdesc - > map_io ( ) , but we must also do it here because of the CPU
* revision check below .
*/
local_flush_tlb_all ( ) ;
flush_cache_all ( ) ;
2005-11-10 17:26:51 +03:00
omap2_check_revision ( ) ;
omap_sram_init ( ) ;
2007-03-06 14:16:36 +03:00
omapfb_reserve_sdram ( ) ;
2006-04-02 20:46:27 +04:00
}
2009-06-20 05:08:25 +04:00
/*
* omap2_init_reprogram_sdrc - reprogram SDRC timing parameters
*
* Sets the CORE DPLL3 M2 divider to the same value that it ' s at
* currently . This has the effect of setting the SDRC SDRAM AC timing
* registers to the values currently defined by the kernel . Currently
* only defined for OMAP3 ; will return 0 if called on OMAP2 . Returns
* - EINVAL if the dpll3_m2_ck cannot be found , 0 if called on OMAP2 ,
* or passes along the return value of clk_set_rate ( ) .
*/
static int __init _omap2_init_reprogram_sdrc ( void )
{
struct clk * dpll3_m2_ck ;
int v = - EINVAL ;
long rate ;
if ( ! cpu_is_omap34xx ( ) )
return 0 ;
dpll3_m2_ck = clk_get ( NULL , " dpll3_m2_ck " ) ;
if ( ! dpll3_m2_ck )
return - EINVAL ;
rate = clk_get_rate ( dpll3_m2_ck ) ;
pr_info ( " Reprogramming SDRC clock to %ld Hz \n " , rate ) ;
v = clk_set_rate ( dpll3_m2_ck , rate ) ;
if ( v )
pr_err ( " dpll3_m2_clk rate change failed: %d \n " , v ) ;
clk_put ( dpll3_m2_ck ) ;
return v ;
}
2009-07-25 05:43:25 +04:00
void __init omap2_init_common_hw ( struct omap_sdrc_params * sdrc_cs0 ,
struct omap_sdrc_params * sdrc_cs1 )
2006-04-02 20:46:27 +04:00
{
2005-11-10 17:26:51 +03:00
omap2_mux_init ( ) ;
2009-05-29 01:16:04 +04:00
# ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */
2009-09-03 21:14:01 +04:00
/* The OPP tables have to be registered before a clk init */
omap_pm_if_early_init ( mpu_opps , dsp_opps , l3_opps ) ;
2008-08-19 12:08:40 +04:00
pwrdm_init ( powerdomains_omap ) ;
2008-08-19 12:08:44 +04:00
clkdm_init ( clockdomains_omap , clkdm_pwrdm_autodeps ) ;
2005-11-10 17:26:51 +03:00
omap2_clk_init ( ) ;
2009-09-03 21:14:02 +04:00
omap_serial_early_init ( ) ;
2009-09-03 21:14:01 +04:00
omap_pm_if_init ( ) ;
2009-07-25 05:43:25 +04:00
omap2_sdrc_init ( sdrc_cs0 , sdrc_cs1 ) ;
2009-06-20 05:08:25 +04:00
_omap2_init_reprogram_sdrc ( ) ;
2009-05-29 01:16:04 +04:00
# endif
2006-06-27 03:16:16 +04:00
gpmc_init ( ) ;
2005-11-10 17:26:51 +03:00
}