⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sb_utils.c

📁 一个很好的嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  *********************************************************************    *  Broadcom Common Firmware Environment (CFE)    *      *  Silicon Backplane utilities       	File: sb_utils.c    *      *********************************************************************      *    *  Copyright 2003,2004    *  Broadcom Corporation. All rights reserved.    *      *  This software is furnished under license and may be used and     *  copied only in accordance with the following terms and     *  conditions.  Subject to these conditions, you may download,     *  copy, install, use, modify and distribute modified or unmodified     *  copies of this software in source and/or binary form.  No title     *  or ownership is transferred hereby.    *      *  1) Any source code used, modified or distributed must reproduce     *     and retain this copyright notice and list of conditions     *     as they appear in the source file.    *      *  2) No right is granted to use any trade name, trademark, or     *     logo of Broadcom Corporation.  The "Broadcom Corporation"     *     name may not be used to endorse or promote products derived     *     from this software without the prior written permission of     *     Broadcom Corporation.    *      *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR     *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT     *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN     *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES     *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY     *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR     *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF     *     THE POSSIBILITY OF SUCH DAMAGE.    ********************************************************************* *//* * Misc utility routines for accessing chip-specific features * of SiliconBackplane-based chips. */#include "cfe.h"#include "sbmips32.h"#include "sb_bp.h"#include "sb_utils.h"/* * Depending on the chip, either the Chip Common or the External * Interface core provides global state and control.  These are * mutually exclusive.  The corresponding registers in the two cores * have compatible formats, but the core base address and the register * offsets depend on the core. */#if defined(SB_EXTIF_BASE)#include "sb_extif.h"#elif defined(SB_CHIPC_BASE)#include "sb_chipc.h"#else#error "Neither EXT_IF nor CHIPC defined"#endif#define ASSERT(x) \  do { if (!(x)) printf("sb_utils: assertion failed\n"); } while (0)/* Sharable clock related definitions and calculations. *//* PLL types */#define PLL_NONE        0x00000000#define PLL_N3M         0x00010000#define PLL_N4M         0x00020000#define PLL_TYPE3       0x00030000#define PLL_TYPE4       0x00008000#define CC_CLOCK_BASE   24000000      /* Half the clock freq. *//* bcm4710 (N3M) Clock Control magic field values */#define CC_F6_2         0x02          /* A factor of 2 in */#define CC_F6_3         0x03          /*  6-bit fields like */#define CC_F6_4         0x05          /*  N1, M1 or M3 */#define CC_F6_5         0x09#define CC_F6_6         0x11#define CC_F6_7         0x21#define CC_F5_BIAS      5             /* 5-bit fields get this added */#define CC_MC_BYPASS    0x08#define CC_MC_M1        0x04#define CC_MC_M1M2      0x02#define CC_MC_M1M2M3    0x01#define CC_MC_M1M3      0x11/* bcm5836 (N4M) Clock Control magic field values (ditto) */#define	CC_T2_BIAS      2             /* N1, N2, M1 & M3 bias */#define	CC_T2M2_BIAS    3             /* M2 bias */#define	CC_T2MC_M1BYP   1#define	CC_T2MC_M2BYP   2#define	CC_T2MC_M3BYP 	4static inline uint32_tfactor6(uint32_t x){    switch (x) {	case CC_F6_2:	return 2;	case CC_F6_3:	return 3;	case CC_F6_4:	return 4;	case CC_F6_5:	return 5;	case CC_F6_6:	return 6;	case CC_F6_7:	return 7;	default:	return 0;	}}/* * Calculate the PLL output frequency given a set of clockcontrol * values (CC_CLOCK_BASE assumed fixed). */static uint32_tsb_clock_rate(uint32_t pll_type, uint32_t n, uint32_t m){    uint32_t n1, n2, clock, m1, m2, m3, mc;    n1 = G_CCN_N1(n);    n2 = G_CCN_N2(n);    if (pll_type == PLL_N3M) {	n1 = factor6(n1);	n2 += CC_F5_BIAS;	}    else if (pll_type == PLL_N4M) {	n1 += CC_T2_BIAS;	n2 += CC_T2_BIAS;	}    else if (pll_type == PLL_TYPE3) {	return 100000000;                 /* NB: for SB only */	}    else {        ASSERT(0);	return 0;	}    clock = CC_CLOCK_BASE * n1 * n2;    if (clock == 0)	return 0;    m1 = G_CCM_M1(m);    m2 = G_CCM_M2(m);    m3 = G_CCM_M3(m);    mc = G_CCM_MC(m);    if (pll_type == PLL_N3M) {	m1 = factor6(m1);	m2 += CC_F5_BIAS;	m3 = factor6(m3);	switch (mc) {	    case CC_MC_BYPASS:	return clock;	    case CC_MC_M1:	return clock / m1;	    case CC_MC_M1M2:	return clock / (m1 * m2);	    case CC_MC_M1M2M3:	return clock / (m1 * m2 * m3);	    case CC_MC_M1M3:	return clock / (m1 * m3);	    default:		return 0;	    }	}    else if (pll_type == PLL_N4M) {	m1 += CC_T2_BIAS;	m2 += CC_T2M2_BIAS;	m3 += CC_T2_BIAS;	if ((mc & CC_T2MC_M1BYP) == 0)	    clock /= m1;	if ((mc & CC_T2MC_M2BYP) == 0)	    clock /= m2;	if ((mc & CC_T2MC_M3BYP) == 0)	    clock /= m3;	return clock;	}    else {	ASSERT(0);	return 0;	}}#if defined(SB_EXTIF_BASE)/* Note: For EXTIF cores, the PLL must be N3M (aka TYPE1). *//* Access EXTIF "enumeration" space */#define READCSR(x)   \  (*(volatile uint32_t *)PHYS_TO_K1(SB_EXTIF_BASE+(x)))#define WRITECSR(x,v) \  (*(volatile uint32_t *)PHYS_TO_K1(SB_EXTIF_BASE+(x)) = (v))/* * Reset the entire chip and copy master clock registers to the slaves. */voidsb_chip_reset(void){    /* instant NMI from watchdog timeout after 1 tick */    WRITECSR(R_WATCHDOGCNTR, 1);    while (1)	;}/* Return the current speed the SB is running at */uint32_tsb_clock(void){    uint32_t clockcontrol_n, clockcontrol_sb;    clockcontrol_n = READCSR(R_CLOCKCONTROLN);    clockcontrol_sb = READCSR(R_CLOCKCONTROLSB);    return sb_clock_rate(PLL_N3M, clockcontrol_n, clockcontrol_sb);}/* Return the current speed the CPU is running at. */uint32_tsb_cpu_clock(void){    /* For EXTIF parts, cpu and backplane clocks are identical. */    return sb_clock();}/* Set the current speed of the SB to the desired rate (as closely as   possible) */intsb_setclock(uint32_t sb, uint32_t pci){    uint32_t old_n, old_sb, old_pci;    uint32_t new_n, new_sb, new_pci;    uint i;    static const struct {		uint32_t clock;		uint16_t n;		uint32_t sb;		uint32_t m33;		uint32_t m25;    } sb_clock_table[] = {	{  96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 },	/*  96.000 32.000 24.000 */	{ 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 },	/* 100.000 33.333 25.000 */	{ 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 },	/* 104.000 31.200 24.960 */	{ 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 },	/* 108.000 32.400 24.923 */	{ 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 },	/* 112.000 32.000 24.889 */	{ 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 },	/* 115.200 32.000 24.000 */	{ 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 },	/* 120.000 30.000 24.000 */	{ 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 },	/* 124.800 31.200 24.960 */	{ 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 },	/* 128.000 32.000 24.000 */	{ 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 },	/* 132.000 33.000 24.750 */	{ 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 },	/* 136.000 32.640 24.727 */	{ 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 },	/* 140.000 30.000 24.706 */	{ 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 },	/* 144.000 30.857 24.686 */	{ 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 },	/* 150.857 33.000 24.000 */	{ 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 },	/* 152.000 32.571 24.000 */	{ 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 },	/* 156.000 31.200 24.960 */	{ 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 },	/* 160.000 32.000 24.000 */	{ 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 },	/* 163.200 32.640 24.727 */	{ 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 },	/* 168.000 32.000 24.889 */	{ 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 },	/* 176.000 33.000 24.000 */    };    uint sb_clock_entries = sizeof(sb_clock_table)/sizeof(sb_clock_table[0]);    /* Store the current clock reg values */    old_n = READCSR(R_CLOCKCONTROLN);    old_sb = READCSR(R_CLOCKCONTROLSB);    old_pci = READCSR(R_CLOCKCONTROLPCI);    /* keep current pci clock if not specified */    if (pci == 0) {	pci = sb_clock_rate(PLL_N3M, old_n, old_pci);	}    pci = (pci <= 25000000) ? 25000000 : 33000000;    /* Find a supported clock setting no faster than the request. */    if (sb < sb_clock_table[0].clock)	return 0;    for (i = sb_clock_entries-1; i > 0; i--) {	if (sb >= sb_clock_table[i].clock)	    break;	}    new_n = sb_clock_table[i].n;    new_sb = sb_clock_table[i].sb;    new_pci = pci == 25000000 ? sb_clock_table[i].m25 : sb_clock_table[i].m33;    if (old_n != new_n || old_sb != new_sb || old_pci != new_pci) {	/* Reset to install the new clocks if any changed. */	WRITECSR(R_CLOCKCONTROLN, new_n);	WRITECSR(R_CLOCKCONTROLSB, new_sb);	WRITECSR(R_CLOCKCONTROLPCI, new_pci);	/* Clock MII at 25 MHz. */	WRITECSR(R_CLOCKCONTROLMII, sb_clock_table[i].m25);	/* No return from chip reset. */	sb_chip_reset();	}    return 1;}#elif defined(SB_CHIPC_BASE)/* Access CHIPC "enumeration" space */#define READCSR(x)    \  (*(volatile uint32_t *)PHYS_TO_K1(SB_CHIPC_BASE+(x)))#define WRITECSR(x,v) \  (*(volatile uint32_t *)PHYS_TO_K1(SB_CHIPC_BASE+(x)) = (v))voidsb_chip_reset(void){    /* instant NMI from watchdog timeout after 1 tick */    WRITECSR(R_WATCHDOGCNTR, 1);    while (1)   /* Use 'wait' instead? */	;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -