Path: blob/master/arch/arm/mach-omap2/clkt2xxx_apll.c
10817 views
/*1* OMAP2xxx APLL clock control functions2*3* Copyright (C) 2005-2008 Texas Instruments, Inc.4* Copyright (C) 2004-2010 Nokia Corporation5*6* Contacts:7* Richard Woodruff <[email protected]>8* Paul Walmsley9*10* Based on earlier work by Tuukka Tikkanen, Tony Lindgren,11* Gordon McNutt and RidgeRun, Inc.12*13* This program is free software; you can redistribute it and/or modify14* it under the terms of the GNU General Public License version 2 as15* published by the Free Software Foundation.16*/17#undef DEBUG1819#include <linux/kernel.h>20#include <linux/clk.h>21#include <linux/io.h>2223#include <plat/clock.h>24#include <plat/prcm.h>2526#include "clock.h"27#include "clock2xxx.h"28#include "cm2xxx_3xxx.h"29#include "cm-regbits-24xx.h"3031/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */32#define EN_APLL_STOPPED 033#define EN_APLL_LOCKED 33435/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */36#define APLLS_CLKIN_19_2MHZ 037#define APLLS_CLKIN_13MHZ 238#define APLLS_CLKIN_12MHZ 33940void __iomem *cm_idlest_pll;4142/* Private functions */4344/* Enable an APLL if off */45static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)46{47u32 cval, apll_mask;4849apll_mask = EN_APLL_LOCKED << clk->enable_bit;5051cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);5253if ((cval & apll_mask) == apll_mask)54return 0; /* apll already enabled */5556cval &= ~apll_mask;57cval |= apll_mask;58omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);5960omap2_cm_wait_idlest(cm_idlest_pll, status_mask,61OMAP24XX_CM_IDLEST_VAL, clk->name);6263/*64* REVISIT: Should we return an error code if omap2_wait_clock_ready()65* fails?66*/67return 0;68}6970static int omap2_clk_apll96_enable(struct clk *clk)71{72return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL_MASK);73}7475static int omap2_clk_apll54_enable(struct clk *clk)76{77return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL_MASK);78}7980static void _apll96_allow_idle(struct clk *clk)81{82omap2xxx_cm_set_apll96_auto_low_power_stop();83}8485static void _apll96_deny_idle(struct clk *clk)86{87omap2xxx_cm_set_apll96_disable_autoidle();88}8990static void _apll54_allow_idle(struct clk *clk)91{92omap2xxx_cm_set_apll54_auto_low_power_stop();93}9495static void _apll54_deny_idle(struct clk *clk)96{97omap2xxx_cm_set_apll54_disable_autoidle();98}99100/* Stop APLL */101static void omap2_clk_apll_disable(struct clk *clk)102{103u32 cval;104105cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);106cval &= ~(EN_APLL_LOCKED << clk->enable_bit);107omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);108}109110/* Public data */111112const struct clkops clkops_apll96 = {113.enable = omap2_clk_apll96_enable,114.disable = omap2_clk_apll_disable,115.allow_idle = _apll96_allow_idle,116.deny_idle = _apll96_deny_idle,117};118119const struct clkops clkops_apll54 = {120.enable = omap2_clk_apll54_enable,121.disable = omap2_clk_apll_disable,122.allow_idle = _apll54_allow_idle,123.deny_idle = _apll54_deny_idle,124};125126/* Public functions */127128u32 omap2xxx_get_apll_clkin(void)129{130u32 aplls, srate = 0;131132aplls = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);133aplls &= OMAP24XX_APLLS_CLKIN_MASK;134aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;135136if (aplls == APLLS_CLKIN_19_2MHZ)137srate = 19200000;138else if (aplls == APLLS_CLKIN_13MHZ)139srate = 13000000;140else if (aplls == APLLS_CLKIN_12MHZ)141srate = 12000000;142143return srate;144}145146147148