2005-11-10 14:26:51 +00:00
/*
* linux / arch / arm / mach - omap2 / io . c
*
* OMAP2 I / O mapping code
*
* Copyright ( C ) 2005 Nokia Corporation
2009-05-28 14:16:04 -07:00
* Copyright ( C ) 2007 - 2009 Texas Instruments
2008-10-06 15:49:36 +03:00
*
* Author :
* Juha Yrjola < juha . yrjola @ nokia . com >
* Syed Khasim < x0khasim @ ti . com >
2005-11-10 14:26:51 +00:00
*
2009-05-28 14:16:04 -07:00
* Added OMAP4 support - Santosh Shilimkar < santosh . shilimkar @ ti . com >
*
2005-11-10 14:26:51 +00: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 12:10:45 +01:00
# include <linux/io.h>
2009-06-19 19:08:25 -06:00
# include <linux/clk.h>
2009-08-03 15:06:36 +03:00
# include <linux/omapfb.h>
2005-11-10 14:26:51 +00:00
2006-04-02 17:46:27 +01:00
# include <asm/tlb.h>
# include <asm/mach/map.h>
2009-10-20 09:40:47 -07:00
# include <plat/mux.h>
# include <plat/sram.h>
# include <plat/sdrc.h>
# include <plat/gpmc.h>
# include <plat/serial.h>
2009-08-07 12:01:55 +03:00
# include <plat/vram.h>
2008-10-06 15:49:36 +03:00
2010-01-26 20:13:12 -07:00
# include "clock2xxx.h"
OMAP3/4 clock: split into per-chip family files
clock34xx_data.c now contains data for the OMAP34xx family, the
OMAP36xx family, and the OMAP3517 family, so rename it to
clock3xxx_data.c. Rename clock34xx.c to clock3xxx.c, and move the
chip family-specific clock functions to clock34xx.c, clock36xx.c, or
clock3517.c, as appropriate. So now "clock3xxx.*" refers to the OMAP3
superset.
The main goal here is to prepare to compile chip family-specific clock
functions only for kernel builds that target that chip family. To get to
that point, we also need to add CONFIG_SOC_* options for those other
chip families; that will be done in future patches, planned for 2.6.35.
OMAP4 is also affected by this. It duplicated the OMAP3 non-CORE DPLL
clkops structure. The OMAP4 variant of this clkops structure has been
removed, and since there was nothing else currently in clock44xx.c, it
too has been removed -- it can always be added back later when there
is some content for it. (The OMAP4 clock autogeneration scripts have been
updated accordingly.)
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Benoît Cousson <b-cousson@ti.com>
Cc: Rajendra Nayak <rnayak@ti.com>
Cc: Ranjith Lohithakshan <ranjithl@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
2010-02-22 22:09:20 -07:00
# include "clock3xxx.h"
2010-01-26 20:13:12 -07:00
# include "clock44xx.h"
2005-11-10 14:26:51 +00:00
2009-10-20 09:40:47 -07:00
# include <plat/omap-pm.h>
# include <plat/powerdomain.h>
2008-08-19 11:08:40 +03:00
# include "powerdomains.h"
2005-11-10 14:26:51 +00:00
2009-10-20 09:40:47 -07:00
# include <plat/clockdomain.h>
2008-08-19 11:08:44 +03:00
# include "clockdomains.h"
2009-10-20 09:40:47 -07:00
# include <plat/omap_hwmod.h>
2009-09-03 20:14:05 +03:00
2005-11-10 14:26:51 +00:00
/*
* The machine specific code may provide the extra mapping besides the
* default mapping provided here .
*/
2008-10-09 17:51:41 +03:00
2010-02-12 12:26:47 -08:00
# ifdef CONFIG_ARCH_OMAP2
2008-10-09 17:51:41 +03:00
static struct map_desc omap24xx_io_desc [ ] __initdata = {
2005-11-10 14:26:51 +00:00
{
. virtual = L3_24XX_VIRT ,
. pfn = __phys_to_pfn ( L3_24XX_PHYS ) ,
. length = L3_24XX_SIZE ,
. type = MT_DEVICE
} ,
2008-02-20 15:30:06 -08:00
{
2008-10-09 17:51:41 +03:00
. virtual = L4_24XX_VIRT ,
. pfn = __phys_to_pfn ( L4_24XX_PHYS ) ,
. length = L4_24XX_SIZE ,
. type = MT_DEVICE
2008-02-20 15:30:06 -08:00
} ,
2008-10-09 17:51:41 +03:00
} ;
# ifdef CONFIG_ARCH_OMAP2420
static struct map_desc omap242x_io_desc [ ] __initdata = {
{
2010-01-08 15:23:05 -07:00
. virtual = DSP_MEM_2420_VIRT ,
. pfn = __phys_to_pfn ( DSP_MEM_2420_PHYS ) ,
. length = DSP_MEM_2420_SIZE ,
2008-10-09 17:51:41 +03:00
. type = MT_DEVICE
} ,
{
2010-01-08 15:23:05 -07:00
. virtual = DSP_IPI_2420_VIRT ,
. pfn = __phys_to_pfn ( DSP_IPI_2420_PHYS ) ,
. length = DSP_IPI_2420_SIZE ,
2008-10-09 17:51:41 +03:00
. type = MT_DEVICE
2008-02-20 15:30:06 -08:00
} ,
2008-10-09 17:51:41 +03:00
{
2010-01-08 15:23:05 -07:00
. virtual = DSP_MMU_2420_VIRT ,
. pfn = __phys_to_pfn ( DSP_MMU_2420_PHYS ) ,
. length = DSP_MMU_2420_SIZE ,
2008-10-09 17:51:41 +03:00
. type = MT_DEVICE
} ,
} ;
# endif
2006-12-06 17:14:05 -08:00
# ifdef CONFIG_ARCH_OMAP2430
2008-10-09 17:51:41 +03:00
static struct map_desc omap243x_io_desc [ ] __initdata = {
2006-12-06 17:14:05 -08: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 17:51:41 +03: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-06 17:14:05 -08:00
# endif
# endif
2008-10-09 17:51:41 +03:00
2010-02-12 12:26:48 -08:00
# ifdef CONFIG_ARCH_OMAP3
2008-10-09 17:51:41 +03:00
static struct map_desc omap34xx_io_desc [ ] __initdata = {
2005-11-10 14:26:51 +00:00
{
2008-10-09 17:51:41 +03:00
. virtual = L3_34XX_VIRT ,
. pfn = __phys_to_pfn ( L3_34XX_PHYS ) ,
. length = L3_34XX_SIZE ,
2006-12-07 13:58:10 -08:00
. type = MT_DEVICE
} ,
{
2008-10-09 17:51:41 +03:00
. virtual = L4_34XX_VIRT ,
. pfn = __phys_to_pfn ( L4_34XX_PHYS ) ,
. length = L4_34XX_SIZE ,
2006-12-07 13:58:10 -08:00
. type = MT_DEVICE
} ,
2008-10-09 17:51:41 +03:00
{
. virtual = OMAP34XX_GPMC_VIRT ,
. pfn = __phys_to_pfn ( OMAP34XX_GPMC_PHYS ) ,
. length = OMAP34XX_GPMC_SIZE ,
2005-11-10 14:26:51 +00:00
. type = MT_DEVICE
2008-10-09 17:51:41 +03: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 14:26:51 +00:00
. type = MT_DEVICE
2008-10-09 17:51:41 +03: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 14:26:51 +00:00
} ;
2008-10-09 17:51:41 +03:00
# endif
2009-05-28 14:16:04 -07: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 = OMAP44XX_GPMC_VIRT ,
. pfn = __phys_to_pfn ( OMAP44XX_GPMC_PHYS ) ,
. length = OMAP44XX_GPMC_SIZE ,
. type = MT_DEVICE ,
} ,
2009-10-19 17:25:57 -07:00
{
. virtual = OMAP44XX_EMIF1_VIRT ,
. pfn = __phys_to_pfn ( OMAP44XX_EMIF1_PHYS ) ,
. length = OMAP44XX_EMIF1_SIZE ,
. type = MT_DEVICE ,
} ,
{
. virtual = OMAP44XX_EMIF2_VIRT ,
. pfn = __phys_to_pfn ( OMAP44XX_EMIF2_PHYS ) ,
. length = OMAP44XX_EMIF2_SIZE ,
. type = MT_DEVICE ,
} ,
{
. virtual = OMAP44XX_DMM_VIRT ,
. pfn = __phys_to_pfn ( OMAP44XX_DMM_PHYS ) ,
. length = OMAP44XX_DMM_SIZE ,
. type = MT_DEVICE ,
} ,
2009-05-28 14:16:04 -07:00
{
. 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 14:26:51 +00:00
2010-02-12 12:26:47 -08:00
static void __init _omap2_map_common_io ( void )
{
/* 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 ( ) ;
omap2_check_revision ( ) ;
omap_sram_init ( ) ;
omapfb_reserve_sdram ( ) ;
omap_vram_reserve_sdram ( ) ;
}
# ifdef CONFIG_ARCH_OMAP2420
2010-03-03 16:24:53 +00:00
void __init omap242x_map_common_io ( void )
2005-11-10 14:26:51 +00:00
{
2008-10-09 17:51:41 +03:00
iotable_init ( omap24xx_io_desc , ARRAY_SIZE ( omap24xx_io_desc ) ) ;
iotable_init ( omap242x_io_desc , ARRAY_SIZE ( omap242x_io_desc ) ) ;
2010-02-12 12:26:47 -08:00
_omap2_map_common_io ( ) ;
}
2008-10-09 17:51:41 +03:00
# endif
2010-02-12 12:26:47 -08:00
# ifdef CONFIG_ARCH_OMAP2430
2010-03-03 16:24:53 +00:00
void __init omap243x_map_common_io ( void )
2010-02-12 12:26:47 -08:00
{
2008-10-09 17:51:41 +03:00
iotable_init ( omap24xx_io_desc , ARRAY_SIZE ( omap24xx_io_desc ) ) ;
iotable_init ( omap243x_io_desc , ARRAY_SIZE ( omap243x_io_desc ) ) ;
2010-02-12 12:26:47 -08:00
_omap2_map_common_io ( ) ;
}
2008-10-09 17:51:41 +03:00
# endif
2010-02-12 12:26:48 -08:00
# ifdef CONFIG_ARCH_OMAP3
2010-03-03 16:24:53 +00:00
void __init omap34xx_map_common_io ( void )
2010-02-12 12:26:47 -08:00
{
2008-10-09 17:51:41 +03:00
iotable_init ( omap34xx_io_desc , ARRAY_SIZE ( omap34xx_io_desc ) ) ;
2010-02-12 12:26:47 -08:00
_omap2_map_common_io ( ) ;
}
2008-10-09 17:51:41 +03:00
# endif
2006-04-02 17:46:27 +01:00
2010-02-12 12:26:47 -08:00
# ifdef CONFIG_ARCH_OMAP4
2010-03-03 16:24:53 +00:00
void __init omap44xx_map_common_io ( void )
2010-02-12 12:26:47 -08:00
{
2009-05-28 14:16:04 -07:00
iotable_init ( omap44xx_io_desc , ARRAY_SIZE ( omap44xx_io_desc ) ) ;
2010-02-12 12:26:47 -08:00
_omap2_map_common_io ( ) ;
2006-04-02 17:46:27 +01:00
}
2010-02-12 12:26:47 -08:00
# endif
2006-04-02 17:46:27 +01:00
2009-06-19 19:08:25 -06: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-24 19:43:25 -06:00
void __init omap2_init_common_hw ( struct omap_sdrc_params * sdrc_cs0 ,
struct omap_sdrc_params * sdrc_cs1 )
2006-04-02 17:46:27 +01:00
{
2010-01-26 20:12:53 -07:00
pwrdm_init ( powerdomains_omap ) ;
2010-01-26 20:12:59 -07:00
clkdm_init ( clockdomains_omap , clkdm_autodeps ) ;
2010-02-22 22:09:32 -07:00
if ( cpu_is_omap242x ( ) )
omap2420_hwmod_init ( ) ;
else if ( cpu_is_omap243x ( ) )
omap2430_hwmod_init ( ) ;
else if ( cpu_is_omap34xx ( ) )
omap3xxx_hwmod_init ( ) ;
2009-09-24 16:23:07 -07:00
omap2_mux_init ( ) ;
2010-02-22 22:09:32 -07:00
/* The OPP tables have to be registered before a clk init */
2009-09-03 20:14:01 +03:00
omap_pm_if_early_init ( mpu_opps , dsp_opps , l3_opps ) ;
2010-01-26 20:13:12 -07:00
OMAP2 clock: split OMAP2420, OMAP2430 clock data into their own files
In preparation for multi-OMAP2 kernels, split
mach-omap2/clock2xxx_data.c into mach-omap2/clock2420_data.c and
mach-omap2/clock2430_data.c. 2430 uses a different device space
physical memory layout than past or future OMAPs, and we use a
different virtual memory layout as well, which causes trouble for
architecture-level code/data that tries to support both. We tried
using offsets from the virtual base last year, but those patches never
made it upstream; so after some discussion with Tony about the best
all-around approach, we'll just grit our teeth and duplicate the
structures. The maintenance advantages of a single kernel config that
can compile and boot on OMAP2, 3, and 4 platforms are simply too
compelling.
This approach does have some nice benefits beyond multi-OMAP 2 kernel
support. The runtime size of OMAP2420-specific and OMAP2430-specific
kernels is smaller, since unused clocks for the other OMAP2 chip will
no longer be compiled in. (At some point we will mark the clock data
__initdata and allocate it during registration, which will eliminate
the runtime memory advantage.) It also makes the clock trees slightly
easier to read, since 2420-specific and 2430-specific clocks are no
longer mixed together.
This patch also splits 2430-specific clock code into its own file,
mach-omap2/clock2430.c, which is only compiled in for 2430 builds -
mostly for organizational clarity.
While here, fix a bug in the OMAP2430 clock tree: "emul_ck" was
incorrectly marked as being 2420-only, when actually it is present on
both OMAP2420 and OMAP2430.
Thanks to Tony for some good discussions about how to approach this
problem.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Richard Woodruff <r-woodruff2@ti.com>
2010-02-22 22:09:22 -07:00
if ( cpu_is_omap2420 ( ) )
omap2420_clk_init ( ) ;
else if ( cpu_is_omap2430 ( ) )
omap2430_clk_init ( ) ;
2010-01-26 20:13:12 -07:00
else if ( cpu_is_omap34xx ( ) )
omap3xxx_clk_init ( ) ;
else if ( cpu_is_omap44xx ( ) )
omap4xxx_clk_init ( ) ;
else
pr_err ( " Could not init clock framework - unknown CPU \n " ) ;
2009-09-03 20:14:02 +03:00
omap_serial_early_init ( ) ;
2010-03-10 17:16:31 +00:00
if ( cpu_is_omap24xx ( ) | | cpu_is_omap34xx ( ) ) /* FIXME: OMAP4 */
omap_hwmod_late_init ( ) ;
2009-09-03 20:14:01 +03:00
omap_pm_if_init ( ) ;
2010-03-10 17:16:31 +00:00
if ( cpu_is_omap24xx ( ) | | cpu_is_omap34xx ( ) ) {
omap2_sdrc_init ( sdrc_cs0 , sdrc_cs1 ) ;
_omap2_init_reprogram_sdrc ( ) ;
}
2006-06-26 16:16:16 -07:00
gpmc_init ( ) ;
2005-11-10 14:26:51 +00:00
}