Path: blob/master/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
17531 views
/*1* arch/sh/kernel/cpu/sh4/clock-sh7757.c2*3* SH7757 support for the clock framework4*5* Copyright (C) 2009-2010 Renesas Solutions Corp.6*7* This file is subject to the terms and conditions of the GNU General Public8* License. See the file "COPYING" in the main directory of this archive9* for more details.10*/11#include <linux/init.h>12#include <linux/kernel.h>13#include <linux/io.h>14#include <linux/clkdev.h>15#include <asm/clock.h>16#include <asm/freq.h>1718/*19* Default rate for the root input clock, reset this with clk_set_rate()20* from the platform code.21*/22static struct clk extal_clk = {23.rate = 48000000,24};2526static unsigned long pll_recalc(struct clk *clk)27{28int multiplier;2930multiplier = test_mode_pin(MODE_PIN0) ? 24 : 16;3132return clk->parent->rate * multiplier;33}3435static struct clk_ops pll_clk_ops = {36.recalc = pll_recalc,37};3839static struct clk pll_clk = {40.ops = &pll_clk_ops,41.parent = &extal_clk,42.flags = CLK_ENABLE_ON_INIT,43};4445static struct clk *clks[] = {46&extal_clk,47&pll_clk,48};4950static unsigned int div2[] = { 1, 1, 2, 1, 1, 4, 1, 6,511, 1, 1, 16, 1, 24, 1, 1 };5253static struct clk_div_mult_table div4_div_mult_table = {54.divisors = div2,55.nr_divisors = ARRAY_SIZE(div2),56};5758static struct clk_div4_table div4_table = {59.div_mult_table = &div4_div_mult_table,60};6162enum { DIV4_I, DIV4_SH, DIV4_P, DIV4_NR };6364#define DIV4(_bit, _mask, _flags) \65SH_CLK_DIV4(&pll_clk, FRQCR, _bit, _mask, _flags)6667struct clk div4_clks[DIV4_NR] = {68/*69* P clock is always enable, because some P clock modules is used70* by Host PC.71*/72[DIV4_P] = DIV4(0, 0x2800, CLK_ENABLE_ON_INIT),73[DIV4_SH] = DIV4(12, 0x00a0, CLK_ENABLE_ON_INIT),74[DIV4_I] = DIV4(20, 0x0004, CLK_ENABLE_ON_INIT),75};7677#define MSTPCR0 0xffc8003078#define MSTPCR1 0xffc8003479#define MSTPCR2 0xffc100288081enum { MSTP004, MSTP000, MSTP114, MSTP113, MSTP112,82MSTP111, MSTP110, MSTP103, MSTP102, MSTP220,83MSTP_NR };8485static struct clk mstp_clks[MSTP_NR] = {86/* MSTPCR0 */87[MSTP004] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 4, 0),88[MSTP000] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 0, 0),8990/* MSTPCR1 */91[MSTP114] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 14, 0),92[MSTP113] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 13, 0),93[MSTP112] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 12, 0),94[MSTP111] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 11, 0),95[MSTP110] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 10, 0),96[MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 3, 0),97[MSTP102] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 2, 0),9899/* MSTPCR2 */100[MSTP220] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 20, 0),101};102103#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }104105static struct clk_lookup lookups[] = {106/* main clocks */107CLKDEV_CON_ID("extal", &extal_clk),108CLKDEV_CON_ID("pll_clk", &pll_clk),109110/* DIV4 clocks */111CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),112CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),113CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),114115/* MSTP32 clocks */116CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP004]),117CLKDEV_CON_ID("riic", &mstp_clks[MSTP000]),118{119/* TMU0 */120.dev_id = "sh_tmu.0",121.con_id = "tmu_fck",122.clk = &mstp_clks[MSTP113],123}, {124/* TMU1 */125.dev_id = "sh_tmu.1",126.con_id = "tmu_fck",127.clk = &mstp_clks[MSTP114],128},129{130/* SCIF4 (But, ID is 2) */131.dev_id = "sh-sci.2",132.con_id = "sci_fck",133.clk = &mstp_clks[MSTP112],134}, {135/* SCIF3 */136.dev_id = "sh-sci.1",137.con_id = "sci_fck",138.clk = &mstp_clks[MSTP111],139}, {140/* SCIF2 */141.dev_id = "sh-sci.0",142.con_id = "sci_fck",143.clk = &mstp_clks[MSTP110],144},145CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]),146CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]),147};148149int __init arch_clk_init(void)150{151int i, ret = 0;152153for (i = 0; i < ARRAY_SIZE(clks); i++)154ret |= clk_register(clks[i]);155for (i = 0; i < ARRAY_SIZE(lookups); i++)156clkdev_add(&lookups[i]);157158if (!ret)159ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),160&div4_table);161if (!ret)162ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);163164return ret;165}166167168169