2005-04-17 02:20:36 +04:00
/*
* BRIEF MODULE DESCRIPTION
2008-04-30 23:18:41 +04:00
* Simple Au1xx0 clocks routines .
2005-04-17 02:20:36 +04:00
*
2008-04-30 23:18:41 +04:00
* Copyright 2001 , 2008 MontaVista Software Inc .
* Author : MontaVista Software , Inc . < source @ mvista . com >
2005-04-17 02:20:36 +04:00
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation ; either version 2 of the License , or ( at your
* option ) any later version .
*
* THIS SOFTWARE IS PROVIDED ` ` AS IS ' ' AND ANY EXPRESS OR IMPLIED
* WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF
* USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*
* 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 . ,
* 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <linux/module.h>
2008-12-21 11:26:24 +03:00
# include <linux/spinlock.h>
# include <asm/time.h>
2005-04-17 02:20:36 +04:00
# include <asm/mach-au1x00/au1000.h>
2008-12-21 11:26:24 +03:00
/*
* I haven ' t found anyone that doesn ' t use a 12 MHz source clock ,
* but just in case . . . . .
*/
# define AU1000_SRC_CLK 12000000
2008-04-30 23:18:41 +04:00
static unsigned int au1x00_clock ; /* Hz */
2005-04-17 02:20:36 +04:00
static unsigned long uart_baud_base ;
/*
* Set the au1000_clock
*/
void set_au1x00_speed ( unsigned int new_freq )
{
au1x00_clock = new_freq ;
}
unsigned int get_au1x00_speed ( void )
{
return au1x00_clock ;
}
2008-05-07 15:42:55 +04:00
EXPORT_SYMBOL ( get_au1x00_speed ) ;
2005-04-17 02:20:36 +04:00
/*
* The UART baud base is not known at compile time . . . if
* we want to be able to use the same code on different
* speed CPUs .
*/
unsigned long get_au1x00_uart_baud_base ( void )
{
return uart_baud_base ;
}
void set_au1x00_uart_baud_base ( unsigned long new_baud_base )
{
uart_baud_base = new_baud_base ;
}
2008-12-21 11:26:24 +03:00
/*
* We read the real processor speed from the PLL . This is important
* because it is more accurate than computing it from the 32 KHz
* counter , if it exists . If we don ' t have an accurate processor
* speed , all of the peripherals that derive their clocks based on
* this advertised speed will introduce error and sometimes not work
2011-03-31 05:57:33 +04:00
* properly . This function is further convoluted to still allow configurations
2008-12-21 11:26:24 +03:00
* to do that in case they have really , really old silicon with a
* write - only PLL register . - - Dan
*/
unsigned long au1xxx_calc_clock ( void )
{
unsigned long cpu_speed ;
/*
* On early Au1000 , sys_cpupll was write - only . Since these
* silicon versions of Au1000 are not sold by AMD , we don ' t bend
* over backwards trying to determine the frequency .
*/
if ( au1xxx_cpu_has_pll_wo ( ) )
cpu_speed = 396000000 ;
else
cpu_speed = ( au_readl ( SYS_CPUPLL ) & 0x0000003f ) * AU1000_SRC_CLK ;
/* On Alchemy CPU:counter ratio is 1:1 */
mips_hpt_frequency = cpu_speed ;
/* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */
set_au1x00_uart_baud_base ( cpu_speed / ( 2 * ( ( int ) ( au_readl ( SYS_POWERCTRL )
& 0x03 ) + 2 ) * 16 ) ) ;
set_au1x00_speed ( cpu_speed ) ;
return cpu_speed ;
}