2010-01-27 06:13:09 +03:00
/*
* OMAP34xx M2 divider clock code
*
* Copyright ( C ) 2007 - 2008 Texas Instruments , Inc .
* Copyright ( C ) 2007 - 2010 Nokia Corporation
*
* Paul Walmsley
* Jouni Högander
*
* Parts of this code are based on code written by
* Richard Woodruff , Tony Lindgren , Tuukka Tikkanen , Karthik Dasu
*
* 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 .
*/
# undef DEBUG
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/clk.h>
# include <linux/io.h>
# include <plat/clock.h>
# include <plat/sram.h>
# include <plat/sdrc.h>
# include "clock.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-23 08:09:20 +03:00
# include "clock3xxx.h"
2010-01-27 06:13:09 +03:00
# include "clock34xx.h"
# include "sdrc.h"
# define CYCLES_PER_MHZ 1000000
/*
* CORE DPLL ( DPLL3 ) M2 divider rate programming functions
*
* These call into SRAM code to do the actual CM writes , since the SDRAM
* is clocked from DPLL3 .
*/
/**
* omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
* @ clk : struct clk * of DPLL to set
* @ rate : rounded target rate
*
* Program the DPLL M2 divider with the rounded target rate . Returns
* - EINVAL upon error , or 0 upon success .
*/
int omap3_core_dpll_m2_set_rate ( struct clk * clk , unsigned long rate )
{
u32 new_div = 0 ;
u32 unlock_dll = 0 ;
u32 c ;
unsigned long validrate , sdrcrate , _mpurate ;
struct omap_sdrc_params * sdrc_cs0 ;
struct omap_sdrc_params * sdrc_cs1 ;
int ret ;
if ( ! clk | | ! rate )
return - EINVAL ;
validrate = omap2_clksel_round_rate_div ( clk , rate , & new_div ) ;
if ( validrate ! = rate )
return - EINVAL ;
sdrcrate = sdrc_ick_p - > rate ;
if ( rate > clk - > rate )
sdrcrate < < = ( ( rate / clk - > rate ) > > 1 ) ;
else
sdrcrate > > = ( ( clk - > rate / rate ) > > 1 ) ;
ret = omap2_sdrc_get_params ( sdrcrate , & sdrc_cs0 , & sdrc_cs1 ) ;
if ( ret )
return - EINVAL ;
if ( sdrcrate < MIN_SDRC_DLL_LOCK_FREQ ) {
pr_debug ( " clock: will unlock SDRC DLL \n " ) ;
unlock_dll = 1 ;
}
/*
* XXX This only needs to be done when the CPU frequency changes
*/
_mpurate = arm_fck_p - > rate / CYCLES_PER_MHZ ;
c = ( _mpurate < < SDRC_MPURATE_SCALE ) > > SDRC_MPURATE_BASE_SHIFT ;
c + = 1 ; /* for safety */
c * = SDRC_MPURATE_LOOPS ;
c > > = SDRC_MPURATE_SCALE ;
if ( c = = 0 )
c = 1 ;
pr_debug ( " clock: changing CORE DPLL rate from %lu to %lu \n " , clk - > rate ,
validrate ) ;
pr_debug ( " clock: SDRC CS0 timing params used: "
" RFR %08x CTRLA %08x CTRLB %08x MR %08x \n " ,
sdrc_cs0 - > rfr_ctrl , sdrc_cs0 - > actim_ctrla ,
sdrc_cs0 - > actim_ctrlb , sdrc_cs0 - > mr ) ;
if ( sdrc_cs1 )
pr_debug ( " clock: SDRC CS1 timing params used: "
" RFR %08x CTRLA %08x CTRLB %08x MR %08x \n " ,
sdrc_cs1 - > rfr_ctrl , sdrc_cs1 - > actim_ctrla ,
sdrc_cs1 - > actim_ctrlb , sdrc_cs1 - > mr ) ;
if ( sdrc_cs1 )
omap3_configure_core_dpll (
new_div , unlock_dll , c , rate > clk - > rate ,
sdrc_cs0 - > rfr_ctrl , sdrc_cs0 - > actim_ctrla ,
sdrc_cs0 - > actim_ctrlb , sdrc_cs0 - > mr ,
sdrc_cs1 - > rfr_ctrl , sdrc_cs1 - > actim_ctrla ,
sdrc_cs1 - > actim_ctrlb , sdrc_cs1 - > mr ) ;
else
omap3_configure_core_dpll (
new_div , unlock_dll , c , rate > clk - > rate ,
sdrc_cs0 - > rfr_ctrl , sdrc_cs0 - > actim_ctrla ,
sdrc_cs0 - > actim_ctrlb , sdrc_cs0 - > mr ,
0 , 0 , 0 , 0 ) ;
return 0 ;
}