📄 ixdp2400_misc.c
字号:
//==========================================================================
//
// ixdp2400_misc.c
//
// HAL misc board support code for XScale IXDP2400
//
//==========================================================================
//####COPYRIGHTBEGIN####
//
// -------------------------------------------
// The contents of this file are subject to the Red Hat eCos Public License
// Version 1.1 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.redhat.com/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations under
// the License.
//
// The Original Code is eCos - Embedded Configurable Operating System,
// released September 30, 1998.
//
// The Initial Developer of the Original Code is Red Hat.
// Portions created by Red Hat are
// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.
// All Rights Reserved.
// -------------------------------------------
//
//####COPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): lagarwal
// Contributors:
// Date: 2002-02-25
// Purpose: HAL board support
// Description: Implementations of HAL board interfaces
//
//####DESCRIPTIONEND####
//
//========================================================================*/
#include <pkgconf/hal.h>
#include <pkgconf/system.h>
#include CYGBLD_HAL_PLATFORM_H
#include CYGHWR_MEMORY_LAYOUT_H
#include <cyg/infra/cyg_type.h> // base types
#include <cyg/infra/cyg_trac.h> // tracing macros
#include <cyg/infra/cyg_ass.h> // assertion macros
#include <cyg/hal/hal_io.h> // IO macros
#include <cyg/hal/hal_stub.h> // Stub macros
#include <cyg/hal/hal_if.h> // calling interface API
#include <cyg/hal/hal_arch.h> // Register state info
#include <cyg/hal/hal_intr.h> // Interrupt names
#include <cyg/hal/hal_cache.h>
#include <cyg/hal/hal_ixdp2400.h> // Hardware definitions
#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED
#include <cyg/hal/cfg_utility.h>
#include <cyg/io/i2c.h>
#include <cyg/io/pci.h>
#ifdef ENABLE_INT
CYG_ADDRESS pciIntList[PCI_ISR_COUNT]; /* list of int handlers */
CYG_ADDRWORD pciIntDataList[PCI_ISR_COUNT]; /* list of data objects */
#endif
externC cyg_pci_device slave_dev_info;
cyg_uint32 cpld_rev, board_rev, ext_osc_freq, silicon_rev;
struct board_config *board_config_data = (struct board_config *)SCRATCHPAD_BASE;
int qdr_ch_sz_array[MAX_QDR_CHANNEL];
extern void printf(char *fmt, ...);
int strap_options_val(void)
{
return *(STRAP_OPTIONS_REG);
}
unsigned long swap32(unsigned long x)
{
#ifdef __ARMEB__
return ((( x & 0x000000FF)<<24) |
(( x & 0x0000FF00)<<8) |
(( x & 0x00FF0000)>>8) |
(( x & 0xFF000000)>>24));
#else
return x;
#endif
}
unsigned short swap16(unsigned short x)
{
#ifdef __ARMEB__
return((( x & 0x00FF) <<8) |
(( x & 0xFF00)>>8));
#else
return x;
#endif
}
void display_led(char firstchar, char secondchar, char thirdchar, char fourthchar)
{
#ifdef __ARMEB__
if(((silicon_rev & 0xF0) >> 4))
{
*((volatile cyg_uint8 *)ALPHANUM_DIS_DATA) = fourthchar;
*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 1)) = thirdchar;
*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 2)) = secondchar;
*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 3)) = firstchar;
}
else
{
*((volatile cyg_uint8 *)ALPHANUM_DIS_DATA) = firstchar;
*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 1)) = secondchar;
*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 2)) = thirdchar;
*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 3)) = fourthchar;
}
#else
*((volatile cyg_uint8 *)ALPHANUM_DIS_DATA) = fourthchar;
*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 1)) = thirdchar;
*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 2)) = secondchar;
*((volatile cyg_uint8 *)(ALPHANUM_DIS_DATA + 3)) = firstchar;
#endif
}
#ifdef ENABLE_INT
void pciInt(void)
{
int i;
pci_ISR *isr;
char cpld_int_val = *(CPLD_INT_REG);
for(i = 0; i < PCI_ISR_COUNT; i++)
{
if((pciIntList[i] != (CYG_ADDRESS)hal_default_isr) && (cpld_int_val & (1 << i)))
{
isr = (pci_ISR *)pciIntList[i];
(*isr)(i, pciIntDataList[i]);
}
}
}
void pciIntConnect(int vector, CYG_ADDRESS routine, CYG_ADDRWORD data)
{
if(pciIntList[vector] == (CYG_ADDRESS)hal_default_isr)
{
pciIntList[vector] = routine;
pciIntDataList[vector] = data;
}
}
void pciIntDisconnect(int vector)
{
pciIntList[vector] = (CYG_ADDRESS)hal_default_isr;
pciIntDataList[vector] = (CYG_ADDRWORD)NULL;
}
#endif
void hal_sram_init(int channel, int skip_csr, int frm_pci, int offset)
{
int i, j, qdr_ch_csr_base, qdr_base, sram_csr_val, temp, cache_on;
int qdr_ch_size = MIN_SRAM_SIZE;
int sram_detected = 0;
// calculate the csr base and qdr base
if(frm_pci)
{
qdr_ch_csr_base = slave_dev_info.base_map[CSR_BAR] + QDR_CH_BASE_FRM_PCI + (channel * 0x400);
qdr_base = slave_dev_info.base_map[SRAM_BAR] + (channel * 0x10000000);
}
else
{
qdr_ch_csr_base = QDR_CH_CSR_BASE + (channel * 0x400000);
qdr_base = SRAM_BASE + (channel * 0x10000000);
}
// init csrs
if(!skip_csr)
{
int addr;
// rcomp registers are only 4 bytes distant. So, when this function will be called by pci init it won't
// work properly due to pci bug. Insert a dummy read cycle in between write operations.
for(addr = 0x340; addr <= 0x3BC; addr += 4)
{
*((volatile cyg_uint32 *)(qdr_ch_csr_base + addr)) = 0xCCCC;
#ifdef A0_REV
temp = *((volatile cyg_uint32 *)(qdr_ch_csr_base + addr));
#endif
}
// Invert rcomp polarity
*((volatile cyg_uint32 *)(qdr_ch_csr_base + 0x300)) = 0x10060;
#ifdef QDR1
// for 50 ohm ref resistor in real board/ tester
*((volatile cyg_uint32 *)(qdr_ch_csr_base + 0x318)) = 0xFFFF3;
// wait for 1ms
hal_delay_us(1000);
*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_RX_DLL_OFF)) = 0x48;
#else
// for 50 ohm ref resistor in real board/ tester
*((volatile cyg_uint32 *)(qdr_ch_csr_base + 0x318)) = 0x518C3;
// wait for 1ms
hal_delay_us(1000);
*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_RX_DLL_OFF)) = 0x52;
#endif
*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_RX_DESKEW_OFF)) = 0x12;
// set sram csr to use max sram size
*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_CH_CONTROL_OFF)) = MAX_SRAM_SIZE_CSR_VAL;
// wait for 3ms
hal_delay_us(3000);
*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_RD_PTR_OFF)) = 0x4;
// read rd_ptr_off back to ensure that write is completed
temp = *((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_RD_PTR_OFF));
}
if(!frm_pci)
{
HAL_DCACHE_IS_ENABLED(cache_on);
if (cache_on) {
HAL_DCACHE_SYNC();
HAL_DCACHE_DISABLE();
}
for(j = 1; j <= 5; j++)
{
volatile cyg_uint32 *temp1, *temp2;
*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_CH_CONTROL_OFF)) = PIPELINE | (j << 7);
hal_delay_us(3000);
// now probe for the right size
for(i = 0; i < SRAM_SIZE_LOOPS; i++)
{
temp1 = (volatile cyg_uint32 *)(qdr_base + qdr_ch_size);
*temp1 = 0xAA55AA55;
if(*temp1 != 0xAA55AA55)
{
break;
}
temp1 = (volatile cyg_uint32 *)(qdr_base + offset);
temp2 = (volatile cyg_uint32 *)(qdr_base + (qdr_ch_size / 2) + offset);
*temp1 = 0xA5A5A5A5;
*temp2 = 0x55AAAA55;
if(*temp1 == *temp2)
{
break;
}
sram_detected = 1;
qdr_ch_size *= 2;
}
}
if (cache_on) {
HAL_DCACHE_ENABLE();
}
if(!sram_detected)
{
qdr_ch_size = 0;
}
qdr_ch_sz_array[channel] = qdr_ch_size;
temp = 1024 * 1024;
for(i = 0; i < 6; i++)
{
temp = temp * 2;
if(temp == qdr_ch_size)
break;
}
sram_csr_val = i << 7;
sram_csr_val |= PIPELINE;
*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_CH_CONTROL_OFF)) = sram_csr_val;
}
if(!frm_pci && qdr_ch_size)
{
// initialize whole SRAM with 0 so that it doesn't generate parity errors
memset((char *)(qdr_base + offset), 0, (qdr_ch_size - offset));
if(board_rev >= 3)
{
// parity is working only on 3rd board rev. and above
*((volatile cyg_uint32 *)(qdr_ch_csr_base + QDR_CH_CONTROL_OFF)) |= PARITY_ENABLE;
}
}
}
void hal_hardware_init(void)
{
int i;
silicon_rev = *(PRODUCT_ID_REG);
display_led(DISPLAY_NULL, 'O', 'S', 'C');
cpld_rev = *(CPLD_REV_REG);
board_rev = (cpld_rev & 0xF0) >> 4;
if(board_rev < 4)
{
ext_osc_freq = 600000000 / 6;
}
else
{
int numerator, denominator;
int denom_array[] = {2, 4, 8, 16, 1, 2, 4, 8};
numerator = (*(SYS_CLK_M_REG) & 0xFF) * 2;
denominator = denom_array[(*(SYS_CLK_N_REG) & 0x7)];
ext_osc_freq = (3125000 * numerator) / denominator;
}
// Let the timer run at a default rate (for delays)
hal_clock_initialize((ext_osc_freq / 2));
// Set up eCos/ROM interfaces
hal_if_init();
display_led('C', 'F', 'G', 'D');
// if this is master npu then read config data
if(strap_options_val() & CFG_PCI_BOOT_HOST)
{
struct KI_EEPROM_CONTENT temp;
// read config data
if(i2c_seq_read(SLAVE_ADDR_1, 0, (unsigned char *)&temp, sizeof(struct KI_EEPROM_CONTENT)))
{
printf("Encountered problem in reading config EPROM\n");
}
else
{
if(temp.comm_cfg.prom_fmt == '0')
{
// save in scratch for later reference
// remember scratch is not byte writable
for(i = 0; i < sizeof(struct KI_EEPROM_CONTENT); i += 4)
{
*((cyg_uint32 *)((cyg_uint32)&(board_config_data->config_data) + i)) = *((cyg_uint32 *)((cyg_uint32)&temp + i));
}
// set the valid flag
board_config_data->config_valid = CONFIG_DATA_VALID;
}
else
{
printf("Config EPROM is either not programmed or corrupted\n");
}
}
board_config_data->sdram_size = hal_dram_size;
}
else
{
// if slave has flash then init valid flag with 0 so that we will know later
// whether master has copied config data or not
if(strap_options_val() & CFG_PROM_BOOT)
{
board_config_data->config_valid = 0;
}
}
{
char *min_product_type[] = {"IXP2800", "IXP2800 with Crypto", "IXP2400"};
char *maj_rev[] = {"A1", "B0"};
printf("Found %s Rev. %s\n", min_product_type[((silicon_rev & 0xFF00) >> 8)], maj_rev[((silicon_rev & 0xF0) >> 4)]);
printf("Core clock frequency is %d MHZ\n", ((ext_osc_freq * 6) / 1000000));
printf("DDR channel operating freq. is %d MHZ\n", (((ext_osc_freq * 6) / 1000000) / ((*(CCR_REG) >> 16) & 0xF)));
if(!(strap_options_val() & CFG_PCI_BOOT_HOST))
{
printf("QDR channel 0 operating freq. is %d MHZ\n", (((ext_osc_freq * 6) / 1000000) / (*(CCR_REG) & 0xF)));
}
}
display_led('S', 'R', 'A', 'M');
// init qdr channels
for(i = 0; i < MAX_QDR_CHANNEL; i++)
{
if(!(strap_options_val() & CFG_PCI_BOOT_HOST) && (i == 0))
{
char dev_id;
// on slave QDR channel 0 may have a TCAM card
if(!i2c_read(SLAVE_ADDR_4, DEV_ID_ADDR, &dev_id))
{
if(dev_id == TC_DEV_ID)
{
board_config_data->qdr_channel_size[i] = qdr_ch_sz_array[i] = 0;
printf("Found TCAM card on QDR channel 0. Skipping QDR channel 0 init.......\n");
continue;
}
}
}
hal_sram_init(i, 0, 0, 0);
board_config_data->qdr_channel_size[i] = qdr_ch_sz_array[i];
}
#ifdef ENABLE_INT
{
// init pci int and data list
for (i = 0; i < PCI_ISR_COUNT; i++)
{
pciIntList[i] = (CYG_ADDRESS)hal_default_isr;
pciIntDataList[i] = (CYG_ADDRWORD)NULL;
}
// enable IRQ
hal_unmask_all_int();
// attach and enable pci intb
HAL_INTERRUPT_ATTACH(CYGNUM_HAL_INTERRUPT_PCI_INTB, pciInt, 0, 0);
HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_PCI_INTB);
}
#endif
}
#include CYGHWR_MEMORY_LAYOUT_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -