arm_clk:在sysclk後有乙個hclkpll用於將sysclk轉換成arm_clk。arm_clk用於armcpu,mssdclk。在暫存器hclk_ctrl中,arm_clk將會被分頻成hclk,pclk和ddram_clk。
hclk:ahb匯流排時鐘。用於ahb矩陣和usbahb、ahb從機、fab從機和apb從機
p_clk:外設時鐘。
clk48mhz:usb48mhz時鐘——基於osc_clk。
ddram_clk:ddr sdram時鐘
mssdclk:sd卡時鐘。
二、clock.c中有關函式介紹
clk結構體定義
struct clk {
structlist_head node;
struct module*owner;
const char*name; /* clock name */
struct clk*parent; /* parent clock */
u32 rate; /* rate in hz for the clock (0= disabled) */
u32 flags; /* setup flags */
s8 usecount; /* number of users of thisclock */
/* requiredfunctions per clock */
int(*set_rate) (struct clk *, u32);
u32(*round_rate) (struct clk *, u32);
int (*enable)(struct clk *clk, int);
/* optionalfunctions per clock */
int(*set_parent) (struct clk * clk, struct clk * parent);
u32(*get_rate) (struct clk *clk);
/* registerand mask for enablings/disabling the clock, only
used when the clk_flag_st_enab flag is set*/
u32enable_reg; /* register toenable and disable associated clock */
u32enable_mask; /* or mask forenable, and ~mask for disable */
static void clk_upate_children(struct clk *clk)
local_update_armpll_rate();
local_update_usbpll_rate();
這個函式作用就是根據輸入的系統時鐘sysclk和相關暫存器的設定來獲得clk_armpll.rate和clk_usbpll.rate 的成員值。當然後面還有函式會根據這個值去設定相關暫存器。
local_update_armpll_rate()和local_update_usbpll_rate()實現過程相仿。只追蹤第乙個函式的實現過程。
static void local_update_armpll_rate(void)
u32 clkin,pllreg;
/* get pllinput clock rate */
獲得系統時鐘速率
clkin =clk_armpll.parent->rate;
/* get armhclkpll register */
pllreg =__raw_readl(clkpwr_hclkpll_ctrl(clkpwr_iobase)) & 0x1ffff;
根據系統時鐘速度,和乙個配置項獲得arm_clk的速率。
clk_armpll.rate= local_clk_get_pllrate_from_reg(clkin, pllreg);
static u32 local_clk_find_pll_cfg(u32 pllin_freq,
u32 target_freq,
clkpwr_hclk_pll_setup_t *pllsetup)
這個函式作用是根據目前的pllin_freq和target_freq為設定pllsetup 。即如果按照pllsetup的項去配置相關暫存器,即可實現由pllin_freq 到target_freq的目標。而函式
static u32local_clk_hclkpll_setup(clkpwr_hclk_pll_setup_t *phclkpllsetup)就是做這個事情的。
static int local_armpll_set_rate(struct clk *clk, u32rate)封裝上面介紹的兩個函式。這函式很簡單,給定乙個時鐘,然後再給定乙個要設定的速率。就能實現目標。不看其具體的實現就知道,它先要根據rate和clk->parent.rate為自己找到乙個合適的pllsetup,然後再將任務傳給local_clk_hclkpll_setup()去實現。
static struct clk *chip_clks = {
&osc_32khz,
&osc_pll397,
&osc_main,
&clk_sys,
&clk_armpll,
&clk_hclk,
&clk_pclk,
&clk_usbpll,
&clk_timer0,
&clk_timer1,
&clk_timer2,
&clk_timer3,
&clk_vfp9,
&clk_dma,
#if defined (config_lpc32xx_watchdog)
&clk_wdt,
#endif
#if defined (config_mach_lpc32xx_uart3_enable)
&clk_uart3,
#endif
#if defined (config_mach_lpc32xx_uart4_enable)
&clk_uart4,
#endif
#if defined (config_mach_lpc32xx_uart5_enable)
&clk_uart5,
#endif
#if defined (config_mach_lpc32xx_uart6_enable)
&clk_uart6,
#endif
#if defined (config_mach_lpc32xx_i2c0_enable)
&clk_i2c0,
#endif
#if defined (config_mach_lpc32xx_i2c1_enable)
&clk_i2c1,
#endif
#if defined (config_mach_lpc32xx_usbotg_i2c_enable)
&clk_i2c2,
#endif
#if defined(config_spi_lpc32xx)
#if defined(config_mach_lpc32xx_ssp0_enable)
&clk_ssp0,
#endif
#if defined(config_mach_lpc32xx_ssp1_enable)
&clk_ssp1,
#endif
#endif
#if defined(config_keyboard_lpc32xx)
&clk_kscan,
#endif
#if defined(config_mtd_nand_slc_lpc32xx)
&clk_nand,
#endif
#if defined(config_snd_lpc3***_soc_i2s)
&clk_i2s0,
&clk_i2s1,
#endif
#if defined (config_touchscreen_lpc32xx)
&clk_tsc,
#endif
#if defined (config_mmc_armmmci)
&clk_mmc,
#endif
#if defined (config_lpc32xx_mii)
&clk_net,
#endif
#if defined (config_fb_armclcd)
&clk_lcd,
#endif
#if defined (config_usb_gadget_lpc32xx)
&clk_usbd,
#endif
這個結構體列出了lpc3250可能用到的所有時鐘,而時鐘的具體實現就是利用前面介紹的函式。
struct clk *local_clk_get(struct device *dev, const char*id)這個函式一般是會在id的位置傳入乙個時鐘名稱。然後該函式返回這個時鐘的結構體。第乙個引數沒什麼用處。
static int local_clk_enable(struct clk *clk)這個函式只是根據具體的時鐘,來呼叫clk->enable成員方法。
struct clk *clk_get(struct device *dev, const char *id)是對struct clk *local_clk_get()函式的封裝。只是中間新增了這麼一項:在獲取時鐘結構體期間禁能了中斷
int clk_is_sysclk_mainosc(void)判斷系統時鐘是否是從osc_clk(主振盪器時鐘)獲取。
最後的int __initclk_init(void)函式,分別註冊了lpc3250的時鐘,確定了系統時鐘源。增加引用計數。雖然這個函式將時鐘註冊進了linux系統,但是這配置都還是預設的配置。arm_clk和osc_clk還是一樣的。所以時鐘在具體使用的時候,還要再具體配置。
lpc1768的時鐘樹梳理和小結
可以看到,外部晶振我使用的是8mhz,這個在配置檔案的時候需要設定。不然keil計算就會出現錯誤。看到cclk是100mhz,因為這個晶元最快是100mhz的主頻,usb不能超過48,一般設定為48,可以低於48,但是也有限制,幾個pll都是有最大最小值的限制的,這個在參考手冊中有說明的,因此放大縮...
STM32的時鐘系統介紹
stm32 有5個時鐘源 hsi hse lsi lse pll hsi是高速內部時鐘,rc振盪器,頻率約為8mhz,精度不高。hse是高速外部時鐘,接外部時鐘源,頻率範圍為4mhz 16mhz。lsi是低速內部時鐘,rc振盪器,頻率約為40khz,提供低功耗時鐘。lse是低速外部時鐘,接頻率為32...
TMS320F28335的時鐘介紹
tms320f28335的時鐘介紹 tms320f28335上有乙個基於pll電路的片上時鐘模組,為cpu及外設提供時鐘有兩種方式 一種是用外部的時鐘源,將其連線到x1引腳上或者xclkin引腳上,x2接地 另一種是使用振盪器產生時鐘,用30mhz的晶體和兩個20pf的電容組成的電路分別連線到x1和...