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

📄 em86xxapi.c

📁 1. 8623L平台
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************** Copyright (c) 2002-2007 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the EM86XX boot loader *//* * em86xxapi.c * * by Ho Lee 01/23/2002 */#include "config.h"#include "uart.h"#include "io.h"#include "hardware.h"#include "irqs.h"#include "util.h"#include "vsprintf.h"#include "em86xxapi.h"extern int board_init(void);//// Intialization//int em86xx_init(void){#if defined(CONFIG_ARCH_TANGO15) && (CONFIG_ARCH_TANGO15_REV > 1) && !defined(CONFIG_ENABLE_NETWORK_TANGO15)    unsigned long sys_gpio_dir = (unsigned long)(((unsigned long long)DEFAULT_GPIO_DIR) & 0xffff);    unsigned long sys_gpio_out = (unsigned long)(((unsigned long long)DEFAULT_GPIO_OUTPUT) & 0xffff);    unsigned long eth_gpio_dir = (unsigned long)((((unsigned long long)DEFAULT_GPIO_DIR) >> 16) & 0x1ffff);    unsigned long eth_gpio_out = (unsigned long)((((unsigned long long)DEFAULT_GPIO_OUTPUT) >> 16) & 0x1ffff);#endif    // setup remap register    __raw_writel(DRAMBASE, REG_BASE_CPU + CPU_remap);    // setup peripheral bus interface    // CS0 : IDE, 16/16 (addr/data)    // CS1 :     // CS2 : parallel flash / FlexROM, 24/8    // CS3 :     // default :     __raw_writel(DEFAULT_PB_DEFAULT_TIMING, REG_BASE_HOST + PB_default_timing);    __raw_writel(DEFAULT_PB_CS_CONFIG, REG_BASE_HOST + PB_cs_config);    // timing 0 :     __raw_writel(DEFAULT_PB_TIMING0, REG_BASE_HOST + PB_timing0);    __raw_writel(DEFAULT_PB_USE_TIMING0, REG_BASE_HOST + PB_use_timing0);    // timing 1 :     __raw_writel(DEFAULT_PB_TIMING1, REG_BASE_HOST + PB_timing1);    __raw_writel(DEFAULT_PB_USE_TIMING1, REG_BASE_HOST + PB_use_timing1);    // timing 2 :     __raw_writel(DEFAULT_PB_TIMING2, REG_BASE_HOST + PB_timing2);    __raw_writel(DEFAULT_PB_USE_TIMING2, REG_BASE_HOST + PB_use_timing2);    // timing 3 :     __raw_writel(DEFAULT_PB_TIMING3, REG_BASE_HOST + PB_timing3);    __raw_writel(DEFAULT_PB_USE_TIMING3, REG_BASE_HOST + PB_use_timing3);    // timing 4 :     __raw_writel(DEFAULT_PB_TIMING4, REG_BASE_HOST + PB_timing4);    __raw_writel(DEFAULT_PB_USE_TIMING4, REG_BASE_HOST + PB_use_timing4);    // timing 5 :     __raw_writel(DEFAULT_PB_TIMING5, REG_BASE_HOST + PB_timing5);    __raw_writel(DEFAULT_PB_USE_TIMING5, REG_BASE_HOST + PB_use_timing5);    // setup mapping between GPIO and IRQ    __raw_writel(DEFAULT_IRQ_GPIOMAP, REG_BASE_SYSTEM + SYS_gpio_int);    // setup default GPIO pins direction and value (if set to output)    __raw_writel(0xffff0000 | (DEFAULT_GPIO_DIR & 0xffff), REG_BASE_SYSTEM + SYS_gpio_dir);#if defined(CONFIG_ARCH_TANGO15) && (CONFIG_ARCH_TANGO15_REV > 1) && !defined(CONFIG_ENABLE_NETWORK_TANGO15)    // Put ETH pins in gpio mode (17 pins: enumerated as 16-32)    __raw_writel(0x1ffff, REG_BASE_HOST + ETH_gpio_mask1);    __raw_writel(0x1ffff, REG_BASE_HOST + ETH_gpio_mode1);    if (sys_gpio_dir != 0) /* Some pins are set to output */    	__raw_writel((sys_gpio_dir << 16) | sys_gpio_out, REG_BASE_SYSTEM + SYS_gpio_data);    if (eth_gpio_dir != 0) {        __raw_writel(eth_gpio_dir, REG_BASE_HOST + ETH_gpio_mask1);        __raw_writel(eth_gpio_dir, REG_BASE_HOST + ETH_gpio_dir1);        __raw_writel(eth_gpio_dir, REG_BASE_HOST + ETH_gpio_mask1);        __raw_writel(eth_gpio_dir & eth_gpio_out, REG_BASE_HOST + ETH_gpio_data1);    }#else    if (DEFAULT_GPIO_DIR != 0) /* Some pins are set to output */    	__raw_writel((DEFAULT_GPIO_DIR << 16) | DEFAULT_GPIO_OUTPUT, REG_BASE_SYSTEM + SYS_gpio_data);#endif#ifdef CONFIG_ARCH_TANGO#ifdef CONFIG_ENABLE_IDE#ifdef CONFIG_ENABLE_IDE_ISA    // IDE configuration compatible with Mambo    // IDE pins are tristated    __raw_writel(0x10800, REG_BASE_HOST + IDECTRL_pri_idectl);#else    // Enable bus master IDE interface    __raw_writel(0x08400, REG_BASE_HOST + IDECTRL_pri_idectl);#endif#endif#if defined(DEFAULT_CD0_FREQ) || defined(DEFAULT_CD1_FREQ) || defined(DEFAULT_CD2_FREQ) || defined(DEFAULT_CD3_FREQ)    // Setup clean dividers    em86xx_set_SYS_clean_dividers();#endif#endif /* CONFIG_ARCH_TANGO */        // Calling board specific initialization routine.    board_init();    return 0;}//// Clock//unsigned long em86xx_getclock(void){    unsigned int reg, mult, div;    unsigned long clock;    reg = __raw_readl(REG_BASE_SYSTEM + SYS_clkgen0_pll);    mult = reg & 0x03ff;    div = (reg >> 16) & 0x003f;    // clock = CPU_CLK_INPUT * (MULT + 2) / (DIV + 2)    clock = idivide(EM86XX_EXT_CLOCK, div + 2);    clock = clock * (mult + 2);    return clock;}unsigned int em86xx_getclockmhz(void){    unsigned long clock = em86xx_getclock();    clock /= 1000000;    clock >>= 1;    return (unsigned int) clock;}// MULT =  9, DIV = 1 =>  49.5 MHz// MULT = 20, DIV = 1 =>  99.0 MHz// MULT = 31, DIV = 1 => 148.5 MHz// MULT = 42, DIV = 1 => 198.0 MHzvoid em86xx_setclockmhz(int clock){    unsigned int reg, mult, div;    // clock = CPU_CLK_INPUT * (MULT + 2) / (DIV + 2)    // MULT = clock * (DIV + 2) / CPU_CLK_INPUT - 2    // fix DIV as 1        if (clock > 100)        div = 1;    else         div = 3;    mult = clock * (div + 2);    mult <<= 1;    mult /= (EM86XX_EXT_CLOCK / 1000000);    mult -= 2;    reg = __raw_readl(REG_BASE_SYSTEM + SYS_clkgen0_pll);    reg &= ~0x003f00ff;    reg |= ((mult) | (div << 16));    __raw_writel(reg, REG_BASE_SYSTEM + SYS_clkgen0_pll);}#ifdef CONFIG_ARCH_TANGO#if defined(DEFAULT_CD0_FREQ) || defined(DEFAULT_CD1_FREQ) || defined(DEFAULT_CD2_FREQ) || defined(DEFAULT_CD3_FREQ)/*****************************************************************************//*                                                                           *//*   Sigma Desgin 1-5-2005                                                   *//*   Set the  Clean Dividers Registers for TANGO 1.5 and 2.0 to a know state *//*   Sys_Cleandiv  will always be defined as 		      SYSClk         *//*					         Fout =-----------------     *//*						      2 + divider*2^(-27)    *//*The below function finds the correct divider given Fout in .config<board>  *//*****************************************************************************/unsigned int em86xx_calculate_SYS_clean_dividers(unsigned int freq){#if 0	unsigned int constant1 = 0x8000000;	unsigned int constant2 = 0x10000000;	unsigned int SYSClk, divider, num;		SYSClk = em86xx_getclockmhz();	num = constant1 * SYSClk;	divider = idivide(num, freq) - constant2;	return divider;#else	unsigned int SYSclk = em86xx_getclockmhz() * 1000000;	return((idivide((SYSclk << 2), (freq >> 12)) - (2 << 14)) << 13);#endif}void em86xx_set_SYS_clean_dividers(void){	unsigned long reg;#ifdef DEFAULT_CD0_FREQ	reg = em86xx_calculate_SYS_clean_dividers(DEFAULT_CD0_FREQ);	__raw_writel(reg, REG_BASE_SYSTEM + SYS_cleandiv0_div);#endif#ifdef DEFAULT_CD1_FREQ	reg = em86xx_calculate_SYS_clean_dividers(DEFAULT_CD1_FREQ);	__raw_writel(reg, REG_BASE_SYSTEM + SYS_cleandiv1_div);#endif#ifdef DEFAULT_CD2_FREQ	reg = em86xx_calculate_SYS_clean_dividers(DEFAULT_CD2_FREQ);	__raw_writel(reg, REG_BASE_SYSTEM + SYS_cleandiv2_div);#endif#ifdef DEFAULT_CD3_FREQ	reg = em86xx_calculate_SYS_clean_dividers(DEFAULT_CD3_FREQ);	__raw_writel(reg, REG_BASE_SYSTEM + SYS_cleandiv3_div);#endif}#endif#endif /* CONFIG_ARCH_TANGO *///// Delay//void em86xx_usleep(int usec){#if 0    int i;    unsigned long clock = em86xx_getclock();    clock >>= 20;    clock >>= 1;    clock /= 5;    clock *= usec;    for (i = 0; i < clock; ++i)        ;#else    unsigned int start, end;    start = __raw_readl(REG_BASE_SYSTEM + SYS_xtal_in_cnt);    end = start + (usec * 27);    if (end <= start)        while (__raw_readl(REG_BASE_SYSTEM + SYS_xtal_in_cnt) > start);    while (__raw_readl(REG_BASE_SYSTEM + SYS_xtal_in_cnt) < end);#endif}void em86xx_msleep(int msec){#if 0    while (msec-- > 0)         em86xx_usleep(990);#else    while (msec-- > 0)         em86xx_usleep(998);#endif}//// CPSR flag//// disable IRQ and FIQ and return original flagunsigned int em86xx_saveflag_clif(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs r1, cpsr\n"            // get CPSR        "mov %0, r1\n"              // save CPSR        "orr r1, r1, #0xc0\n"       // disable IRQ & FIQ        "msr cpsr_c, r1\n"          // set CPSR        : "=r" (cpsr_reg) : : "r1");    return cpsr_reg;}// disable FIQ and return original flagunsigned int em86xx_saveflag_clf(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs r1, cpsr\n"            // get CPSR        "mov %0, r1\n"              // save CPSR        "orr r1, r1, #0x40\n"       // disable FIQ        "msr cpsr_c, r1\n"          // set CPSR        : "=r" (cpsr_reg) : : "r1");    return cpsr_reg;}// disable IRQ and return original flagunsigned int em86xx_saveflag_cli(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs r1, cpsr\n"            // get CPSR        "mov %0, r1\n"              // save CPSR        "orr r1, r1, #0x80\n"       // disable IRQ        "msr cpsr_c, r1\n"          // set CPSR        : "=r" (cpsr_reg) : : "r1");    return cpsr_reg;}// return CPSRunsigned int em86xx_getflag(void){    unsigned int cpsr_reg;    __asm__ __volatile__(        "mrs r1, cpsr\n"            // get CPSR        "mov %0, r1\n"                      : "=r" (cpsr_reg) : : "r1");    return cpsr_reg;}void em86xx_restoreflag(unsigned int cpsr_reg){    __asm__ __volatile__(        "mov r1, %0\n"        "msr cpsr_c, r1\n"        : : "r" (cpsr_reg));}//// Cache control//int em86xx_cache_bist(void){    unsigned int reg = 0;    int icache, dcache, writeback;    em86xx_get_cache_state(&icache, &dcache, &writeback);    em86xx_enable_cache(0, 0, 0); /* disable cache before BIST */    __asm__ __volatile__ (        "mcr    p15, 0, %0, c7, c13, 0\n"        "mcr    p15, 0, %0, c7, c13, 1\n"        : : "r" (reg)    );    __asm__ __volatile__ (        "mrc    p15, 0, %0, c8, c0, 0\n"        : "=r" (reg)    );    em86xx_enable_cache(icache, dcache, writeback);    return reg & 0x3;}void em86xx_get_cache_state(int *picache, int *pdcache, int *pwriteback){    unsigned int reg;    __asm__ __volatile__ (        "mrc    p15, 0, %0, c1, c0, 0\n"        : "=r" (reg)    );    if (picache)        *picache = (reg & 0x1000) ? 1 : 0;    if (pdcache)        *pdcache = (reg & 0x0004) ? 1 : 0;    if (pwriteback)        *pwriteback = (reg & 0x0002) ? 1 : 0;}void em86xx_enable_cache(int icache, int dcache, int writeback){    unsigned int reg;    __asm__ __volatile__ (        "mrc    p15, 0, %0, c1, c0, 0\n"        : "=r" (reg)    );

⌨️ 快捷键说明

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