2008-10-21 14:07:00 +01:00
/* linux/arch/arm/plat-s3c64xx/clock.c
*
* Copyright 2008 Openmoko , Inc .
* Copyright 2008 Simtec Electronics
* Ben Dooks < ben @ simtec . co . uk >
* http : //armlinux.simtec.co.uk/
*
* S3C64XX Base clock support
*
* 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/init.h>
# include <linux/module.h>
# include <linux/interrupt.h>
# include <linux/ioport.h>
# include <linux/io.h>
# include <mach/hardware.h>
# include <mach/map.h>
2010-01-26 10:45:40 +09:00
# include <mach/regs-sys.h>
# include <mach/regs-clock.h>
2010-01-26 13:41:30 +09:00
# include <mach/pll.h>
2008-10-21 14:07:00 +01:00
# include <plat/cpu.h>
# include <plat/devs.h>
# include <plat/clock.h>
2009-03-05 11:43:13 +08:00
struct clk clk_h2 = {
. name = " hclk2 " ,
. id = - 1 ,
. rate = 0 ,
} ;
2008-10-21 14:07:00 +01:00
struct clk clk_27m = {
. name = " clk_27m " ,
. id = - 1 ,
. rate = 27000000 ,
} ;
2008-10-31 16:14:36 +00:00
static int clk_48m_ctrl ( struct clk * clk , int enable )
{
unsigned long flags ;
u32 val ;
/* can't rely on clock lock, this register has other usages */
local_irq_save ( flags ) ;
val = __raw_readl ( S3C64XX_OTHERS ) ;
if ( enable )
val | = S3C64XX_OTHERS_USBMASK ;
else
val & = ~ S3C64XX_OTHERS_USBMASK ;
__raw_writel ( val , S3C64XX_OTHERS ) ;
local_irq_restore ( flags ) ;
return 0 ;
}
2008-10-21 14:07:00 +01:00
struct clk clk_48m = {
. name = " clk_48m " ,
. id = - 1 ,
. rate = 48000000 ,
2008-10-31 16:14:36 +00:00
. enable = clk_48m_ctrl ,
2008-10-21 14:07:00 +01:00
} ;
static int inline s3c64xx_gate ( void __iomem * reg ,
struct clk * clk ,
int enable )
{
unsigned int ctrlbit = clk - > ctrlbit ;
u32 con ;
con = __raw_readl ( reg ) ;
if ( enable )
con | = ctrlbit ;
else
con & = ~ ctrlbit ;
__raw_writel ( con , reg ) ;
return 0 ;
}
static int s3c64xx_pclk_ctrl ( struct clk * clk , int enable )
{
return s3c64xx_gate ( S3C_PCLK_GATE , clk , enable ) ;
}
static int s3c64xx_hclk_ctrl ( struct clk * clk , int enable )
{
return s3c64xx_gate ( S3C_HCLK_GATE , clk , enable ) ;
}
2008-10-21 14:07:02 +01:00
int s3c64xx_sclk_ctrl ( struct clk * clk , int enable )
2008-10-21 14:07:00 +01:00
{
return s3c64xx_gate ( S3C_SCLK_GATE , clk , enable ) ;
}
static struct clk init_clocks_disable [ ] = {
{
. name = " nand " ,
. id = - 1 ,
. parent = & clk_h ,
} , {
. name = " adc " ,
. id = - 1 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_TSADC ,
} , {
. name = " i2c " ,
. id = - 1 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_IIC ,
} , {
. name = " iis " ,
. id = 0 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_IIS0 ,
} , {
. name = " iis " ,
. id = 1 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_IIS1 ,
} , {
. name = " spi " ,
. id = 0 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_SPI0 ,
} , {
. name = " spi " ,
. id = 1 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_SPI1 ,
2010-01-18 16:15:08 +09:00
} , {
. name = " spi_48m " ,
. id = 0 ,
. parent = & clk_48m ,
. enable = s3c64xx_sclk_ctrl ,
. ctrlbit = S3C_CLKCON_SCLK_SPI0_48 ,
} , {
. name = " spi_48m " ,
. id = 1 ,
. parent = & clk_48m ,
. enable = s3c64xx_sclk_ctrl ,
. ctrlbit = S3C_CLKCON_SCLK_SPI1_48 ,
2008-10-21 14:07:00 +01:00
} , {
. name = " 48m " ,
. id = 0 ,
. parent = & clk_48m ,
. enable = s3c64xx_sclk_ctrl ,
. ctrlbit = S3C_CLKCON_SCLK_MMC0_48 ,
} , {
. name = " 48m " ,
. id = 1 ,
. parent = & clk_48m ,
. enable = s3c64xx_sclk_ctrl ,
. ctrlbit = S3C_CLKCON_SCLK_MMC1_48 ,
} , {
. name = " 48m " ,
. id = 2 ,
. parent = & clk_48m ,
. enable = s3c64xx_sclk_ctrl ,
. ctrlbit = S3C_CLKCON_SCLK_MMC2_48 ,
2009-04-28 16:06:24 +01:00
} , {
. name = " dma0 " ,
. id = - 1 ,
. parent = & clk_h ,
. enable = s3c64xx_hclk_ctrl ,
. ctrlbit = S3C_CLKCON_HCLK_DMA0 ,
} , {
. name = " dma1 " ,
. id = - 1 ,
. parent = & clk_h ,
. enable = s3c64xx_hclk_ctrl ,
. ctrlbit = S3C_CLKCON_HCLK_DMA1 ,
2008-10-21 14:07:00 +01:00
} ,
} ;
static struct clk init_clocks [ ] = {
{
. name = " lcd " ,
. id = - 1 ,
. parent = & clk_h ,
. enable = s3c64xx_hclk_ctrl ,
. ctrlbit = S3C_CLKCON_HCLK_LCD ,
} , {
. name = " gpio " ,
. id = - 1 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_GPIO ,
} , {
. name = " usb-host " ,
. id = - 1 ,
. parent = & clk_h ,
. enable = s3c64xx_hclk_ctrl ,
2009-06-18 23:54:44 +02:00
. ctrlbit = S3C_CLKCON_HCLK_UHOST ,
2008-10-21 14:07:00 +01:00
} , {
. name = " hsmmc " ,
. id = 0 ,
. parent = & clk_h ,
. enable = s3c64xx_hclk_ctrl ,
. ctrlbit = S3C_CLKCON_HCLK_HSMMC0 ,
} , {
. name = " hsmmc " ,
. id = 1 ,
. parent = & clk_h ,
. enable = s3c64xx_hclk_ctrl ,
. ctrlbit = S3C_CLKCON_HCLK_HSMMC1 ,
} , {
. name = " hsmmc " ,
. id = 2 ,
. parent = & clk_h ,
. enable = s3c64xx_hclk_ctrl ,
. ctrlbit = S3C_CLKCON_HCLK_HSMMC2 ,
} , {
. name = " timers " ,
. id = - 1 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_PWM ,
} , {
. name = " uart " ,
. id = 0 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_UART0 ,
} , {
. name = " uart " ,
. id = 1 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_UART1 ,
} , {
. name = " uart " ,
. id = 2 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_UART2 ,
} , {
. name = " uart " ,
. id = 3 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_UART3 ,
} , {
. name = " rtc " ,
. id = - 1 ,
. parent = & clk_p ,
. enable = s3c64xx_pclk_ctrl ,
. ctrlbit = S3C_CLKCON_PCLK_RTC ,
} , {
. name = " watchdog " ,
. id = - 1 ,
. parent = & clk_p ,
. ctrlbit = S3C_CLKCON_PCLK_WDT ,
} , {
. name = " ac97 " ,
. id = - 1 ,
. parent = & clk_p ,
. ctrlbit = S3C_CLKCON_PCLK_AC97 ,
}
} ;
static struct clk * clks [ ] __initdata = {
& clk_ext ,
& clk_epll ,
& clk_27m ,
& clk_48m ,
2009-03-05 11:43:13 +08:00
& clk_h2 ,
2008-10-21 14:07:00 +01:00
} ;
2009-01-26 19:12:01 +00:00
void __init s3c64xx_register_clocks ( void )
2008-10-21 14:07:00 +01:00
{
struct clk * clkp ;
int ret ;
int ptr ;
s3c24xx_register_clocks ( clks , ARRAY_SIZE ( clks ) ) ;
2010-01-06 01:21:38 +09:00
s3c_register_clocks ( init_clocks , ARRAY_SIZE ( init_clocks ) ) ;
2008-10-21 14:07:00 +01:00
clkp = init_clocks_disable ;
for ( ptr = 0 ; ptr < ARRAY_SIZE ( init_clocks_disable ) ; ptr + + , clkp + + ) {
ret = s3c24xx_register_clock ( clkp ) ;
if ( ret < 0 ) {
printk ( KERN_ERR " Failed to register clock %s (%d) \n " ,
clkp - > name , ret ) ;
}
( clkp - > enable ) ( clkp , 0 ) ;
}
2008-11-21 10:36:05 +00:00
s3c_pwmclk_init ( ) ;
2008-10-21 14:07:00 +01:00
}