/* * sh73a0 clock framework support * * Copyright (C) 2010 Magnus Damm * * 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 #include #include #include #include #include #define FRQCRA IOMEM(0xe6150000) #define FRQCRB IOMEM(0xe6150004) #define FRQCRD IOMEM(0xe61500e4) #define VCLKCR1 IOMEM(0xe6150008) #define VCLKCR2 IOMEM(0xe615000C) #define VCLKCR3 IOMEM(0xe615001C) #define ZBCKCR IOMEM(0xe6150010) #define FLCKCR IOMEM(0xe6150014) #define SD0CKCR IOMEM(0xe6150074) #define SD1CKCR IOMEM(0xe6150078) #define SD2CKCR IOMEM(0xe615007C) #define FSIACKCR IOMEM(0xe6150018) #define FSIBCKCR IOMEM(0xe6150090) #define SUBCKCR IOMEM(0xe6150080) #define SPUACKCR IOMEM(0xe6150084) #define SPUVCKCR IOMEM(0xe6150094) #define MSUCKCR IOMEM(0xe6150088) #define HSICKCR IOMEM(0xe615008C) #define MFCK1CR IOMEM(0xe6150098) #define MFCK2CR IOMEM(0xe615009C) #define DSITCKCR IOMEM(0xe6150060) #define DSI0PCKCR IOMEM(0xe6150064) #define DSI1PCKCR IOMEM(0xe6150068) #define DSI0PHYCR 0xe615006C #define DSI1PHYCR 0xe6150070 #define PLLECR IOMEM(0xe61500d0) #define PLL0CR IOMEM(0xe61500d8) #define PLL1CR IOMEM(0xe6150028) #define PLL2CR IOMEM(0xe615002c) #define PLL3CR IOMEM(0xe61500dc) #define SMSTPCR0 IOMEM(0xe6150130) #define SMSTPCR1 IOMEM(0xe6150134) #define SMSTPCR2 IOMEM(0xe6150138) #define SMSTPCR3 IOMEM(0xe615013c) #define SMSTPCR4 IOMEM(0xe6150140) #define SMSTPCR5 IOMEM(0xe6150144) #define CKSCR IOMEM(0xe61500c0) /* Fixed 32 KHz root clock from EXTALR pin */ static struct clk r_clk = { .rate = 32768, }; /* * 26MHz default rate for the EXTAL1 root input clock. * If needed, reset this with clk_set_rate() from the platform code. */ struct clk sh73a0_extal1_clk = { .rate = 26000000, }; /* * 48MHz default rate for the EXTAL2 root input clock. * If needed, reset this with clk_set_rate() from the platform code. */ struct clk sh73a0_extal2_clk = { .rate = 48000000, }; /* A fixed divide-by-2 block */ static unsigned long div2_recalc(struct clk *clk) { return clk->parent->rate / 2; } static struct sh_clk_ops div2_clk_ops = { .recalc = div2_recalc, }; static unsigned long div7_recalc(struct clk *clk) { return clk->parent->rate / 7; } static struct sh_clk_ops div7_clk_ops = { .recalc = div7_recalc, }; static unsigned long div13_recalc(struct clk *clk) { return clk->parent->rate / 13; } static struct sh_clk_ops div13_clk_ops = { .recalc = div13_recalc, }; /* Divide extal1 by two */ static struct clk extal1_div2_clk = { .ops = &div2_clk_ops, .parent = &sh73a0_extal1_clk, }; /* Divide extal2 by two */ static struct clk extal2_div2_clk = { .ops = &div2_clk_ops, .parent = &sh73a0_extal2_clk, }; static struct sh_clk_ops main_clk_ops = { .recalc = followparent_recalc, }; /* Main clock */ static struct clk main_clk = { .ops = &main_clk_ops, }; /* Divide Main clock by two */ static struct clk main_div2_clk = { .ops = &div2_clk_ops, .parent = &main_clk, }; /* PLL0, PLL1, PLL2, PLL3 */ static unsigned long pll_recalc(struct clk *clk) { unsigned long mult = 1; if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) { mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1); /* handle CFG bit for PLL1 and PLL2 */ switch (clk->enable_bit) { case 1: case 2: if (__raw_readl(clk->enable_reg) & (1 << 20)) mult *= 2; } } return clk->parent->rate * mult; } static struct sh_clk_ops pll_clk_ops = { .recalc = pll_recalc,