2011-11-10 18:45:52 -08:00
/*
* R8A7740 processor support
*
* Copyright ( C ) 2011 Renesas Solutions Corp .
* Copyright ( C ) 2011 Kuninori Morimoto < kuninori . morimoto . gx @ renesas . com >
*
* 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
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* 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 . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include <linux/init.h>
# include <linux/kernel.h>
# include <linux/io.h>
# include <linux/sh_clk.h>
# include <linux/clkdev.h>
2013-03-27 00:56:57 -07:00
# include <mach/clock.h>
2011-11-10 18:45:52 -08:00
# include <mach/common.h>
# include <mach/r8a7740.h>
/*
* | MDx | XTAL1 / EXTAL1 | System | EXTALR |
* Clock | - - - - - - - + - - - - - - - - - - - - - - - - - + clock | 32.768 | RCLK
* Mode | 2 / 1 / 0 | src MHz | source | KHz | source
* - - - - - - - + - - - - - - - + - - - - - - - - - - - - - - - - - + - - - - - - - - - - - + - - - - - - - - + - - - - - - - - - -
* 0 | 0 0 0 | External 20 ~ 50 | XTAL1 | O | EXTALR
* 1 | 0 0 1 | Crystal 20 ~ 30 | XTAL1 | O | EXTALR
* 2 | 0 1 0 | External 40 ~ 50 | XTAL1 / 2 | O | EXTALR
* 3 | 0 1 1 | Crystal 40 ~ 50 | XTAL1 / 2 | O | EXTALR
* 4 | 1 0 0 | External 20 ~ 50 | XTAL1 | x | XTAL1 / 1024
* 5 | 1 0 1 | Crystal 20 ~ 30 | XTAL1 | x | XTAL1 / 1024
* 6 | 1 1 0 | External 40 ~ 50 | XTAL1 / 2 | x | XTAL1 / 2048
* 7 | 1 1 1 | Crystal 40 ~ 50 | XTAL1 / 2 | x | XTAL1 / 2048
*/
/* CPG registers */
2012-09-14 20:08:08 +00:00
# define FRQCRA IOMEM(0xe6150000)
# define FRQCRB IOMEM(0xe6150004)
# define VCLKCR1 IOMEM(0xE6150008)
# define VCLKCR2 IOMEM(0xE615000c)
# define FRQCRC IOMEM(0xe61500e0)
# define FSIACKCR IOMEM(0xe6150018)
# define PLLC01CR IOMEM(0xe6150028)
2011-11-10 18:45:52 -08:00
2012-09-14 20:08:08 +00:00
# define SUBCKCR IOMEM(0xe6150080)
# define USBCKCR IOMEM(0xe615008c)
2011-11-10 18:45:52 -08:00
2012-09-14 20:08:08 +00:00
# define MSTPSR0 IOMEM(0xe6150030)
# define MSTPSR1 IOMEM(0xe6150038)
# define MSTPSR2 IOMEM(0xe6150040)
# define MSTPSR3 IOMEM(0xe6150048)
# define MSTPSR4 IOMEM(0xe615004c)
# define FSIBCKCR IOMEM(0xe6150090)
# define HDMICKCR IOMEM(0xe6150094)
# define SMSTPCR0 IOMEM(0xe6150130)
# define SMSTPCR1 IOMEM(0xe6150134)
# define SMSTPCR2 IOMEM(0xe6150138)
# define SMSTPCR3 IOMEM(0xe615013c)
# define SMSTPCR4 IOMEM(0xe6150140)
2011-11-10 18:45:52 -08:00
2012-10-30 22:57:25 -07:00
# define FSIDIVA IOMEM(0xFE1F8000)
# define FSIDIVB IOMEM(0xFE1F8008)
2011-11-10 18:45:52 -08:00
/* Fixed 32 KHz root clock from EXTALR pin */
static struct clk extalr_clk = {
. rate = 32768 ,
} ;
/*
* 25 MHz default rate for the EXTAL1 root input clock .
* If needed , reset this with clk_set_rate ( ) from the platform code .
*/
static struct clk extal1_clk = {
. rate = 25000000 ,
} ;
/*
* 48 MHz default rate for the EXTAL2 root input clock .
* If needed , reset this with clk_set_rate ( ) from the platform code .
*/
static struct clk extal2_clk = {
. rate = 48000000 ,
} ;
/*
* 27 MHz default rate for the DV_CLKI root input clock .
* If needed , reset this with clk_set_rate ( ) from the platform code .
*/
static struct clk dv_clk = {
. rate = 27000000 ,
} ;
2013-03-27 00:56:57 -07:00
SH_CLK_RATIO ( div2 , 1 , 2 ) ;
SH_CLK_RATIO ( div1k , 1 , 1024 ) ;
2011-11-10 18:45:52 -08:00
2013-03-27 00:56:57 -07:00
SH_FIXED_RATIO_CLK ( extal1_div2_clk , extal1_clk , div2 ) ;
SH_FIXED_RATIO_CLK ( extal1_div1024_clk , extal1_clk , div1k ) ;
SH_FIXED_RATIO_CLK ( extal1_div2048_clk , extal1_div2_clk , div1k ) ;
SH_FIXED_RATIO_CLK ( extal2_div2_clk , extal2_clk , div2 ) ;
2011-11-10 18:45:52 -08:00
2012-02-29 22:17:00 +09:00
static struct sh_clk_ops followparent_clk_ops = {
2011-11-10 18:45:52 -08:00
. recalc = followparent_recalc ,
} ;
/* Main clock */
static struct clk system_clk = {
. ops = & followparent_clk_ops ,
} ;
2013-03-27 00:56:57 -07:00
SH_FIXED_RATIO_CLK ( system_div2_clk , system_clk , div2 ) ;
2011-11-10 18:45:52 -08:00
/* r_clk */
static struct clk r_clk = {
. ops = & followparent_clk_ops ,
} ;
/* PLLC0/PLLC1 */
static unsigned long pllc01_recalc ( struct clk * clk )
{
unsigned long mult = 1 ;
if ( __raw_readl ( PLLC01CR ) & ( 1 < < 14 ) )
mult = ( ( __raw_readl ( clk - > enable_reg ) > > 24 ) & 0x7f ) + 1 ;
return clk - > parent - > rate * mult ;
}
2012-02-29 22:17:00 +09:00
static struct sh_clk_ops pllc01_clk_ops = {
2011-11-10 18:45:52 -08:00
. recalc = pllc01_recalc ,
} ;
static struct clk pllc0_clk = {
. ops = & pllc01_clk_ops ,
. flags = CLK_ENABLE_ON_INIT ,
. parent = & system_clk ,
. enable_reg = ( void __iomem * ) FRQCRC ,
} ;
static struct clk pllc1_clk = {
. ops = & pllc01_clk_ops ,
. flags = CLK_ENABLE_ON_INIT ,
. parent = & system_div2_clk ,
. enable_reg = ( void __iomem * ) FRQCRA ,
} ;
/* PLLC1 / 2 */
2013-03-27 00:56:57 -07:00
SH_FIXED_RATIO_CLK ( pllc1_div2_clk , pllc1_clk , div2 ) ;
2011-11-10 18:45:52 -08:00
2012-04-24 02:07:47 -07:00
/* USB clock */
2012-10-29 01:14:41 -07:00
/*
* USBCKCR is controlling usb24 clock
* bit [ 7 ] : parent clock
* bit [ 6 ] : clock divide rate
* And this bit [ 7 ] is used as a " usb24s " from other devices .
* ( Video clock / Sub clock / SPU clock )
* You can controll this clock as a below .
*
* struct clk * usb24 = clk_get ( dev , " usb24 " ) ;
* struct clk * usb24s = clk_get ( NULL , " usb24s " ) ;
* struct clk * system = clk_get ( NULL , " system_clk " ) ;
* int rate = clk_get_rate ( system ) ;
*
* clk_set_parent ( usb24s , system ) ; // for bit[7]
* clk_set_rate ( usb24 , rate / 2 ) ; // for bit[6]
*/
2012-04-24 02:07:47 -07:00
static struct clk * usb24s_parents [ ] = {
[ 0 ] = & system_clk ,
[ 1 ] = & extal2_clk
} ;
static int usb24s_enable ( struct clk * clk )
{
__raw_writel ( __raw_readl ( USBCKCR ) & ~ ( 1 < < 8 ) , USBCKCR ) ;
return 0 ;
}
static void usb24s_disable ( struct clk * clk )
{
__raw_writel ( __raw_readl ( USBCKCR ) | ( 1 < < 8 ) , USBCKCR ) ;
}
static int usb24s_set_parent ( struct clk * clk , struct clk * parent )
{
int i , ret ;
u32 val ;
if ( ! clk - > parent_table | | ! clk - > parent_num )
return - EINVAL ;
/* Search the parent */
for ( i = 0 ; i < clk - > parent_num ; i + + )
if ( clk - > parent_table [ i ] = = parent )
break ;
if ( i = = clk - > parent_num )
return - ENODEV ;
ret = clk_reparent ( clk , parent ) ;
if ( ret < 0 )
return ret ;
val = __raw_readl ( USBCKCR ) ;
val & = ~ ( 1 < < 7 ) ;
val | = i < < 7 ;
__raw_writel ( val , USBCKCR ) ;
return 0 ;
}
static struct sh_clk_ops usb24s_clk_ops = {
2012-05-06 18:12:41 -07:00
. recalc = followparent_recalc ,
2012-04-24 02:07:47 -07:00
. enable = usb24s_enable ,
. disable = usb24s_disable ,
. set_parent = usb24s_set_parent ,
} ;
static struct clk usb24s_clk = {
. ops = & usb24s_clk_ops ,
. parent_table = usb24s_parents ,
. parent_num = ARRAY_SIZE ( usb24s_parents ) ,
. parent = & system_clk ,
} ;
static unsigned long usb24_recalc ( struct clk * clk )
{
return clk - > parent - > rate /
( ( __raw_readl ( USBCKCR ) & ( 1 < < 6 ) ) ? 1 : 2 ) ;
} ;
static int usb24_set_rate ( struct clk * clk , unsigned long rate )
{
u32 val ;
/* closer to which ? parent->rate or parent->rate/2 */
val = __raw_readl ( USBCKCR ) ;
val & = ~ ( 1 < < 6 ) ;
val | = ( rate > ( clk - > parent - > rate / 4 ) * 3 ) < < 6 ;
__raw_writel ( val , USBCKCR ) ;
return 0 ;
}
static struct sh_clk_ops usb24_clk_ops = {
. recalc = usb24_recalc ,
. set_rate = usb24_set_rate ,
} ;
static struct clk usb24_clk = {
. ops = & usb24_clk_ops ,
. parent = & usb24s_clk ,
} ;
2012-06-12 02:36:58 -07:00
/* External FSIACK/FSIBCK clock */
static struct clk fsiack_clk = {
} ;
static struct clk fsibck_clk = {
} ;
2013-04-16 17:16:19 +02:00
static struct clk * main_clks [ ] = {
2011-11-10 18:45:52 -08:00
& extalr_clk ,
& extal1_clk ,
& extal2_clk ,
& extal1_div2_clk ,
& extal1_div1024_clk ,
& extal1_div2048_clk ,
& extal2_div2_clk ,
& dv_clk ,
& system_clk ,
& system_div2_clk ,
& r_clk ,
& pllc0_clk ,
& pllc1_clk ,
& pllc1_div2_clk ,
2012-04-24 02:07:47 -07:00
& usb24s_clk ,
& usb24_clk ,
2012-06-12 02:36:58 -07:00
& fsiack_clk ,
& fsibck_clk ,
2011-11-10 18:45:52 -08:00
} ;
2013-03-27 00:56:40 -07:00
/* DIV4 clocks */
2011-11-10 18:45:52 -08:00
static void div4_kick ( struct clk * clk )
{
unsigned long value ;
/* set KICK bit in FRQCRB to update hardware setting */
value = __raw_readl ( FRQCRB ) ;
value | = ( 1 < < 31 ) ;
__raw_writel ( value , FRQCRB ) ;
}
static int divisors [ ] = { 2 , 3 , 4 , 6 , 8 , 12 , 16 , 18 ,
24 , 32 , 36 , 48 , 0 , 72 , 96 , 0 } ;
static struct clk_div_mult_table div4_div_mult_table = {
. divisors = divisors ,
. nr_divisors = ARRAY_SIZE ( divisors ) ,
} ;
static struct clk_div4_table div4_table = {
. div_mult_table = & div4_div_mult_table ,
. kick = div4_kick ,
} ;
2013-03-27 00:56:40 -07:00
enum {
DIV4_I , DIV4_ZG , DIV4_B , DIV4_M1 , DIV4_HP ,
DIV4_HPP , DIV4_USBP , DIV4_S , DIV4_ZB , DIV4_M3 , DIV4_CP ,
DIV4_NR
} ;
2013-04-16 17:16:19 +02:00
static struct clk div4_clks [ DIV4_NR ] = {
2013-03-27 00:56:40 -07:00
[ DIV4_I ] = SH_CLK_DIV4 ( & pllc1_clk , FRQCRA , 20 , 0x6fff , CLK_ENABLE_ON_INIT ) ,
[ DIV4_ZG ] = SH_CLK_DIV4 ( & pllc1_clk , FRQCRA , 16 , 0x6fff , CLK_ENABLE_ON_INIT ) ,
[ DIV4_B ] = SH_CLK_DIV4 ( & pllc1_clk , FRQCRA , 8 , 0x6fff , CLK_ENABLE_ON_INIT ) ,
[ DIV4_M1 ] = SH_CLK_DIV4 ( & pllc1_clk , FRQCRA , 4 , 0x6fff , CLK_ENABLE_ON_INIT ) ,
[ DIV4_HP ] = SH_CLK_DIV4 ( & pllc1_clk , FRQCRB , 4 , 0x6fff , 0 ) ,
[ DIV4_HPP ] = SH_CLK_DIV4 ( & pllc1_clk , FRQCRC , 20 , 0x6fff , 0 ) ,
[ DIV4_USBP ] = SH_CLK_DIV4 ( & pllc1_clk , FRQCRC , 16 , 0x6fff , 0 ) ,
[ DIV4_S ] = SH_CLK_DIV4 ( & pllc1_clk , FRQCRC , 12 , 0x6fff , 0 ) ,
[ DIV4_ZB ] = SH_CLK_DIV4 ( & pllc1_clk , FRQCRC , 8 , 0x6fff , 0 ) ,
[ DIV4_M3 ] = SH_CLK_DIV4 ( & pllc1_clk , FRQCRC , 4 , 0x6fff , 0 ) ,
[ DIV4_CP ] = SH_CLK_DIV4 ( & pllc1_clk , FRQCRC , 0 , 0x6fff , 0 ) ,
} ;
2012-06-12 02:35:36 -07:00
/* DIV6 reparent */
enum {
DIV6_HDMI ,
2012-06-12 02:36:39 -07:00
DIV6_VCLK1 , DIV6_VCLK2 ,
2012-06-12 02:36:58 -07:00
DIV6_FSIA , DIV6_FSIB ,
2012-06-12 02:35:36 -07:00
DIV6_REPARENT_NR ,
} ;
static struct clk * hdmi_parent [ ] = {
[ 0 ] = & pllc1_div2_clk ,
[ 1 ] = & system_clk ,
[ 2 ] = & dv_clk
} ;
2012-06-12 02:36:39 -07:00
static struct clk * vclk_parents [ 8 ] = {
[ 0 ] = & pllc1_div2_clk ,
[ 2 ] = & dv_clk ,
[ 3 ] = & usb24s_clk ,
[ 4 ] = & extal1_div2_clk ,
[ 5 ] = & extalr_clk ,
} ;
2012-06-12 02:36:58 -07:00
static struct clk * fsia_parents [ ] = {
[ 0 ] = & pllc1_div2_clk ,
[ 1 ] = & fsiack_clk , /* external clock */
} ;
static struct clk * fsib_parents [ ] = {
[ 0 ] = & pllc1_div2_clk ,
[ 1 ] = & fsibck_clk , /* external clock */
} ;
2012-06-12 02:35:36 -07:00
static struct clk div6_reparent_clks [ DIV6_REPARENT_NR ] = {
[ DIV6_HDMI ] = SH_CLK_DIV6_EXT ( HDMICKCR , 0 ,
hdmi_parent , ARRAY_SIZE ( hdmi_parent ) , 6 , 2 ) ,
2012-06-12 02:36:39 -07:00
[ DIV6_VCLK1 ] = SH_CLK_DIV6_EXT ( VCLKCR1 , 0 ,
vclk_parents , ARRAY_SIZE ( vclk_parents ) , 12 , 3 ) ,
[ DIV6_VCLK2 ] = SH_CLK_DIV6_EXT ( VCLKCR2 , 0 ,
vclk_parents , ARRAY_SIZE ( vclk_parents ) , 12 , 3 ) ,
2012-06-12 02:36:58 -07:00
[ DIV6_FSIA ] = SH_CLK_DIV6_EXT ( FSIACKCR , 0 ,
fsia_parents , ARRAY_SIZE ( fsia_parents ) , 6 , 2 ) ,
[ DIV6_FSIB ] = SH_CLK_DIV6_EXT ( FSIBCKCR , 0 ,
fsib_parents , ARRAY_SIZE ( fsib_parents ) , 6 , 2 ) ,
2012-06-12 02:35:36 -07:00
} ;
2013-03-27 00:56:40 -07:00
/* DIV6 clocks */
enum {
DIV6_SUB ,
DIV6_NR
} ;
static struct clk div6_clks [ DIV6_NR ] = {
[ DIV6_SUB ] = SH_CLK_DIV6 ( & pllc1_div2_clk , SUBCKCR , 0 ) ,
} ;
2012-06-12 02:35:36 -07:00
/* HDMI1/2 clock */
static unsigned long hdmi12_recalc ( struct clk * clk )
{
u32 val = __raw_readl ( HDMICKCR ) ;
int shift = ( int ) clk - > priv ;
val > > = shift ;
val & = 0x3 ;
return clk - > parent - > rate / ( 1 < < val ) ;
} ;
static int hdmi12_set_rate ( struct clk * clk , unsigned long rate )
{
u32 val , mask ;
int i , shift ;
for ( i = 0 ; i < 3 ; i + + )
if ( rate = = clk - > parent - > rate / ( 1 < < i ) )
goto find ;
return - ENODEV ;
find :
shift = ( int ) clk - > priv ;
val = __raw_readl ( HDMICKCR ) ;
mask = ~ ( 0x3 < < shift ) ;
val = ( val & mask ) | i < < shift ;
__raw_writel ( val , HDMICKCR ) ;
return 0 ;
} ;
static struct sh_clk_ops hdmi12_clk_ops = {
. recalc = hdmi12_recalc ,
. set_rate = hdmi12_set_rate ,
} ;
static struct clk hdmi1_clk = {
. ops = & hdmi12_clk_ops ,
. priv = ( void * ) 9 ,
. parent = & div6_reparent_clks [ DIV6_HDMI ] , /* late install */
} ;
static struct clk hdmi2_clk = {
. ops = & hdmi12_clk_ops ,
. priv = ( void * ) 11 ,
. parent = & div6_reparent_clks [ DIV6_HDMI ] , /* late install */
} ;
static struct clk * late_main_clks [ ] = {
& hdmi1_clk ,
& hdmi2_clk ,
} ;
2012-10-30 22:57:25 -07:00
/* FSI DIV */
enum { FSIDIV_A , FSIDIV_B , FSIDIV_REPARENT_NR } ;
static struct clk fsidivs [ ] = {
[ FSIDIV_A ] = SH_CLK_FSIDIV ( FSIDIVA , & div6_reparent_clks [ DIV6_FSIA ] ) ,
[ FSIDIV_B ] = SH_CLK_FSIDIV ( FSIDIVB , & div6_reparent_clks [ DIV6_FSIB ] ) ,
} ;
2012-06-12 02:35:36 -07:00
/* MSTP */
2011-11-10 18:45:52 -08:00
enum {
2012-06-12 02:36:39 -07:00
MSTP128 , MSTP127 , MSTP125 ,
2011-11-10 18:47:16 -08:00
MSTP116 , MSTP111 , MSTP100 , MSTP117 ,
2011-11-10 18:45:52 -08:00
MSTP230 ,
MSTP222 ,
2012-06-25 03:37:10 -07:00
MSTP218 , MSTP217 , MSTP216 , MSTP214 ,
2011-11-10 18:45:52 -08:00
MSTP207 , MSTP206 , MSTP204 , MSTP203 , MSTP202 , MSTP201 , MSTP200 ,
2012-04-24 02:07:47 -07:00
MSTP329 , MSTP328 , MSTP323 , MSTP320 ,
2012-04-24 02:08:29 -07:00
MSTP314 , MSTP313 , MSTP312 ,
2012-10-26 15:38:47 +02:00
MSTP309 , MSTP304 ,
2012-04-24 02:07:47 -07:00
2012-04-24 02:08:11 -07:00
MSTP416 , MSTP415 , MSTP407 , MSTP406 ,
2011-11-10 18:45:52 -08:00
MSTP_NR
} ;
static struct clk mstp_clks [ MSTP_NR ] = {
2012-06-12 02:36:39 -07:00
[ MSTP128 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_S ] , SMSTPCR1 , 28 , 0 ) , /* CEU21 */
[ MSTP127 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_S ] , SMSTPCR1 , 27 , 0 ) , /* CEU20 */
2011-11-10 18:45:52 -08:00
[ MSTP125 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR1 , 25 , 0 ) , /* TMU0 */
2011-11-10 18:47:16 -08:00
[ MSTP117 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_B ] , SMSTPCR1 , 17 , 0 ) , /* LCDC1 */
2011-11-10 18:45:52 -08:00
[ MSTP116 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR1 , 16 , 0 ) , /* IIC0 */
[ MSTP111 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR1 , 11 , 0 ) , /* TMU1 */
2011-11-10 18:47:16 -08:00
[ MSTP100 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_B ] , SMSTPCR1 , 0 , 0 ) , /* LCDC0 */
2011-11-10 18:45:52 -08:00
[ MSTP230 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR2 , 30 , 0 ) , /* SCIFA6 */
[ MSTP222 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR2 , 22 , 0 ) , /* SCIFA7 */
2012-06-25 03:36:49 -07:00
[ MSTP218 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR2 , 18 , 0 ) , /* DMAC1 */
[ MSTP217 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR2 , 17 , 0 ) , /* DMAC2 */
[ MSTP216 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR2 , 16 , 0 ) , /* DMAC3 */
2012-06-25 03:37:10 -07:00
[ MSTP214 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR2 , 14 , 0 ) , /* USBDMAC */
2011-11-10 18:45:52 -08:00
[ MSTP207 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR2 , 7 , 0 ) , /* SCIFA5 */
[ MSTP206 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR2 , 6 , 0 ) , /* SCIFB */
[ MSTP204 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR2 , 4 , 0 ) , /* SCIFA0 */
[ MSTP203 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR2 , 3 , 0 ) , /* SCIFA1 */
[ MSTP202 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR2 , 2 , 0 ) , /* SCIFA2 */
[ MSTP201 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR2 , 1 , 0 ) , /* SCIFA3 */
[ MSTP200 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR2 , 0 , 0 ) , /* SCIFA4 */
[ MSTP329 ] = SH_CLK_MSTP32 ( & r_clk , SMSTPCR3 , 29 , 0 ) , /* CMT10 */
2012-04-01 18:46:09 -07:00
[ MSTP328 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR3 , 28 , 0 ) , /* FSI */
2011-11-10 18:45:52 -08:00
[ MSTP323 ] = SH_CLK_MSTP32 ( & div6_clks [ DIV6_SUB ] , SMSTPCR3 , 23 , 0 ) , /* IIC1 */
2012-04-24 02:07:47 -07:00
[ MSTP320 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR3 , 20 , 0 ) , /* USBF */
2012-04-24 02:08:11 -07:00
[ MSTP314 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR3 , 14 , 0 ) , /* SDHI0 */
[ MSTP313 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR3 , 13 , 0 ) , /* SDHI1 */
2012-04-24 02:08:29 -07:00
[ MSTP312 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR3 , 12 , 0 ) , /* MMC */
2012-05-06 22:58:41 -07:00
[ MSTP309 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR3 , 9 , 0 ) , /* GEther */
2012-10-26 15:38:47 +02:00
[ MSTP304 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_CP ] , SMSTPCR3 , 4 , 0 ) , /* TPU0 */
2012-04-24 02:07:47 -07:00
[ MSTP416 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR4 , 16 , 0 ) , /* USBHOST */
2012-04-24 02:08:11 -07:00
[ MSTP415 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR4 , 15 , 0 ) , /* SDHI2 */
2012-04-24 02:07:47 -07:00
[ MSTP407 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR4 , 7 , 0 ) , /* USB-Func */
[ MSTP406 ] = SH_CLK_MSTP32 ( & div4_clks [ DIV4_HP ] , SMSTPCR4 , 6 , 0 ) , /* USB Phy */
2011-11-10 18:45:52 -08:00
} ;
static struct clk_lookup lookups [ ] = {
/* main clocks */
CLKDEV_CON_ID ( " extalr " , & extalr_clk ) ,
CLKDEV_CON_ID ( " extal1 " , & extal1_clk ) ,
CLKDEV_CON_ID ( " extal2 " , & extal2_clk ) ,
CLKDEV_CON_ID ( " extal1_div2 " , & extal1_div2_clk ) ,
CLKDEV_CON_ID ( " extal1_div1024 " , & extal1_div1024_clk ) ,
CLKDEV_CON_ID ( " extal1_div2048 " , & extal1_div2048_clk ) ,
CLKDEV_CON_ID ( " extal2_div2 " , & extal2_div2_clk ) ,
CLKDEV_CON_ID ( " dv_clk " , & dv_clk ) ,
CLKDEV_CON_ID ( " system_clk " , & system_clk ) ,
CLKDEV_CON_ID ( " system_div2_clk " , & system_div2_clk ) ,
CLKDEV_CON_ID ( " r_clk " , & r_clk ) ,
CLKDEV_CON_ID ( " pllc0_clk " , & pllc0_clk ) ,
CLKDEV_CON_ID ( " pllc1_clk " , & pllc1_clk ) ,
CLKDEV_CON_ID ( " pllc1_div2_clk " , & pllc1_div2_clk ) ,
2012-04-24 02:07:47 -07:00
CLKDEV_CON_ID ( " usb24s " , & usb24s_clk ) ,
2012-06-12 02:35:36 -07:00
CLKDEV_CON_ID ( " hdmi1 " , & hdmi1_clk ) ,
CLKDEV_CON_ID ( " hdmi2 " , & hdmi2_clk ) ,
2012-06-12 02:36:39 -07:00
CLKDEV_CON_ID ( " video1 " , & div6_reparent_clks [ DIV6_VCLK1 ] ) ,
CLKDEV_CON_ID ( " video2 " , & div6_reparent_clks [ DIV6_VCLK2 ] ) ,
2012-06-12 02:36:58 -07:00
CLKDEV_CON_ID ( " fsiack " , & fsiack_clk ) ,
CLKDEV_CON_ID ( " fsibck " , & fsibck_clk ) ,
2011-11-10 18:45:52 -08:00
/* DIV4 clocks */
CLKDEV_CON_ID ( " i_clk " , & div4_clks [ DIV4_I ] ) ,
CLKDEV_CON_ID ( " zg_clk " , & div4_clks [ DIV4_ZG ] ) ,
CLKDEV_CON_ID ( " b_clk " , & div4_clks [ DIV4_B ] ) ,
CLKDEV_CON_ID ( " m1_clk " , & div4_clks [ DIV4_M1 ] ) ,
CLKDEV_CON_ID ( " hp_clk " , & div4_clks [ DIV4_HP ] ) ,
CLKDEV_CON_ID ( " hpp_clk " , & div4_clks [ DIV4_HPP ] ) ,
CLKDEV_CON_ID ( " s_clk " , & div4_clks [ DIV4_S ] ) ,
CLKDEV_CON_ID ( " zb_clk " , & div4_clks [ DIV4_ZB ] ) ,
CLKDEV_CON_ID ( " m3_clk " , & div4_clks [ DIV4_M3 ] ) ,
CLKDEV_CON_ID ( " cp_clk " , & div4_clks [ DIV4_CP ] ) ,
/* DIV6 clocks */
CLKDEV_CON_ID ( " sub_clk " , & div6_clks [ DIV6_SUB ] ) ,
/* MSTP32 clocks */
2011-11-10 18:47:16 -08:00
CLKDEV_DEV_ID ( " sh_mobile_lcdc_fb.0 " , & mstp_clks [ MSTP100 ] ) ,
2012-12-12 02:08:09 -08:00
CLKDEV_DEV_ID ( " sh_tmu.3 " , & mstp_clks [ MSTP111 ] ) ,
CLKDEV_DEV_ID ( " sh_tmu.4 " , & mstp_clks [ MSTP111 ] ) ,
CLKDEV_DEV_ID ( " sh_tmu.5 " , & mstp_clks [ MSTP111 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " i2c-sh_mobile.0 " , & mstp_clks [ MSTP116 ] ) ,
2013-04-17 12:34:03 +02:00
CLKDEV_DEV_ID ( " fff20000.i2c " , & mstp_clks [ MSTP116 ] ) ,
2011-11-10 18:47:16 -08:00
CLKDEV_DEV_ID ( " sh_mobile_lcdc_fb.1 " , & mstp_clks [ MSTP117 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " sh_tmu.0 " , & mstp_clks [ MSTP125 ] ) ,
2012-12-12 02:08:09 -08:00
CLKDEV_DEV_ID ( " sh_tmu.1 " , & mstp_clks [ MSTP125 ] ) ,
CLKDEV_DEV_ID ( " sh_tmu.2 " , & mstp_clks [ MSTP125 ] ) ,
2012-06-12 02:36:39 -07:00
CLKDEV_DEV_ID ( " sh_mobile_ceu.0 " , & mstp_clks [ MSTP127 ] ) ,
CLKDEV_DEV_ID ( " sh_mobile_ceu.1 " , & mstp_clks [ MSTP128 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " sh-sci.4 " , & mstp_clks [ MSTP200 ] ) ,
2013-02-26 11:03:27 -06:00
CLKDEV_DEV_ID ( " e6c80000.sci " , & mstp_clks [ MSTP200 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " sh-sci.3 " , & mstp_clks [ MSTP201 ] ) ,
2013-02-26 11:03:27 -06:00
CLKDEV_DEV_ID ( " e6c70000.sci " , & mstp_clks [ MSTP201 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " sh-sci.2 " , & mstp_clks [ MSTP202 ] ) ,
2013-02-26 11:03:27 -06:00
CLKDEV_DEV_ID ( " e6c60000.sci " , & mstp_clks [ MSTP202 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " sh-sci.1 " , & mstp_clks [ MSTP203 ] ) ,
2013-02-26 11:03:27 -06:00
CLKDEV_DEV_ID ( " e6c50000.sci " , & mstp_clks [ MSTP203 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " sh-sci.0 " , & mstp_clks [ MSTP204 ] ) ,
2013-02-26 11:03:27 -06:00
CLKDEV_DEV_ID ( " e6c40000.sci " , & mstp_clks [ MSTP204 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " sh-sci.8 " , & mstp_clks [ MSTP206 ] ) ,
2013-02-26 11:03:27 -06:00
CLKDEV_DEV_ID ( " e6c30000.sci " , & mstp_clks [ MSTP206 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " sh-sci.5 " , & mstp_clks [ MSTP207 ] ) ,
2013-02-26 11:03:27 -06:00
CLKDEV_DEV_ID ( " e6cb0000.sci " , & mstp_clks [ MSTP207 ] ) ,
2012-06-25 03:37:10 -07:00
CLKDEV_DEV_ID ( " sh-dma-engine.3 " , & mstp_clks [ MSTP214 ] ) ,
2012-06-25 03:36:49 -07:00
CLKDEV_DEV_ID ( " sh-dma-engine.2 " , & mstp_clks [ MSTP216 ] ) ,
CLKDEV_DEV_ID ( " sh-dma-engine.1 " , & mstp_clks [ MSTP217 ] ) ,
CLKDEV_DEV_ID ( " sh-dma-engine.0 " , & mstp_clks [ MSTP218 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " sh-sci.7 " , & mstp_clks [ MSTP222 ] ) ,
2013-02-26 11:03:27 -06:00
CLKDEV_DEV_ID ( " e6cd0000.sci " , & mstp_clks [ MSTP222 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " sh-sci.6 " , & mstp_clks [ MSTP230 ] ) ,
2013-02-26 11:03:27 -06:00
CLKDEV_DEV_ID ( " e6cc0000.sci " , & mstp_clks [ MSTP230 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " sh_cmt.10 " , & mstp_clks [ MSTP329 ] ) ,
2012-04-01 18:46:09 -07:00
CLKDEV_DEV_ID ( " sh_fsi2 " , & mstp_clks [ MSTP328 ] ) ,
2011-11-10 18:45:52 -08:00
CLKDEV_DEV_ID ( " i2c-sh_mobile.1 " , & mstp_clks [ MSTP323 ] ) ,
2013-04-17 12:34:03 +02:00
CLKDEV_DEV_ID ( " e6c20000.i2c " , & mstp_clks [ MSTP323 ] ) ,
2012-04-24 02:07:47 -07:00
CLKDEV_DEV_ID ( " renesas_usbhs " , & mstp_clks [ MSTP320 ] ) ,
2012-04-24 02:08:11 -07:00
CLKDEV_DEV_ID ( " sh_mobile_sdhi.0 " , & mstp_clks [ MSTP314 ] ) ,
2013-02-08 19:38:25 +01:00
CLKDEV_DEV_ID ( " e6850000.sdhi " , & mstp_clks [ MSTP314 ] ) ,
2012-04-24 02:08:11 -07:00
CLKDEV_DEV_ID ( " sh_mobile_sdhi.1 " , & mstp_clks [ MSTP313 ] ) ,
2013-02-08 19:38:25 +01:00
CLKDEV_DEV_ID ( " e6860000.sdhi " , & mstp_clks [ MSTP313 ] ) ,
2012-04-24 02:08:29 -07:00
CLKDEV_DEV_ID ( " sh_mmcif " , & mstp_clks [ MSTP312 ] ) ,
2013-02-08 19:38:25 +01:00
CLKDEV_DEV_ID ( " e6bd0000.mmcif " , & mstp_clks [ MSTP312 ] ) ,
2013-06-07 13:57:12 +00:00
CLKDEV_DEV_ID ( " r8a7740-gether " , & mstp_clks [ MSTP309 ] ) ,
2012-12-18 17:22:38 +00:00
CLKDEV_DEV_ID ( " e9a00000.sh-eth " , & mstp_clks [ MSTP309 ] ) ,
2013-07-16 12:32:04 +02:00
CLKDEV_DEV_ID ( " renesas-tpu-pwm " , & mstp_clks [ MSTP304 ] ) ,
2013-07-26 00:50:59 +02:00
CLKDEV_DEV_ID ( " e6600000.pwm " , & mstp_clks [ MSTP304 ] ) ,
2012-04-24 02:08:11 -07:00
CLKDEV_DEV_ID ( " sh_mobile_sdhi.2 " , & mstp_clks [ MSTP415 ] ) ,
2013-02-08 19:38:25 +01:00
CLKDEV_DEV_ID ( " e6870000.sdhi " , & mstp_clks [ MSTP415 ] ) ,
2012-04-24 02:07:47 -07:00
/* ICK */
CLKDEV_ICK_ID ( " host " , " renesas_usbhs " , & mstp_clks [ MSTP416 ] ) ,
CLKDEV_ICK_ID ( " func " , " renesas_usbhs " , & mstp_clks [ MSTP407 ] ) ,
CLKDEV_ICK_ID ( " phy " , " renesas_usbhs " , & mstp_clks [ MSTP406 ] ) ,
CLKDEV_ICK_ID ( " pci " , " renesas_usbhs " , & div4_clks [ DIV4_USBP ] ) ,
CLKDEV_ICK_ID ( " usb24 " , " renesas_usbhs " , & usb24_clk ) ,
2012-06-12 02:35:36 -07:00
CLKDEV_ICK_ID ( " ick " , " sh-mobile-hdmi " , & div6_reparent_clks [ DIV6_HDMI ] ) ,
2012-06-12 02:36:58 -07:00
CLKDEV_ICK_ID ( " icka " , " sh_fsi2 " , & div6_reparent_clks [ DIV6_FSIA ] ) ,
CLKDEV_ICK_ID ( " ickb " , " sh_fsi2 " , & div6_reparent_clks [ DIV6_FSIB ] ) ,
2012-10-30 22:57:25 -07:00
CLKDEV_ICK_ID ( " diva " , " sh_fsi2 " , & fsidivs [ FSIDIV_A ] ) ,
CLKDEV_ICK_ID ( " divb " , " sh_fsi2 " , & fsidivs [ FSIDIV_B ] ) ,
2012-11-07 19:08:16 -08:00
CLKDEV_ICK_ID ( " xcka " , " sh_fsi2 " , & fsiack_clk ) ,
CLKDEV_ICK_ID ( " xckb " , " sh_fsi2 " , & fsibck_clk ) ,
2011-11-10 18:45:52 -08:00
} ;
void __init r8a7740_clock_init ( u8 md_ck )
{
int k , ret = 0 ;
/* detect system clock parent */
if ( md_ck & MD_CK1 )
system_clk . parent = & extal1_div2_clk ;
else
system_clk . parent = & extal1_clk ;
/* detect RCLK parent */
switch ( md_ck & ( MD_CK2 | MD_CK1 ) ) {
case MD_CK2 | MD_CK1 :
r_clk . parent = & extal1_div2048_clk ;
break ;
case MD_CK2 :
r_clk . parent = & extal1_div1024_clk ;
break ;
case MD_CK1 :
default :
r_clk . parent = & extalr_clk ;
break ;
}
for ( k = 0 ; ! ret & & ( k < ARRAY_SIZE ( main_clks ) ) ; k + + )
ret = clk_register ( main_clks [ k ] ) ;
if ( ! ret )
ret = sh_clk_div4_register ( div4_clks , DIV4_NR , & div4_table ) ;
if ( ! ret )
ret = sh_clk_div6_register ( div6_clks , DIV6_NR ) ;
2012-06-12 02:35:36 -07:00
if ( ! ret )
ret = sh_clk_div6_reparent_register ( div6_reparent_clks ,
DIV6_REPARENT_NR ) ;
2011-11-10 18:45:52 -08:00
if ( ! ret )
2012-06-27 09:59:00 +09:00
ret = sh_clk_mstp_register ( mstp_clks , MSTP_NR ) ;
2011-11-10 18:45:52 -08:00
2012-06-12 02:35:36 -07:00
for ( k = 0 ; ! ret & & ( k < ARRAY_SIZE ( late_main_clks ) ) ; k + + )
ret = clk_register ( late_main_clks [ k ] ) ;
2012-10-30 22:57:25 -07:00
if ( ! ret )
ret = sh_clk_fsidiv_register ( fsidivs , FSIDIV_REPARENT_NR ) ;
2011-11-10 18:45:52 -08:00
clkdev_add_table ( lookups , ARRAY_SIZE ( lookups ) ) ;
if ( ! ret )
2012-02-29 21:41:30 +09:00
shmobile_clk_init ( ) ;
2011-11-10 18:45:52 -08:00
else
panic ( " failed to setup r8a7740 clocks \n " ) ;
}