X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=arch%2Farm%2Fmach-s5pc100%2Fclock.c;h=2d4a761a516368008d4a607cc38098c4c53bdae6;hb=8bc26a008f61eac5631701cbd65f88c015a63280;hp=084abd13b0a56e963dbdc189078e7a822f6f317b;hpb=78ab952717b62c0ba6ca7f7a27eaa0486685e45f;p=pandora-kernel.git diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c index 084abd13b0a5..0305e9b8282d 100644 --- a/arch/arm/mach-s5pc100/clock.c +++ b/arch/arm/mach-s5pc100/clock.c @@ -273,24 +273,6 @@ static struct clksrc_clk clk_div_hdmi = { .reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 }, }; -static int s5pc100_epll_enable(struct clk *clk, int enable) -{ - unsigned int ctrlbit = clk->ctrlbit; - unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; - - if (enable) - __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); - else - __raw_writel(epll_con, S5P_EPLL_CON); - - return 0; -} - -static unsigned long s5pc100_epll_get_rate(struct clk *clk) -{ - return clk->rate; -} - static u32 epll_div[][4] = { { 32750000, 131, 3, 4 }, { 32768000, 131, 3, 4 }, @@ -341,13 +323,16 @@ static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate) __raw_writel(epll_con, S5P_EPLL_CON); + printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n", + clk->rate, rate); + clk->rate = rate; return 0; } static struct clk_ops s5pc100_epll_ops = { - .get_rate = s5pc100_epll_get_rate, + .get_rate = s5p_epll_get_rate, .set_rate = s5pc100_epll_set_rate, }; @@ -411,7 +396,7 @@ static int s5pc100_sclk1_ctrl(struct clk *clk, int enable) * recommended to keep the following clocks disabled until the driver requests * for enabling the clock. */ -static struct clk init_clocks_disable[] = { +static struct clk init_clocks_off[] = { { .name = "cssys", .id = -1, @@ -691,55 +676,55 @@ static struct clk init_clocks_disable[] = { }, { .name = "iis", .id = 0, - .parent = &clk_div_d1_bus.clk, + .parent = &clk_div_pclkd1.clk, .enable = s5pc100_d1_5_ctrl, .ctrlbit = (1 << 0), }, { .name = "iis", .id = 1, - .parent = &clk_div_d1_bus.clk, + .parent = &clk_div_pclkd1.clk, .enable = s5pc100_d1_5_ctrl, .ctrlbit = (1 << 1), }, { .name = "iis", .id = 2, - .parent = &clk_div_d1_bus.clk, + .parent = &clk_div_pclkd1.clk, .enable = s5pc100_d1_5_ctrl, .ctrlbit = (1 << 2), }, { .name = "ac97", .id = -1, - .parent = &clk_div_d1_bus.clk, + .parent = &clk_div_pclkd1.clk, .enable = s5pc100_d1_5_ctrl, .ctrlbit = (1 << 3), }, { .name = "pcm", .id = 0, - .parent = &clk_div_d1_bus.clk, + .parent = &clk_div_pclkd1.clk, .enable = s5pc100_d1_5_ctrl, .ctrlbit = (1 << 4), }, { .name = "pcm", .id = 1, - .parent = &clk_div_d1_bus.clk, + .parent = &clk_div_pclkd1.clk, .enable = s5pc100_d1_5_ctrl, .ctrlbit = (1 << 5), }, { .name = "spdif", .id = -1, - .parent = &clk_div_d1_bus.clk, + .parent = &clk_div_pclkd1.clk, .enable = s5pc100_d1_5_ctrl, .ctrlbit = (1 << 6), }, { .name = "adc", .id = -1, - .parent = &clk_div_d1_bus.clk, + .parent = &clk_div_pclkd1.clk, .enable = s5pc100_d1_5_ctrl, .ctrlbit = (1 << 7), }, { .name = "keypad", .id = -1, - .parent = &clk_div_d1_bus.clk, + .parent = &clk_div_pclkd1.clk, .enable = s5pc100_d1_5_ctrl, .ctrlbit = (1 << 8), }, { @@ -848,6 +833,18 @@ struct clksrc_sources clk_src_group3 = { .nr_sources = ARRAY_SIZE(clk_src_group3_list), }; +static struct clksrc_clk clk_sclk_audio0 = { + .clk = { + .name = "sclk_audio", + .id = 0, + .ctrlbit = (1 << 8), + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clk_src_group3, + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 }, +}; + static struct clk *clk_src_group4_list[] = { [0] = &clk_mout_epll.clk, [1] = &clk_div_mpll.clk, @@ -862,6 +859,18 @@ struct clksrc_sources clk_src_group4 = { .nr_sources = ARRAY_SIZE(clk_src_group4_list), }; +static struct clksrc_clk clk_sclk_audio1 = { + .clk = { + .name = "sclk_audio", + .id = 1, + .ctrlbit = (1 << 9), + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clk_src_group4, + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, +}; + static struct clk *clk_src_group5_list[] = { [0] = &clk_mout_epll.clk, [1] = &clk_div_mpll.clk, @@ -875,6 +884,18 @@ struct clksrc_sources clk_src_group5 = { .nr_sources = ARRAY_SIZE(clk_src_group5_list), }; +static struct clksrc_clk clk_sclk_audio2 = { + .clk = { + .name = "sclk_audio", + .id = 2, + .ctrlbit = (1 << 10), + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clk_src_group5, + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 }, +}; + static struct clk *clk_src_group6_list[] = { [0] = &s5p_clk_27m, [1] = &clk_vclk54m, @@ -944,6 +965,64 @@ struct clksrc_sources clk_src_pwi = { .nr_sources = ARRAY_SIZE(clk_src_pwi_list), }; +static struct clk *clk_sclk_spdif_list[] = { + [0] = &clk_sclk_audio0.clk, + [1] = &clk_sclk_audio1.clk, + [2] = &clk_sclk_audio2.clk, +}; + +struct clksrc_sources clk_src_sclk_spdif = { + .sources = clk_sclk_spdif_list, + .nr_sources = ARRAY_SIZE(clk_sclk_spdif_list), +}; + +static int s5pc100_spdif_set_rate(struct clk *clk, unsigned long rate) +{ + struct clk *pclk; + int ret; + + pclk = clk_get_parent(clk); + if (IS_ERR(pclk)) + return -EINVAL; + + ret = pclk->ops->set_rate(pclk, rate); + clk_put(pclk); + + return ret; +} + +static unsigned long s5pc100_spdif_get_rate(struct clk *clk) +{ + struct clk *pclk; + int rate; + + pclk = clk_get_parent(clk); + if (IS_ERR(pclk)) + return -EINVAL; + + rate = pclk->ops->get_rate(clk); + clk_put(pclk); + + return rate; +} + +static struct clk_ops s5pc100_sclk_spdif_ops = { + .set_rate = s5pc100_spdif_set_rate, + .get_rate = s5pc100_spdif_get_rate, +}; + +static struct clksrc_clk clk_sclk_spdif = { + .clk = { + .name = "sclk_spdif", + .id = -1, + .ctrlbit = (1 << 11), + .enable = s5pc100_sclk1_ctrl, + .ops = &s5pc100_sclk_spdif_ops, + }, + .sources = &clk_src_sclk_spdif, + .reg_src = { .reg = S5P_CLK_SRC3, .shift = 24, .size = 2 }, +}; + static struct clksrc_clk clksrcs[] = { { .clk = { @@ -999,39 +1078,6 @@ static struct clksrc_clk clksrcs[] = { }, .sources = &clk_src_group6, .reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 }, - }, { - .clk = { - .name = "sclk_audio", - .id = 0, - .ctrlbit = (1 << 8), - .enable = s5pc100_sclk1_ctrl, - - }, - .sources = &clk_src_group3, - .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 }, - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 }, - }, { - .clk = { - .name = "sclk_audio", - .id = 1, - .ctrlbit = (1 << 9), - .enable = s5pc100_sclk1_ctrl, - - }, - .sources = &clk_src_group4, - .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 }, - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, - }, { - .clk = { - .name = "sclk_audio", - .id = 2, - .ctrlbit = (1 << 10), - .enable = s5pc100_sclk1_ctrl, - - }, - .sources = &clk_src_group5, - .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 }, - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 }, }, { .clk = { .name = "sclk_lcd", @@ -1179,6 +1225,10 @@ static struct clksrc_clk *sysclks[] = { &clk_div_pclkd1, &clk_div_cam, &clk_div_hdmi, + &clk_sclk_audio0, + &clk_sclk_audio1, + &clk_sclk_audio2, + &clk_sclk_spdif, }; void __init_or_cpufreq s5pc100_setup_clocks(void) @@ -1196,7 +1246,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void) unsigned int ptr; /* Set S5PC100 functions for clk_fout_epll */ - clk_fout_epll.enable = s5pc100_epll_enable; + clk_fout_epll.enable = s5p_epll_enable; clk_fout_epll.ops = &s5pc100_epll_ops; printk(KERN_DEBUG "%s: registering clocks\n", __func__); @@ -1331,8 +1381,6 @@ static struct clk *clks[] __initdata = { void __init s5pc100_register_clocks(void) { - struct clk *clkp; - int ret; int ptr; s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); @@ -1343,16 +1391,8 @@ void __init s5pc100_register_clocks(void) s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); - 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); - } + s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_pwmclk_init(); }