📄 clkinit.c
字号:
/* * (C) Copyright 2002 * Custom IDEAS, Inc. <www.cideas.com> * Jon Diekema <diekema@cideas.com> * * See file CREDITS for list of people who contributed to this * project. * * 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, or (at your option) any later version. * * 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 <common.h>#include <ioports.h>#include <mpc8260.h>#include <asm/cpm_8260.h>#include <configs/sacsng.h>#include "clkinit.h"int Daq64xSampling = 0;void Daq_BRG_Reset(uint brg){ volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile uint *brg_ptr; brg_ptr = (uint *)&immr->im_brgc1; if (brg >= 5) { brg_ptr = (uint *)&immr->im_brgc5; brg -= 4; } brg_ptr += brg; *brg_ptr |= CPM_BRG_RST; *brg_ptr &= ~CPM_BRG_RST;}void Daq_BRG_Disable(uint brg){ volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile uint *brg_ptr; brg_ptr = (uint *)&immr->im_brgc1; if (brg >= 5) { brg_ptr = (uint *)&immr->im_brgc5; brg -= 4; } brg_ptr += brg; *brg_ptr &= ~CPM_BRG_EN;}void Daq_BRG_Enable(uint brg){ volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile uint *brg_ptr; brg_ptr = (uint *)&immr->im_brgc1; if (brg >= 5) { brg_ptr = (uint *)&immr->im_brgc5; brg -= 4; } brg_ptr += brg; *brg_ptr |= CPM_BRG_EN;}uint Daq_BRG_Get_Div16(uint brg){ volatile immap_t *immr = (immap_t *)CFG_IMMR; uint *brg_ptr; brg_ptr = (uint *)&immr->im_brgc1; if (brg >= 5) { brg_ptr = (uint *)&immr->im_brgc5; brg -= 4; } brg_ptr += brg; if (*brg_ptr & CPM_BRG_DIV16) { /* DIV16 active */ return (TRUE); } else { /* DIV16 inactive */ return (FALSE); }}void Daq_BRG_Set_Div16(uint brg, uint div16){ volatile immap_t *immr = (immap_t *)CFG_IMMR; uint *brg_ptr; brg_ptr = (uint *)&immr->im_brgc1; if (brg >= 5) { brg_ptr = (uint *)&immr->im_brgc5; brg -= 4; } brg_ptr += brg; if (div16) { /* DIV16 active */ *brg_ptr |= CPM_BRG_DIV16; } else { /* DIV16 inactive */ *brg_ptr &= ~CPM_BRG_DIV16; }}uint Daq_BRG_Get_Count(uint brg){ volatile immap_t *immr = (immap_t *)CFG_IMMR; uint *brg_ptr; uint brg_cnt; brg_ptr = (uint *)&immr->im_brgc1; if (brg >= 5) { brg_ptr = (uint *)&immr->im_brgc5; brg -= 4; } brg_ptr += brg; /* Get the clock divider * * Note: A clock divider of 0 means divide by 1, * therefore we need to add 1 to the count. */ brg_cnt = (*brg_ptr & CPM_BRG_CD_MASK) >> CPM_BRG_DIV16_SHIFT; brg_cnt++; if (*brg_ptr & CPM_BRG_DIV16) { brg_cnt *= 16; } return (brg_cnt);}void Daq_BRG_Set_Count(uint brg, uint brg_cnt){ volatile immap_t *immr = (immap_t *)CFG_IMMR; uint *brg_ptr; brg_ptr = (uint *)&immr->im_brgc1; if (brg >= 5) { brg_ptr = (uint *)&immr->im_brgc5; brg -= 4; } brg_ptr += brg; /* * Note: A clock divider of 0 means divide by 1, * therefore we need to subtract 1 from the count. */ if (brg_cnt > 4096) { /* Prescale = Divide by 16 */ *brg_ptr = (*brg_ptr & ~CPM_BRG_CD_MASK) | (((brg_cnt / 16) - 1) << CPM_BRG_DIV16_SHIFT); *brg_ptr |= CPM_BRG_DIV16; } else { /* Prescale = Divide by 1 */ *brg_ptr = (*brg_ptr & ~CPM_BRG_CD_MASK) | ((brg_cnt - 1) << CPM_BRG_DIV16_SHIFT); *brg_ptr &= ~CPM_BRG_DIV16; }}uint Daq_BRG_Get_ExtClk(uint brg){ volatile immap_t *immr = (immap_t *)CFG_IMMR; uint *brg_ptr; brg_ptr = (uint *)&immr->im_brgc1; if (brg >= 5) { brg_ptr = (uint *)&immr->im_brgc5; brg -= 4; } brg_ptr += brg; return ((*brg_ptr & CPM_BRG_EXTC_MASK) >> CPM_BRG_EXTC_SHIFT);}char* Daq_BRG_Get_ExtClk_Description(uint brg){ uint extc; extc = Daq_BRG_Get_ExtClk(brg); switch (brg + 1) { case 1: case 2: case 5: case 6: { switch (extc) { case 0: { return ("BRG_INT"); } case 1: { return ("CLK3"); } case 2: { return ("CLK5"); } } return ("??1245??"); } case 3: case 4: case 7: case 8: { switch (extc) { case 0: { return ("BRG_INT"); } case 1: { return ("CLK9"); } case 2: { return ("CLK15"); } } return ("??3478??"); } } return ("??9876??");}void Daq_BRG_Set_ExtClk(uint brg, uint extc){ volatile immap_t *immr = (immap_t *)CFG_IMMR; uint *brg_ptr; brg_ptr = (uint *)&immr->im_brgc1; if (brg >= 5) { brg_ptr = (uint *)&immr->im_brgc5; brg -= 4; } brg_ptr += brg; *brg_ptr = (*brg_ptr & ~CPM_BRG_EXTC_MASK) | ((extc << CPM_BRG_EXTC_SHIFT) & CPM_BRG_EXTC_MASK);}uint Daq_BRG_Rate(uint brg){ DECLARE_GLOBAL_DATA_PTR; volatile immap_t *immr = (immap_t *)CFG_IMMR; uint *brg_ptr; uint brg_cnt; uint brg_freq = 0; brg_ptr = (uint *)&immr->im_brgc1; brg_ptr += brg; if (brg >= 5) { brg_ptr = (uint *)&immr->im_brgc5; brg_ptr += (brg - 4); } brg_cnt = Daq_BRG_Get_Count(brg); switch (Daq_BRG_Get_ExtClk(brg)) { case CPM_BRG_EXTC_CLK3: case CPM_BRG_EXTC_CLK5: { brg_freq = brg_cnt; break; } default: { brg_freq = (uint)BRG_INT_CLK / brg_cnt; } } return (brg_freq);}uint Daq_Get_SampleRate(void){ /* * Read the BRG's to return the actual sample rate. */ return (Daq_BRG_Rate(MCLK_BRG) / (MCLK_DIVISOR * SCLK_DIVISOR));}void Daq_Init_Clocks(int sample_rate, int sample_64x){ DECLARE_GLOBAL_DATA_PTR; volatile ioport_t *iopa = ioport_addr((immap_t *)CFG_IMMR, 0 /* port A */); uint mclk_divisor; /* MCLK divisor */ int flag; /* Interrupt state */ /* Save off the clocking data */ Daq64xSampling = sample_64x; /* * Limit the sample rate to some sensible values. */ if (sample_rate > MAX_64x_SAMPLE_RATE) { sample_rate = MAX_64x_SAMPLE_RATE; } if (sample_rate < MIN_SAMPLE_RATE) { sample_rate = MIN_SAMPLE_RATE; } /* * Initialize the MCLK/SCLK/LRCLK baud rate generators. */ /* Setup MCLK */ Daq_BRG_Set_ExtClk(MCLK_BRG, CPM_BRG_EXTC_BRGCLK); /* Setup SCLK */# ifdef RUN_SCLK_ON_BRG_INT Daq_BRG_Set_ExtClk(SCLK_BRG, CPM_BRG_EXTC_BRGCLK);# else Daq_BRG_Set_ExtClk(SCLK_BRG, CPM_BRG_EXTC_CLK9);# endif /* Setup LRCLK */# ifdef RUN_LRCLK_ON_BRG_INT Daq_BRG_Set_ExtClk(LRCLK_BRG, CPM_BRG_EXTC_BRGCLK);# else Daq_BRG_Set_ExtClk(LRCLK_BRG, CPM_BRG_EXTC_CLK5);# endif /* * Dynamically adjust MCLK based on the new sample rate. */ /* Compute the divisors */ mclk_divisor = BRG_INT_CLK / (sample_rate * MCLK_DIVISOR * SCLK_DIVISOR); /* * Disable interrupt and save the current state */ flag = disable_interrupts(); /* Setup MCLK */ Daq_BRG_Set_Count(MCLK_BRG, mclk_divisor); /* Setup SCLK */# ifdef RUN_SCLK_ON_BRG_INT Daq_BRG_Set_Count(SCLK_BRG, mclk_divisor * MCLK_DIVISOR);# else Daq_BRG_Set_Count(SCLK_BRG, MCLK_DIVISOR);# endif# ifdef RUN_LRCLK_ON_BRG_INT Daq_BRG_Set_Count(LRCLK_BRG, mclk_divisor * MCLK_DIVISOR * SCLK_DIVISOR);# else Daq_BRG_Set_Count(LRCLK_BRG, SCLK_DIVISOR);# endif /* * Restore the Interrupt state */ if (flag) { enable_interrupts(); } /* Enable the clock drivers */ iopa->pdat &= ~SLRCLK_EN_MASK;}void Daq_Stop_Clocks(void){#ifdef TIGHTEN_UP_BRG_TIMING volatile immap_t *immr = (immap_t *)CFG_IMMR; register uint mclk_brg; /* MCLK BRG value */ register uint sclk_brg; /* SCLK BRG value */ register uint lrclk_brg; /* LRCLK BRG value */ unsigned long flag; /* Interrupt flags */#endif# ifdef TIGHTEN_UP_BRG_TIMING /* * Obtain MCLK BRG reset/disabled value */# if (MCLK_BRG == 0) mclk_brg = (*IM_BRGC1 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (MCLK_BRG == 1) mclk_brg = (*IM_BRGC2 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (MCLK_BRG == 2) mclk_brg = (*IM_BRGC3 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (MCLK_BRG == 3) mclk_brg = (*IM_BRGC4 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (MCLK_BRG == 4) mclk_brg = (*IM_BRGC5 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (MCLK_BRG == 5) mclk_brg = (*IM_BRGC6 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (MCLK_BRG == 6) mclk_brg = (*IM_BRGC7 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (MCLK_BRG == 7) mclk_brg = (*IM_BRGC8 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif /* * Obtain SCLK BRG reset/disabled value */# if (SCLK_BRG == 0) sclk_brg = (*IM_BRGC1 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (SCLK_BRG == 1) sclk_brg = (*IM_BRGC2 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (SCLK_BRG == 2) sclk_brg = (*IM_BRGC3 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (SCLK_BRG == 3) sclk_brg = (*IM_BRGC4 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (SCLK_BRG == 4) sclk_brg = (*IM_BRGC5 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (SCLK_BRG == 5) sclk_brg = (*IM_BRGC6 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (SCLK_BRG == 6) sclk_brg = (*IM_BRGC7 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (SCLK_BRG == 7) sclk_brg = (*IM_BRGC8 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif /* * Obtain LRCLK BRG reset/disabled value */# if (LRCLK_BRG == 0) lrclk_brg = (*IM_BRGC1 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (LRCLK_BRG == 1) lrclk_brg = (*IM_BRGC2 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (LRCLK_BRG == 2) lrclk_brg = (*IM_BRGC3 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (LRCLK_BRG == 3) lrclk_brg = (*IM_BRGC4 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (LRCLK_BRG == 4) lrclk_brg = (*IM_BRGC5 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (LRCLK_BRG == 5) lrclk_brg = (*IM_BRGC6 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (LRCLK_BRG == 6) lrclk_brg = (*IM_BRGC7 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif# if (LRCLK_BRG == 7) lrclk_brg = (*IM_BRGC8 | CPM_BRG_RST) & ~CPM_BRG_EN;# endif /* * Disable interrupt and save the current state */ flag = disable_interrupts(); /* * Set reset on MCLK BRG */# if (MCLK_BRG == 0) *IM_BRGC1 = mclk_brg;# endif# if (MCLK_BRG == 1) *IM_BRGC2 = mclk_brg;# endif# if (MCLK_BRG == 2) *IM_BRGC3 = mclk_brg;# endif# if (MCLK_BRG == 3) *IM_BRGC4 = mclk_brg;# endif# if (MCLK_BRG == 4) *IM_BRGC5 = mclk_brg;# endif# if (MCLK_BRG == 5) *IM_BRGC6 = mclk_brg;# endif# if (MCLK_BRG == 6) *IM_BRGC7 = mclk_brg;# endif# if (MCLK_BRG == 7) *IM_BRGC8 = mclk_brg;# endif /* * Set reset on SCLK BRG */# if (SCLK_BRG == 0) *IM_BRGC1 = sclk_brg;# endif# if (SCLK_BRG == 1) *IM_BRGC2 = sclk_brg;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -