Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
5d3207da
U
U-Boot.Mirror
项目概览
OS
/
U-Boot.Mirror
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
U-Boot.Mirror
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5d3207da
编写于
8月 21, 2002
作者:
W
wdenk
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Initial revision
上级
5b845b66
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
1003 addition
and
0 deletion
+1003
-0
common/virtex2.c
common/virtex2.c
+543
-0
common/xilinx.c
common/xilinx.c
+269
-0
rtc/ds1337.c
rtc/ds1337.c
+191
-0
未找到文件。
common/virtex2.c
0 → 100644
浏览文件 @
5d3207da
/*
* (C) Copyright 2002
* Rich Ireland, Enterasys Networks, rireland@enterasys.com.
* Keith Outwater, keith_outwater@mvis.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
*
*/
/*
* Configuration support for Xilinx Virtex2 devices. Based
* on spartan2.c (Rich Ireland, rireland@enterasys.com).
*/
#include <common.h>
#include <virtex2.h>
#if (CONFIG_FPGA & (CFG_XILINX | CFG_VIRTEX2))
#ifdef FPGA_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
/*
* If the SelectMap interface can be overrun by the processor, define
* CFG_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration
* file and add board-specific support for checking BUSY status. By default,
* assume that the SelectMap interface cannot be overrun.
*/
#ifndef CFG_FPGA_CHECK_BUSY
#undef CFG_FPGA_CHECK_BUSY
#endif
#ifndef CONFIG_FPGA_DELAY
#define CONFIG_FPGA_DELAY()
#endif
#ifndef CFG_FPGA_PROG_FEEDBACK
#define CFG_FPGA_PROG_FEEDBACK
#endif
/*
* Don't allow config cycle to be interrupted
*/
#ifndef CFG_FPGA_CHECK_CTRLC
#undef CFG_FPGA_CHECK_CTRLC
#endif
/*
* Check for errors during configuration by default
*/
#ifndef CFG_FPGA_CHECK_ERROR
#define CFG_FPGA_CHECK_ERROR
#endif
/*
* The default timeout in mS for INIT_B to deassert after PROG_B has
* been deasserted. Per the latest Virtex II Handbook (page 347), the
* max time from PORG_B deassertion to INIT_B deassertion is 4uS per
* data frame for the XC2V8000. The XC2V8000 has 2860 data frames
* which yields 11.44 mS. So let's make it bigger in order to handle
* an XC2V1000, if anyone can ever get ahold of one.
*/
#ifndef CFG_FPGA_WAIT_INIT
#define CFG_FPGA_WAIT_INIT 500
/* time in milliseconds */
#endif
/*
* The default timeout for waiting for BUSY to deassert during configuration.
* This is normally not necessary since for most reasonable configuration
* clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary.
*/
#ifndef CFG_FPGA_WAIT_BUSY
#define CFG_FPGA_WAIT_BUSY 5
/* time in milliseconds */
#endif
/* Default timeout for waiting for FPGA to enter operational mode after
* configuration data has been written.
*/
#ifndef CFG_FPGA_WAIT_CONFIG
#define CFG_FPGA_WAIT_CONFIG 200
/* time in milliseconds */
#endif
static
int
Virtex2_ssm_load
(
Xilinx_desc
*
desc
,
void
*
buf
,
size_t
bsize
);
static
int
Virtex2_ssm_dump
(
Xilinx_desc
*
desc
,
void
*
buf
,
size_t
bsize
);
static
int
Virtex2_ssm_reloc
(
Xilinx_desc
*
desc
,
ulong
reloc_offset
);
static
int
Virtex2_ss_load
(
Xilinx_desc
*
desc
,
void
*
buf
,
size_t
bsize
);
static
int
Virtex2_ss_dump
(
Xilinx_desc
*
desc
,
void
*
buf
,
size_t
bsize
);
static
int
Virtex2_ss_reloc
(
Xilinx_desc
*
desc
,
ulong
reloc_offset
);
int
Virtex2_load
(
Xilinx_desc
*
desc
,
void
*
buf
,
size_t
bsize
)
{
int
ret_val
=
FPGA_FAIL
;
switch
(
desc
->
iface
)
{
case
slave_serial
:
PRINTF
(
"%s: Launching Slave Serial Load
\n
"
,
__FUNCTION__
);
ret_val
=
Virtex2_ss_load
(
desc
,
buf
,
bsize
);
break
;
case
slave_selectmap
:
PRINTF
(
"%s: Launching Slave Parallel Load
\n
"
,
__FUNCTION__
);
ret_val
=
Virtex2_ssm_load
(
desc
,
buf
,
bsize
);
break
;
default:
printf
(
"%s: Unsupported interface type, %d
\n
"
,
__FUNCTION__
,
desc
->
iface
);
}
return
ret_val
;
}
int
Virtex2_dump
(
Xilinx_desc
*
desc
,
void
*
buf
,
size_t
bsize
)
{
int
ret_val
=
FPGA_FAIL
;
switch
(
desc
->
iface
)
{
case
slave_serial
:
PRINTF
(
"%s: Launching Slave Serial Dump
\n
"
,
__FUNCTION__
);
ret_val
=
Virtex2_ss_dump
(
desc
,
buf
,
bsize
);
break
;
case
slave_parallel
:
PRINTF
(
"%s: Launching Slave Parallel Dump
\n
"
,
__FUNCTION__
);
ret_val
=
Virtex2_ssm_dump
(
desc
,
buf
,
bsize
);
break
;
default:
printf
(
"%s: Unsupported interface type, %d
\n
"
,
__FUNCTION__
,
desc
->
iface
);
}
return
ret_val
;
}
int
Virtex2_info
(
Xilinx_desc
*
desc
)
{
return
FPGA_SUCCESS
;
}
int
Virtex2_reloc
(
Xilinx_desc
*
desc
,
ulong
reloc_offset
)
{
int
ret_val
=
FPGA_FAIL
;
if
(
desc
->
family
!=
Xilinx_Virtex2
)
{
printf
(
"%s: Unsupported family type, %d
\n
"
,
__FUNCTION__
,
desc
->
family
);
return
FPGA_FAIL
;
}
else
switch
(
desc
->
iface
)
{
case
slave_serial
:
ret_val
=
Virtex2_ss_reloc
(
desc
,
reloc_offset
);
break
;
case
slave_selectmap
:
ret_val
=
Virtex2_ssm_reloc
(
desc
,
reloc_offset
);
break
;
default:
printf
(
"%s: Unsupported interface type, %d
\n
"
,
__FUNCTION__
,
desc
->
iface
);
}
return
ret_val
;
}
/*
* Virtex-II Slave SelectMap configuration loader. Configuration via
* SelectMap is as follows:
* 1. Set the FPGA's PROG_B line low.
* 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high.
* 3. Write data to the SelectMap port. If INIT_B goes low at any time
* this process, a configuration error (most likely CRC failure) has
* ocurred. At this point a status word may be read from the
* SelectMap interface to determine the source of the problem (You
* could, for instance, put this in you 'abort' function handler).
* 4. After all data has been written, test the state of the FPGA
* INIT_B and DONE lines. If both are high, configuration has
* succeeded. Congratulations!
*/
static
int
Virtex2_ssm_load
(
Xilinx_desc
*
desc
,
void
*
buf
,
size_t
bsize
)
{
int
ret_val
=
FPGA_FAIL
;
Xilinx_Virtex2_Slave_SelectMap_fns
*
fn
=
desc
->
iface_fns
;
PRINTF
(
"%s:%d: Start with interface functions @ 0x%p
\n
"
,
__FUNCTION__
,
__LINE__
,
fn
);
if
(
fn
)
{
size_t
bytecount
=
0
;
unsigned
char
*
data
=
(
unsigned
char
*
)
buf
;
int
cookie
=
desc
->
cookie
;
unsigned
long
ts
;
/* Gotta split this one up (so the stack won't blow??) */
PRINTF
(
"%s:%d: Function Table:
\n
"
" base 0x%p
\n
"
" struct 0x%p
\n
"
" pre 0x%p
\n
"
" prog 0x%p
\n
"
" init 0x%p
\n
"
" error 0x%p
\n
"
,
__FUNCTION__
,
__LINE__
,
&
fn
,
fn
,
fn
->
pre
,
fn
->
pgm
,
fn
->
init
,
fn
->
err
);
PRINTF
(
" clock 0x%p
\n
"
" cs 0x%p
\n
"
" write 0x%p
\n
"
" rdata 0x%p
\n
"
" wdata 0x%p
\n
"
" busy 0x%p
\n
"
" abort 0x%p
\n
"
" post 0x%p
\n\n
"
,
fn
->
clk
,
fn
->
cs
,
fn
->
wr
,
fn
->
rdata
,
fn
->
wdata
,
fn
->
busy
,
fn
->
abort
,
fn
->
post
);
#ifdef CFG_FPGA_PROG_FEEDBACK
printf
(
"Initializing FPGA Device %d...
\n
"
,
cookie
);
#endif
/*
* Run the pre configuration function if there is one.
*/
if
(
*
fn
->
pre
)
{
(
*
fn
->
pre
)
(
cookie
);
}
/*
* Assert the program line. The minimum pulse width for
* Virtex II devices is 300 nS (Tprogram parameter in datasheet).
* There is no maximum value for the pulse width. Check to make
* sure that INIT_B goes low after assertion of PROG_B
*/
(
*
fn
->
pgm
)
(
TRUE
,
TRUE
,
cookie
);
udelay
(
10
);
ts
=
get_timer
(
0
);
do
{
if
(
get_timer
(
ts
)
>
CFG_FPGA_WAIT_INIT
)
{
printf
(
"%s:%d: ** Timeout after %d mS waiting for INIT"
" to assert.
\n
"
,
__FUNCTION__
,
__LINE__
,
CFG_FPGA_WAIT_INIT
);
(
*
fn
->
abort
)
(
cookie
);
return
FPGA_FAIL
;
}
}
while
(
!
(
*
fn
->
init
)
(
cookie
));
(
*
fn
->
pgm
)
(
FALSE
,
TRUE
,
cookie
);
CONFIG_FPGA_DELAY
();
(
*
fn
->
clk
)
(
TRUE
,
TRUE
,
cookie
);
/*
* Start a timer and wait for INIT_B to go high
*/
ts
=
get_timer
(
0
);
do
{
CONFIG_FPGA_DELAY
();
if
(
get_timer
(
ts
)
>
CFG_FPGA_WAIT_INIT
)
{
printf
(
"%s:%d: ** Timeout after %d mS waiting for INIT"
" to deassert.
\n
"
,
__FUNCTION__
,
__LINE__
,
CFG_FPGA_WAIT_INIT
);
(
*
fn
->
abort
)
(
cookie
);
return
FPGA_FAIL
;
}
}
while
((
*
fn
->
init
)
(
cookie
)
&&
(
*
fn
->
busy
)
(
cookie
));
(
*
fn
->
wr
)
(
TRUE
,
TRUE
,
cookie
);
(
*
fn
->
cs
)
(
TRUE
,
TRUE
,
cookie
);
udelay
(
10000
);
/*
* Load the data byte by byte
*/
while
(
bytecount
<
bsize
)
{
#ifdef CFG_FPGA_CHECK_CTRLC
if
(
ctrlc
())
{
(
*
fn
->
abort
)
(
cookie
);
return
FPGA_FAIL
;
}
#endif
#ifdef CFG_FPGA_CHECK_ERROR
if
((
*
fn
->
init
)
(
cookie
))
{
printf
(
"%s:%d: ** Error: INIT asserted during"
" configuration
\n
"
,
__FUNCTION__
,
__LINE__
);
(
*
fn
->
abort
)
(
cookie
);
return
FPGA_FAIL
;
}
#endif
(
*
fn
->
wdata
)
(
data
[
bytecount
++
],
TRUE
,
cookie
);
CONFIG_FPGA_DELAY
();
/*
* Cycle the clock pin
*/
(
*
fn
->
clk
)
(
FALSE
,
TRUE
,
cookie
);
CONFIG_FPGA_DELAY
();
(
*
fn
->
clk
)
(
TRUE
,
TRUE
,
cookie
);
#ifdef CFG_FPGA_CHECK_BUSY
ts
=
get_timer
(
0
);
while
((
*
fn
->
busy
)
(
cookie
))
{
if
(
get_timer
(
ts
)
>
CFG_FPGA_WAIT_BUSY
)
{
printf
(
"%s:%d: ** Timeout after %d mS waiting for"
" BUSY to deassert
\n
"
,
__FUNCTION__
,
__LINE__
,
CFG_FPGA_WAIT_BUSY
);
(
*
fn
->
abort
)
(
cookie
);
return
FPGA_FAIL
;
}
}
#endif
#ifdef CFG_FPGA_PROG_FEEDBACK
if
(
bytecount
%
(
bsize
/
40
)
==
0
)
putc
(
'.'
);
#endif
}
/*
* Finished writing the data; deassert FPGA CS_B and WRITE_B signals.
*/
CONFIG_FPGA_DELAY
();
(
*
fn
->
cs
)
(
FALSE
,
TRUE
,
cookie
);
(
*
fn
->
wr
)
(
FALSE
,
TRUE
,
cookie
);
#ifdef CFG_FPGA_PROG_FEEDBACK
putc
(
'\n'
);
#endif
/*
* Check for successful configuration. FPGA INIT_B and DONE should
* both be high upon successful configuration.
*/
ts
=
get_timer
(
0
);
ret_val
=
FPGA_SUCCESS
;
while
(((
*
fn
->
done
)
(
cookie
)
==
FPGA_FAIL
)
||
(
*
fn
->
init
)
(
cookie
))
{
if
(
get_timer
(
ts
)
>
CFG_FPGA_WAIT_CONFIG
)
{
printf
(
"%s:%d: ** Timeout after %d mS waiting for DONE to"
"assert and INIT to deassert
\n
"
,
__FUNCTION__
,
__LINE__
,
CFG_FPGA_WAIT_CONFIG
);
(
*
fn
->
abort
)
(
cookie
);
ret_val
=
FPGA_FAIL
;
break
;
}
}
if
(
ret_val
==
FPGA_SUCCESS
)
{
#ifdef CFG_FPGA_PROG_FEEDBACK
printf
(
"Initialization of FPGA device %d complete
\n
"
,
cookie
);
#endif
/*
* Run the post configuration function if there is one.
*/
if
(
*
fn
->
post
)
{
(
*
fn
->
post
)
(
cookie
);
}
}
else
{
#ifdef CFG_FPGA_PROG_FEEDBACK
printf
(
"** Initialization of FPGA device %d FAILED
\n
"
,
cookie
);
#endif
}
}
else
{
printf
(
"%s:%d: NULL Interface function table!
\n
"
,
__FUNCTION__
,
__LINE__
);
}
return
ret_val
;
}
/*
* Read the FPGA configuration data
*/
static
int
Virtex2_ssm_dump
(
Xilinx_desc
*
desc
,
void
*
buf
,
size_t
bsize
)
{
int
ret_val
=
FPGA_FAIL
;
Xilinx_Virtex2_Slave_SelectMap_fns
*
fn
=
desc
->
iface_fns
;
if
(
fn
)
{
unsigned
char
*
data
=
(
unsigned
char
*
)
buf
;
size_t
bytecount
=
0
;
int
cookie
=
desc
->
cookie
;
printf
(
"Starting Dump of FPGA Device %d...
\n
"
,
cookie
);
(
*
fn
->
cs
)
(
TRUE
,
TRUE
,
cookie
);
(
*
fn
->
clk
)
(
TRUE
,
TRUE
,
cookie
);
while
(
bytecount
<
bsize
)
{
#ifdef CFG_FPGA_CHECK_CTRLC
if
(
ctrlc
())
{
(
*
fn
->
abort
)
(
cookie
);
return
FPGA_FAIL
;
}
#endif
/*
* Cycle the clock and read the data
*/
(
*
fn
->
clk
)
(
FALSE
,
TRUE
,
cookie
);
(
*
fn
->
clk
)
(
TRUE
,
TRUE
,
cookie
);
(
*
fn
->
rdata
)
(
&
(
data
[
bytecount
++
]),
cookie
);
#ifdef CFG_FPGA_PROG_FEEDBACK
if
(
bytecount
%
(
bsize
/
40
)
==
0
)
putc
(
'.'
);
#endif
}
/*
* Deassert CS_B and cycle the clock to deselect the device.
*/
(
*
fn
->
cs
)
(
FALSE
,
FALSE
,
cookie
);
(
*
fn
->
clk
)
(
FALSE
,
TRUE
,
cookie
);
(
*
fn
->
clk
)
(
TRUE
,
TRUE
,
cookie
);
#ifdef CFG_FPGA_PROG_FEEDBACK
putc
(
'\n'
);
#endif
puts
(
"Done.
\n
"
);
}
else
{
printf
(
"%s:%d: NULL Interface function table!
\n
"
,
__FUNCTION__
,
__LINE__
);
}
return
ret_val
;
}
/*
* Relocate the addresses in the function table from FLASH (or ROM,
* or whatever) to RAM.
*/
static
int
Virtex2_ssm_reloc
(
Xilinx_desc
*
desc
,
ulong
reloc_offset
)
{
ulong
addr
;
int
ret_val
=
FPGA_FAIL
;
Xilinx_Virtex2_Slave_SelectMap_fns
*
fn_r
,
*
fn
=
(
Xilinx_Virtex2_Slave_SelectMap_fns
*
)
(
desc
->
iface_fns
);
if
(
fn
)
{
/*
* Get the relocated table address
*/
addr
=
(
ulong
)
fn
+
reloc_offset
;
fn_r
=
(
Xilinx_Virtex2_Slave_SelectMap_fns
*
)
addr
;
/*
* Check to see if the table has already been relocated. If not, do
* a sanity check to make sure there is a faithful copy of the
* FLASH based function table in RAM, then adjust the table.
*/
if
(
!
fn_r
->
relocated
)
{
if
(
memcmp
(
fn_r
,
fn
,
sizeof
(
Xilinx_Virtex2_Slave_SelectMap_fns
))
==
0
)
{
desc
->
iface_fns
=
fn_r
;
}
else
{
PRINTF
(
"%s:%d: Invalid function table at 0x%p
\n
"
,
__FUNCTION__
,
__LINE__
,
fn_r
);
return
FPGA_FAIL
;
}
PRINTF
(
"%s:%d: Relocating descriptor at 0x%p
\n
"
,
__FUNCTION__
,
__LINE__
,
desc
);
addr
=
(
ulong
)
(
fn
->
pre
)
+
reloc_offset
;
fn_r
->
pre
=
(
Xilinx_pre_fn
)
addr
;
addr
=
(
ulong
)
(
fn
->
pgm
)
+
reloc_offset
;
fn_r
->
pgm
=
(
Xilinx_pgm_fn
)
addr
;
addr
=
(
ulong
)
(
fn
->
init
)
+
reloc_offset
;
fn_r
->
init
=
(
Xilinx_init_fn
)
addr
;
addr
=
(
ulong
)
(
fn
->
done
)
+
reloc_offset
;
fn_r
->
done
=
(
Xilinx_done_fn
)
addr
;
addr
=
(
ulong
)
(
fn
->
err
)
+
reloc_offset
;
fn_r
->
err
=
(
Xilinx_err_fn
)
addr
;
addr
=
(
ulong
)
(
fn
->
clk
)
+
reloc_offset
;
fn_r
->
clk
=
(
Xilinx_clk_fn
)
addr
;
addr
=
(
ulong
)
(
fn
->
cs
)
+
reloc_offset
;
fn_r
->
cs
=
(
Xilinx_cs_fn
)
addr
;
addr
=
(
ulong
)
(
fn
->
wr
)
+
reloc_offset
;
fn_r
->
wr
=
(
Xilinx_wr_fn
)
addr
;
addr
=
(
ulong
)
(
fn
->
rdata
)
+
reloc_offset
;
fn_r
->
rdata
=
(
Xilinx_rdata_fn
)
addr
;
addr
=
(
ulong
)
(
fn
->
wdata
)
+
reloc_offset
;
fn_r
->
wdata
=
(
Xilinx_wdata_fn
)
addr
;
addr
=
(
ulong
)
(
fn
->
busy
)
+
reloc_offset
;
fn_r
->
busy
=
(
Xilinx_busy_fn
)
addr
;
addr
=
(
ulong
)
(
fn
->
abort
)
+
reloc_offset
;
fn_r
->
abort
=
(
Xilinx_abort_fn
)
addr
;
addr
=
(
ulong
)
(
fn
->
post
)
+
reloc_offset
;
fn_r
->
post
=
(
Xilinx_post_fn
)
addr
;
fn_r
->
relocated
=
TRUE
;
}
else
{
printf
(
"%s:%d: Function table @0x%p has already been relocated
\n
"
,
__FUNCTION__
,
__LINE__
,
fn_r
);
desc
->
iface_fns
=
fn_r
;
}
ret_val
=
FPGA_SUCCESS
;
}
else
{
printf
(
"%s: NULL Interface function table!
\n
"
,
__FUNCTION__
);
}
return
ret_val
;
}
static
int
Virtex2_ss_load
(
Xilinx_desc
*
desc
,
void
*
buf
,
size_t
bsize
)
{
printf
(
"%s: Slave Serial Loading is unsupported
\n
"
,
__FUNCTION__
);
return
FPGA_FAIL
;
}
static
int
Virtex2_ss_dump
(
Xilinx_desc
*
desc
,
void
*
buf
,
size_t
bsize
)
{
printf
(
"%s: Slave Serial Dumping is unsupported
\n
"
,
__FUNCTION__
);
return
FPGA_FAIL
;
}
static
int
Virtex2_ss_reloc
(
Xilinx_desc
*
desc
,
ulong
reloc_offset
)
{
int
ret_val
=
FPGA_FAIL
;
Xilinx_Virtex2_Slave_Serial_fns
*
fn
=
(
Xilinx_Virtex2_Slave_Serial_fns
*
)
(
desc
->
iface_fns
);
if
(
fn
)
{
printf
(
"%s:%d: Slave Serial Loading is unsupported
\n
"
,
__FUNCTION__
,
__LINE__
);
}
else
{
printf
(
"%s:%d: NULL Interface function table!
\n
"
,
__FUNCTION__
,
__LINE__
);
}
return
ret_val
;
}
#endif
/* vim: set ts=4 tw=78: */
common/xilinx.c
0 → 100644
浏览文件 @
5d3207da
/*
* (C) Copyright 2002
* Rich Ireland, Enterasys Networks, rireland@enterasys.com.
* Keith Outwater, keith_outwater@mvis.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
*
*/
/*
* Xilinx FPGA support
*/
#include <common.h>
#include <virtex2.h>
#include <spartan2.h>
#if (CONFIG_FPGA & CFG_FPGA_XILINX)
#if 0
#define FPGA_DEBUG
#endif
/* Define FPGA_DEBUG to get debug printf's */
#ifdef FPGA_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
/* Local Static Functions */
static
int
xilinx_validate
(
Xilinx_desc
*
desc
,
char
*
fn
);
/* ------------------------------------------------------------------------- */
int
xilinx_load
(
Xilinx_desc
*
desc
,
void
*
buf
,
size_t
bsize
)
{
int
ret_val
=
FPGA_FAIL
;
/* assume a failure */
if
(
!
xilinx_validate
(
desc
,
__FUNCTION__
))
{
printf
(
"%s: Invalid device descriptor
\n
"
,
__FUNCTION__
);
}
else
switch
(
desc
->
family
)
{
case
Xilinx_Spartan2
:
#if (CONFIG_FPGA & CFG_SPARTAN2)
PRINTF
(
"%s: Launching the Spartan-II Loader...
\n
"
,
__FUNCTION__
);
ret_val
=
Spartan2_load
(
desc
,
buf
,
bsize
);
#else
printf
(
"%s: No support for Spartan-II devices.
\n
"
,
__FUNCTION__
);
#endif
break
;
case
Xilinx_Virtex2
:
#if (CONFIG_FPGA & CFG_VIRTEX2)
PRINTF
(
"%s: Launching the Virtex-II Loader...
\n
"
,
__FUNCTION__
);
ret_val
=
Virtex2_load
(
desc
,
buf
,
bsize
);
#else
printf
(
"%s: No support for Virtex-II devices.
\n
"
,
__FUNCTION__
);
#endif
break
;
default:
printf
(
"%s: Unsupported family type, %d
\n
"
,
__FUNCTION__
,
desc
->
family
);
}
return
ret_val
;
}
int
xilinx_dump
(
Xilinx_desc
*
desc
,
void
*
buf
,
size_t
bsize
)
{
int
ret_val
=
FPGA_FAIL
;
/* assume a failure */
if
(
!
xilinx_validate
(
desc
,
__FUNCTION__
))
{
printf
(
"%s: Invalid device descriptor
\n
"
,
__FUNCTION__
);
}
else
switch
(
desc
->
family
)
{
case
Xilinx_Spartan2
:
#if (CONFIG_FPGA & CFG_SPARTAN2)
PRINTF
(
"%s: Launching the Spartan-II Reader...
\n
"
,
__FUNCTION__
);
ret_val
=
Spartan2_dump
(
desc
,
buf
,
bsize
);
#else
printf
(
"%s: No support for Spartan-II devices.
\n
"
,
__FUNCTION__
);
#endif
break
;
case
Xilinx_Virtex2
:
#if (CONFIG_FPGA & CFG_VIRTEX2)
PRINTF
(
"%s: Launching the Virtex-II Reader...
\n
"
,
__FUNCTION__
);
ret_val
=
Virtex2_dump
(
desc
,
buf
,
bsize
);
#else
printf
(
"%s: No support for Virtex-II devices.
\n
"
,
__FUNCTION__
);
#endif
break
;
default:
printf
(
"%s: Unsupported family type, %d
\n
"
,
__FUNCTION__
,
desc
->
family
);
}
return
ret_val
;
}
int
xilinx_info
(
Xilinx_desc
*
desc
)
{
int
ret_val
=
FPGA_FAIL
;
if
(
xilinx_validate
(
desc
,
__FUNCTION__
))
{
printf
(
"Family:
\t
"
);
switch
(
desc
->
family
)
{
case
Xilinx_Spartan2
:
printf
(
"Spartan-II
\n
"
);
break
;
case
Xilinx_Virtex2
:
printf
(
"Virtex-II
\n
"
);
break
;
/* Add new family types here */
default:
printf
(
"Unknown family type, %d
\n
"
,
desc
->
family
);
}
printf
(
"Interface type:
\t
"
);
switch
(
desc
->
iface
)
{
case
slave_serial
:
printf
(
"Slave Serial
\n
"
);
break
;
case
master_serial
:
/* Not used */
printf
(
"Master Serial
\n
"
);
break
;
case
slave_parallel
:
printf
(
"Slave Parallel
\n
"
);
break
;
case
jtag_mode
:
/* Not used */
printf
(
"JTAG Mode
\n
"
);
break
;
case
slave_selectmap
:
printf
(
"Slave SelectMap Mode
\n
"
);
break
;
case
master_selectmap
:
printf
(
"Master SelectMap Mode
\n
"
);
break
;
/* Add new interface types here */
default:
printf
(
"Unsupported interface type, %d
\n
"
,
desc
->
iface
);
}
printf
(
"Device Size:
\t
%d bytes
\n
"
"Cookie:
\t
0x%x (%d)
\n
"
,
desc
->
size
,
desc
->
cookie
,
desc
->
cookie
);
if
(
desc
->
iface_fns
)
{
printf
(
"Device Function Table @ 0x%p
\n
"
,
desc
->
iface_fns
);
switch
(
desc
->
family
)
{
case
Xilinx_Spartan2
:
#if (CONFIG_FPGA & CFG_SPARTAN2)
Spartan2_info
(
desc
);
#else
/* just in case */
printf
(
"%s: No support for Spartan-II devices.
\n
"
,
__FUNCTION__
);
#endif
break
;
case
Xilinx_Virtex2
:
#if (CONFIG_FPGA & CFG_VIRTEX2)
Virtex2_info
(
desc
);
#else
/* just in case */
printf
(
"%s: No support for Virtex-II devices.
\n
"
,
__FUNCTION__
);
#endif
break
;
/* Add new family types here */
default:
/* we don't need a message here - we give one up above */
}
}
else
printf
(
"No Device Function Table.
\n
"
);
ret_val
=
FPGA_SUCCESS
;
}
else
{
printf
(
"%s: Invalid device descriptor
\n
"
,
__FUNCTION__
);
}
return
ret_val
;
}
int
xilinx_reloc
(
Xilinx_desc
*
desc
,
ulong
reloc_offset
)
{
int
ret_val
=
FPGA_FAIL
;
/* assume a failure */
if
(
!
xilinx_validate
(
desc
,
__FUNCTION__
))
{
printf
(
"%s: Invalid device descriptor
\n
"
,
__FUNCTION__
);
}
else
switch
(
desc
->
family
)
{
case
Xilinx_Spartan2
:
#if (CONFIG_FPGA & CFG_SPARTAN2)
ret_val
=
Spartan2_reloc
(
desc
,
reloc_offset
);
#else
printf
(
"%s: No support for Spartan-II devices.
\n
"
,
__FUNCTION__
);
#endif
break
;
case
Xilinx_Virtex2
:
#if (CONFIG_FPGA & CFG_VIRTEX2)
ret_val
=
Virtex2_reloc
(
desc
,
reloc_offset
);
#else
printf
(
"%s: No support for Virtex-II devices.
\n
"
,
__FUNCTION__
);
#endif
break
;
/* Add new family types here */
default:
printf
(
"%s: Unsupported family type, %d
\n
"
,
__FUNCTION__
,
desc
->
family
);
}
return
ret_val
;
}
/* ------------------------------------------------------------------------- */
static
int
xilinx_validate
(
Xilinx_desc
*
desc
,
char
*
fn
)
{
int
ret_val
=
FALSE
;
if
(
desc
)
{
if
((
desc
->
family
>
min_xilinx_type
)
&&
(
desc
->
family
<
max_xilinx_type
))
{
if
((
desc
->
iface
>
min_xilinx_iface_type
)
&&
(
desc
->
iface
<
max_xilinx_iface_type
))
{
if
(
desc
->
size
)
{
ret_val
=
TRUE
;
}
else
printf
(
"%s: NULL part size
\n
"
,
fn
);
}
else
printf
(
"%s: Invalid Interface type, %d
\n
"
,
fn
,
desc
->
iface
);
}
else
printf
(
"%s: Invalid family type, %d
\n
"
,
fn
,
desc
->
family
);
}
else
printf
(
"%s: NULL descriptor!
\n
"
,
fn
);
return
ret_val
;
}
#endif
/* CONFIG_FPGA & CFG_FPGA_XILINX */
rtc/ds1337.c
0 → 100644
浏览文件 @
5d3207da
/*
* (C) Copyright 2001, 2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
* Keith Outwater, keith_outwater@mvis.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
*/
/*
* Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
* DS1337 Real Time Clock (RTC).
*/
#include <common.h>
#include <command.h>
#include <rtc.h>
#include <i2c.h>
#if defined(CONFIG_RTC_DS1337) && (CONFIG_COMMANDS & CFG_CMD_DATE)
/*---------------------------------------------------------------------*/
#undef DEBUG_RTC
#ifdef DEBUG_RTC
#define DEBUGR(fmt,args...) printf(fmt ,##args)
#else
#define DEBUGR(fmt,args...)
#endif
/*---------------------------------------------------------------------*/
/*
* RTC register addresses
*/
#define RTC_SEC_REG_ADDR 0x0
#define RTC_MIN_REG_ADDR 0x1
#define RTC_HR_REG_ADDR 0x2
#define RTC_DAY_REG_ADDR 0x3
#define RTC_DATE_REG_ADDR 0x4
#define RTC_MON_REG_ADDR 0x5
#define RTC_YR_REG_ADDR 0x6
#define RTC_CTL_REG_ADDR 0x0e
#define RTC_STAT_REG_ADDR 0x0f
/*
* RTC control register bits
*/
#define RTC_CTL_BIT_A1IE 0x1
/* Alarm 1 interrupt enable */
#define RTC_CTL_BIT_A2IE 0x2
/* Alarm 2 interrupt enable */
#define RTC_CTL_BIT_INTCN 0x4
/* Interrupt control */
#define RTC_CTL_BIT_RS1 0x8
/* Rate select 1 */
#define RTC_CTL_BIT_RS2 0x10
/* Rate select 2 */
#define RTC_CTL_BIT_DOSC 0x80
/* Disable Oscillator */
/*
* RTC status register bits
*/
#define RTC_STAT_BIT_A1F 0x1
/* Alarm 1 flag */
#define RTC_STAT_BIT_A2F 0x2
/* Alarm 2 flag */
#define RTC_STAT_BIT_OSF 0x80
/* Oscillator stop flag */
static
uchar
rtc_read
(
uchar
reg
);
static
void
rtc_write
(
uchar
reg
,
uchar
val
);
static
uchar
bin2bcd
(
unsigned
int
n
);
static
unsigned
bcd2bin
(
uchar
c
);
/*
* Get the current time from the RTC
*/
void
rtc_get
(
struct
rtc_time
*
tmp
)
{
uchar
sec
,
min
,
hour
,
mday
,
wday
,
mon_cent
,
year
,
control
,
status
;
control
=
rtc_read
(
RTC_CTL_REG_ADDR
);
status
=
rtc_read
(
RTC_STAT_REG_ADDR
);
sec
=
rtc_read
(
RTC_SEC_REG_ADDR
);
min
=
rtc_read
(
RTC_MIN_REG_ADDR
);
hour
=
rtc_read
(
RTC_HR_REG_ADDR
);
wday
=
rtc_read
(
RTC_DAY_REG_ADDR
);
mday
=
rtc_read
(
RTC_DATE_REG_ADDR
);
mon_cent
=
rtc_read
(
RTC_MON_REG_ADDR
);
year
=
rtc_read
(
RTC_YR_REG_ADDR
);
DEBUGR
(
"Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
"hr: %02x min: %02x sec: %02x control: %02x status: %02x
\n
"
,
year
,
mon_cent
,
mday
,
wday
,
hour
,
min
,
sec
,
control
,
status
);
if
(
status
&
RTC_STAT_BIT_OSF
)
{
printf
(
"### Warning: RTC oscillator has stopped
\n
"
);
/* clear the OSF flag */
rtc_write
(
RTC_STAT_REG_ADDR
,
rtc_read
(
RTC_STAT_REG_ADDR
)
&
~
RTC_STAT_BIT_OSF
);
}
tmp
->
tm_sec
=
bcd2bin
(
sec
&
0x7F
);
tmp
->
tm_min
=
bcd2bin
(
min
&
0x7F
);
tmp
->
tm_hour
=
bcd2bin
(
hour
&
0x3F
);
tmp
->
tm_mday
=
bcd2bin
(
mday
&
0x3F
);
tmp
->
tm_mon
=
bcd2bin
(
mon_cent
&
0x1F
);
tmp
->
tm_year
=
bcd2bin
(
year
)
+
((
mon_cent
&
0x80
)
?
2000
:
1900
);
tmp
->
tm_wday
=
bcd2bin
((
wday
-
1
)
&
0x07
);
tmp
->
tm_yday
=
0
;
tmp
->
tm_isdst
=
0
;
DEBUGR
(
"Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d
\n
"
,
tmp
->
tm_year
,
tmp
->
tm_mon
,
tmp
->
tm_mday
,
tmp
->
tm_wday
,
tmp
->
tm_hour
,
tmp
->
tm_min
,
tmp
->
tm_sec
);
}
/*
* Set the RTC
*/
void
rtc_set
(
struct
rtc_time
*
tmp
)
{
uchar
century
;
DEBUGR
(
"Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d
\n
"
,
tmp
->
tm_year
,
tmp
->
tm_mon
,
tmp
->
tm_mday
,
tmp
->
tm_wday
,
tmp
->
tm_hour
,
tmp
->
tm_min
,
tmp
->
tm_sec
);
rtc_write
(
RTC_YR_REG_ADDR
,
bin2bcd
(
tmp
->
tm_year
%
100
));
century
=
(
tmp
->
tm_year
>=
2000
)
?
0x80
:
0
;
rtc_write
(
RTC_MON_REG_ADDR
,
bin2bcd
(
tmp
->
tm_mon
)
|
century
);
rtc_write
(
RTC_DAY_REG_ADDR
,
bin2bcd
(
tmp
->
tm_wday
+
1
));
rtc_write
(
RTC_DATE_REG_ADDR
,
bin2bcd
(
tmp
->
tm_mday
));
rtc_write
(
RTC_HR_REG_ADDR
,
bin2bcd
(
tmp
->
tm_hour
));
rtc_write
(
RTC_MIN_REG_ADDR
,
bin2bcd
(
tmp
->
tm_min
));
rtc_write
(
RTC_SEC_REG_ADDR
,
bin2bcd
(
tmp
->
tm_sec
));
}
/*
* Reset the RTC. We also enable the oscillator output on the
* SQW/INTB* pin and program it for 32,768 Hz output. Note that
* according to the datasheet, turning on the square wave output
* increases the current drain on the backup battery from about
* 600 nA to 2uA.
*/
void
rtc_reset
(
void
)
{
rtc_write
(
RTC_CTL_REG_ADDR
,
RTC_CTL_BIT_RS1
|
RTC_CTL_BIT_RS2
);
}
/*
* Helper functions
*/
static
uchar
rtc_read
(
uchar
reg
)
{
return
(
i2c_reg_read
(
CFG_I2C_RTC_ADDR
,
reg
));
}
static
void
rtc_write
(
uchar
reg
,
uchar
val
)
{
i2c_reg_write
(
CFG_I2C_RTC_ADDR
,
reg
,
val
);
}
static
unsigned
bcd2bin
(
uchar
n
)
{
return
((((
n
>>
4
)
&
0x0F
)
*
10
)
+
(
n
&
0x0F
));
}
static
unsigned
char
bin2bcd
(
unsigned
int
n
)
{
return
(((
n
/
10
)
<<
4
)
|
(
n
%
10
));
}
#endif
/* CONFIG_RTC_DS1337 && (CFG_COMMANDS & CFG_CMD_DATE) */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录