Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
ezynq
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
ezynq
Commits
01e77ff5
Commit
01e77ff5
authored
Sep 20, 2013
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Working on UART support for dumping registers before DDR initialization
parent
9cfda386
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
299 additions
and
271 deletions
+299
-271
ezynq_clk.py
ezynq_clk.py
+24
-21
ezynq_ddr.py
ezynq_ddr.py
+7
-20
ezynq_ddrc_defs.py
ezynq_ddrc_defs.py
+1
-1
ezynq_feature_config.py
ezynq_feature_config.py
+3
-0
ezynq_registers.py
ezynq_registers.py
+121
-78
ezynq_uboot.py
ezynq_uboot.py
+41
-34
ezynqcfg.py
ezynqcfg.py
+97
-102
test.mk
test.mk
+5
-15
No files found.
ezynq_clk.py
View file @
01e77ff5
...
...
@@ -101,6 +101,8 @@ class EzynqClk:
return
html_file
.
write
(
'<h2>Clock configuration parameters</h2>
\n
'
)
self
.
features
.
html_list_features
(
html_file
)
def
get_clocks
(
self
):
return
self
.
iface_divs
def
calculate_dependent_pars
(
self
):
speed_grade
=
self
.
features
.
get_par_value_or_default
(
"SPEED_GRADE"
)
ddr_type
=
self
.
ddr_type
...
...
@@ -408,6 +410,8 @@ class EzynqClk:
html_file
.
write
(
'</table>'
)
def
get_ddr_mhz
(
self
):
return
self
.
f_in
*
self
.
pll_fdivs
[
self
.
iface_divs
[
'DDR'
][
'PLL'
]]
/
self
.
iface_divs
[
'DDR'
][
'DIV'
]
def
get_uart_mhz
(
self
):
return
self
.
iface_divs
[
'UART'
][
'FREQ'
]
def
get_new_register_sets
(
self
):
return
self
.
clk_register_set
.
get_register_sets
(
True
,
True
)
...
...
@@ -417,37 +421,22 @@ class EzynqClk:
clk_register_set
.
set_initial_state
(
current_reg_sets
,
True
)
# start from the current registers state
if
unlock_needed
:
self
.
slcr_unlock
()
_
=
clk_register_set
.
get_register_sets
(
True
,
True
)
# close previous register settings
clk_register_set
.
flush
(
)
# close previous register settings
# Bypass used PLL-s - stage 1 of PLL setup
self
.
clocks_pll_bypass
(
force
=
False
,
warn
=
False
)
_
=
clk_register_set
.
get_register_sets
(
True
,
True
)
# close previous register settings
clk_register_set
.
flush
(
)
# close previous register settings
# Turn on PLL reset and program feedback - stage 2 of PLL setup
self
.
clocks_pll_reset_and_fdiv
(
force
=
False
,
warn
=
False
)
_
=
clk_register_set
.
get_register_sets
(
True
,
True
)
# close previous register settings
clk_register_set
.
flush
(
)
# close previous register settings
# Configure PLL parameters - stage 3 of PLL setup
self
.
clocks_pll_conf
(
force
=
False
,
warn
=
False
)
_
=
clk_register_set
.
get_register_sets
(
True
,
True
)
# close previous register settings
clk_register_set
.
flush
(
)
# close previous register settings
# Release reset of the PLLs (let them start) - stage 4 of PLL setup
self
.
clocks_pll_start
(
force
=
False
,
warn
=
False
)
_
=
clk_register_set
.
get_register_sets
(
True
,
True
)
# close previous register settings
clk_register_set
.
flush
(
)
# close previous register settings
# stage 5 of clocks setup
self
.
clocks_program
(
force
=
False
,
warn
=
False
)
# #Trying toggle feature (but actually for now it can be left in reset state - is this on/off/on needed?
# _ = ddriob_register_set.get_register_sets(True,True) # close previous register settings
# ddriob_register_set.set_bitfields('ddriob_dci_ctrl', ('reset',1),force,warn)
# _ = ddriob_register_set.get_register_sets(True,True) # close previous register settings
# ddriob_register_set.set_bitfields('ddriob_dci_ctrl', ('reset',0),force,warn)
# _ = ddriob_register_set.get_register_sets(True,True) # close previous register settings
# ddriob_register_set.set_bitfields('ddriob_dci_ctrl', (('reset', 1),
# ('enable',1),
# ('nref_opt1',0),
# ('nref_opt2',0),
# ('nref_opt4',1),
# ('pref_opt2',0),
# ('update_control',0)),force,warn)
return
self
.
get_new_register_sets
()
#Unlock SLCR (if the code is running after RBL) - stage 0 of PLL setup
def
slcr_unlock
(
self
):
...
...
@@ -528,6 +517,17 @@ class EzynqClk:
def
clocks_pll_bypass_off
(
self
,
current_reg_sets
,
force
=
False
,
warn
=
False
):
clk_register_set
=
self
.
clk_register_set
clk_register_set
.
set_initial_state
(
current_reg_sets
,
True
)
# start from the current registers state
# add wait for DCI calibration DONE
# ddriob_register_set.wait_reg_field_values('ddriob_dci_status',('done',1), True, warn)
bits
=
[]
if
'ARM'
in
self
.
pll_fdivs
:
bits
.
append
((
'arm_pll_lock'
,
1
))
if
'DDR'
in
self
.
pll_fdivs
:
bits
.
append
((
'ddr_pll_lock'
,
1
))
if
'IO'
in
self
.
pll_fdivs
:
bits
.
append
((
'io_pll_lock'
,
1
))
clk_register_set
.
wait_reg_field_values
(
'pll_status'
,
tuple
(
bits
),
True
,
warn
)
if
'DDR'
in
self
.
pll_fdivs
:
clk_register_set
.
set_bitfields
(
'ddr_pll_ctrl'
,((
'pll_bypass_force'
,
0
),
...
...
@@ -538,6 +538,8 @@ class EzynqClk:
if
'ARM'
in
self
.
pll_fdivs
:
clk_register_set
.
set_bitfields
(
'arm_pll_ctrl'
,((
'pll_bypass_force'
,
0
),
(
'pll_bypass_qual'
,
0
)),
force
,
warn
)
return
self
.
get_new_register_sets
()
#clocks setup
def
clocks_program
(
self
,
force
=
False
,
warn
=
False
):
...
...
@@ -869,6 +871,7 @@ class EzynqClk:
# reg uart_clk_ctrl, offs=0x154 dflt:0x3f03 actual: 0xa02
if
'UART'
in
self
.
iface_divs
:
print
self
.
iface_divs
[
'UART'
]
if
self
.
iface_divs
[
'UART'
][
'PLL'
]
==
'ARM'
:
uart_srcsel
=
2
elif
self
.
iface_divs
[
'UART'
][
'PLL'
]
==
'DDR'
:
...
...
ezynq_ddr.py
View file @
01e77ff5
...
...
@@ -253,6 +253,8 @@ class EzynqDDR:
ddrc_register_set
=
self
.
ddrc_register_set
ddrc_register_set
.
set_initial_state
(
current_reg_sets
,
True
)
ddrc_register_set
.
set_bitfields
(
'ddrc_ctrl'
,((
'reg_ddrc_soft_rstb'
,
0x1
)),
force
,
warn
)
# add wait for DDR ready
ddrc_register_set
.
wait_reg_field_values
(
'mode_sts_reg'
,(
'ddrc_reg_operating_mode'
,
0
),
False
,
warn
)
return
ddrc_register_set
.
get_register_sets
(
True
,
True
)
def
ddr_init_memory
(
self
,
current_reg_sets
,
force
=
False
,
warn
=
False
):
...
...
@@ -1328,9 +1330,9 @@ class EzynqDDR:
ddriob_register_set
=
self
.
ddriob_register_set
ddriob_register_set
.
set_initial_state
(
current_reg_sets
,
True
)
# start from the current registers state
ddriob_register_set
.
set_bitfields
(
'ddriob_dci_ctrl'
,
(
'reset'
,
1
),
force
,
warn
)
_
=
ddriob_register_set
.
get_register_sets
(
True
,
True
)
# close previous register settings
ddriob_register_set
.
flush
(
)
# close previous register settings
ddriob_register_set
.
set_bitfields
(
'ddriob_dci_ctrl'
,
(
'reset'
,
0
),
force
,
warn
)
_
=
ddriob_register_set
.
get_register_sets
(
True
,
True
)
# close previous register settings
ddriob_register_set
.
flush
()
# close previous register settings
ddriob_register_set
.
set_bitfields
(
'ddriob_dci_ctrl'
,
((
'reset'
,
1
),
(
'enable'
,
1
),
(
'nref_opt1'
,
0
),
...
...
@@ -1338,6 +1340,9 @@ class EzynqDDR:
(
'nref_opt4'
,
1
),
(
'pref_opt2'
,
0
),
(
'update_control'
,
0
)),
force
,
warn
)
# add wait for DCI calibration DONE
ddriob_register_set
.
wait_reg_field_values
(
'ddriob_dci_status'
,(
'done'
,
1
),
True
,
warn
)
return
ddriob_register_set
.
get_register_sets
(
True
,
True
)
# close previous register settings, return new result
...
...
@@ -1443,24 +1448,6 @@ class EzynqDDR:
(
'slew_p'
,
self
.
features
.
get_par_value
(
'BIDIR_SLEW_POS'
)),
(
'drive_n'
,
self
.
features
.
get_par_value
(
'BIDIR_DRIVE_NEG'
)),
(
'drive_p'
,
self
.
features
.
get_par_value
(
'BIDIR_DRIVE_POS'
))),
force
,
warn
)
#0xf9861c
#
# #Trying toggle feature (but actually for now it can be left in reset state - is this on/off/on needed?
# _ = ddriob_register_set.get_register_sets(True,True) # close previous register settings
# # ddriob_register_set.set_bitfields('ddriob_dci_ctrl', ('vrn_out',0),force,warn) # default value shows 1, actual settings - 0 (first time only?)
# #
# # Do in u-boot. When moving - use UG585 table 10-7 to set options
# #
# ddriob_register_set.set_bitfields('ddriob_dci_ctrl', ('reset',1),force,warn)
# _ = ddriob_register_set.get_register_sets(True,True) # close previous register settings
# ddriob_register_set.set_bitfields('ddriob_dci_ctrl', ('reset',0),force,warn)
# _ = ddriob_register_set.get_register_sets(True,True) # close previous register settings
# ddriob_register_set.set_bitfields('ddriob_dci_ctrl', (('reset', 1),
# ('enable',1),
# ('nref_opt1',0),
# ('nref_opt2',0),
# ('nref_opt4',1),
# ('pref_opt2',0),
# ('update_control',0)),force,warn)
#TODO: Remove?
...
...
ezynq_ddrc_defs.py
View file @
01e77ff5
...
...
@@ -194,7 +194,7 @@ DDRC_DEFS={ #not all fields are defined currently
'reg_phy_rdc_we_to_re_delay'
:
{
'r'
:(
8
,
11
),
'd'
:
0x2
,
'c'
:
'use for fixed delay, when reg_phy_use_fixed_re==1'
},
#0x8
'reg_phy_wr_cmd_to_data'
:
{
'r'
:(
4
,
7
),
'd'
:
0
,
'c'
:
'Not used in DFI PHY'
},
'reg_phy_rd_cmd_to_data'
:
{
'r'
:(
0
,
3
),
'd'
:
0
,
'c'
:
'Not used in DFI PHY'
}}},
'mode_sts_reg'
:
{
'OFFS'
:
0x054
,
'DFLT'
:
0x00000000
,
'RW'
:
'R'
,
'FIELDS'
:{
'mode_sts_reg'
:
{
'OFFS'
:
0x054
,
'DFLT'
:
0x00000000
,
'RW'
:
'R'
,
'
COMMENTS'
:
'DDR Controller status'
,
'
FIELDS'
:{
'ddrc_reg_dbg_hpr_q_depth'
:
{
'r'
:(
16
,
20
),
'd'
:
0
,
'm'
:
'R'
,
'c'
:
'number in high priority read CAM'
},
'ddrc_reg_dbg_lpr_q_depth'
:
{
'r'
:(
10
,
15
),
'd'
:
0
,
'm'
:
'R'
,
'c'
:
'number in low priority read CAM'
},
'ddrc_reg_dbg_wr_q_depth'
:
{
'r'
:(
4
,
9
),
'd'
:
0
,
'm'
:
'R'
,
'c'
:
'number in write CAM '
},
...
...
ezynq_feature_config.py
View file @
01e77ff5
...
...
@@ -287,6 +287,9 @@ class EzynqFeatures:
else
:
par_type
=
{
'H'
:
'Integer'
,
'I'
:
'Integer'
,
'F'
:
'Float'
,
'B'
:
'Boolean'
,
'T'
:
'Text'
}[
feature
[
'TYPE'
]]
# if name=='BAUD_RATE':
# print value
html_file
.
write
(
'<tr><th>'
+
feature
[
'CONF_NAME'
]
+
'</th><td>'
+
str
(
value
)
+
'</td><td>'
+
par_type
+
'</td><td>'
+
(
'-'
,
'Y'
)[
feature
[
'MANDATORY'
]]
+
'</td><td>'
+
origin
+
'</td><td>'
+
str
(
feature
[
'DEFAULT'
])
+
'</td><td>'
+
feature
[
'DESCRIPTION'
]
+
'</td></tr>
\n
'
)
html_file
.
write
(
'</table>
\n
'
)
...
...
ezynq_registers.py
View file @
01e77ff5
This diff is collapsed.
Click to expand it.
ezynq_uboot.py
View file @
01e77ff5
...
...
@@ -46,14 +46,26 @@ class EzynqUBoot:
self
.
sections
=
[
'license'
,
'include'
]
def
get_c_file
(
self
):
return
self
.
cfile
def
_opt_hex
(
self
,
d
):
if
d
<
10
:
return
str
(
d
)
else
:
return
hex
(
d
)
def
_add_reg_writes
(
self
,
reg_sets
):
for
addr
,
data
,
_
,
module_name
,
register_name
,
r_def
in
reg_sets
:
for
op
,
addr
,
data
,
mask
,
module_name
,
register_name
,
r_def
in
reg_sets
:
try
:
comments
=
r_def
[
'COMMENTS'
]
except
:
comments
=
''
self
.
cfile
+=
'
\t
writel(0x
%08
x, 0x
%08
x); /*
%
s.
%
s
%
s */
\n
'
%
(
data
,
addr
,
module_name
,
register_name
,
comments
)
if
op
==
's'
:
self
.
cfile
+=
'
\t
writel(0x
%08
x, 0x
%08
x); /*
%
s.
%
s
%
s */
\n
'
%
(
data
,
addr
,
module_name
,
register_name
,
comments
)
elif
op
==
'='
:
self
.
cfile
+=
'
\t
while((readl(0x
%08
x) &
%
s) !=
%
s); /*
%
s.
%
s
%
s */
\n
'
%
(
addr
,
self
.
_opt_hex
(
mask
),
self
.
_opt_hex
(
data
),
module_name
,
register_name
,
comments
)
elif
op
==
'!'
:
self
.
cfile
+=
'
\t
while((readl(0x
%08
x) &
%
s) ==
%
s); /*
%
s.
%
s
%
s */
\n
'
%
(
addr
,
self
.
_opt_hex
(
mask
),
self
.
_opt_hex
(
data
),
module_name
,
register_name
,
comments
)
else
:
raise
Exception
(
'Invalid register operation "
%
s" specified for register 0x
%08
x, data=0x
%08
x, mask=0x
%08
x'
%
(
op
,
addr
,
data
,
mask
))
def
registers_setup
(
self
,
reg_sets
,
clk
,
num_rbl_regs
):
#clk is an instance of ezynq_clk.EzynqClk
self
.
sections
.
append
(
'registers_setup'
)
...
...
@@ -69,71 +81,66 @@ inline void register_setup(void)
self
.
cfile
+=
'}
\n\n
'
def
pll_setup
(
self
,
reg_sets
,
clk
):
#clk is an instance of ezynq_clk.EzynqClk
pll_status_comment
=
clk
.
clk_register_set
.
get_register_comments
(
'pll_status'
)
pll_arm
=
clk
.
clk_register_set
.
get_bitfield_address_mask_comments
(
'pll_status'
,
'arm_pll_lock'
)
pll_ddr
=
clk
.
clk_register_set
.
get_bitfield_address_mask_comments
(
'pll_status'
,
'ddr_pll_lock'
)
pll_io
=
clk
.
clk_register_set
.
get_bitfield_address_mask_comments
(
'pll_status'
,
'io_pll_lock'
)
address
=
pll_arm
[
0
]
mask
=
0
pll_used
=
clk
.
get_plls_used
()
for
pll
,
pll_tuple
in
zip
([
'ARM'
,
'DDR'
,
'IO'
],[
pll_arm
,
pll_ddr
,
pll_io
]):
if
pll
in
pll_used
:
mask
|=
pll_tuple
[
1
]
if
mask
==
0
:
print
'No PLLs are used, skipping generating pll_setup()'
return
self
.
sections
.
append
(
'pll_setup'
)
self
.
cfile
+=
'''/* Wait for PLLs locked:
%
s
*/
self
.
cfile
+=
'''/* Wait for PLLs locked:*/
inline void pll_setup(void)
{
\t
/* Wait for all PLLs locked */
\t
while ((readl (0x
%
x) & 0x
%
x) != 0x
%
x); /* slcr.pll_status
%
s */
\t
/* release PLL bypass on each PLL */
'''
%
(
str
(
pll_used
),
address
,
mask
,
mask
,
pll_status_comment
)
\t
/* Wait for all used PLLs locked, then release PLL bypass on each PLL */
'''
self
.
_add_reg_writes
(
reg_sets
)
self
.
cfile
+=
'}
\n\n
'
def
uart_init
(
self
,
reg_sets
,
clk
):
self
.
sections
.
append
(
'uart_init'
)
self
.
cfile
+=
'''/* Initilize UART to output debug info during boot */
inline void uart_init(void)
{
\t
/* Wait for all used PLLs locked, then release PLL bypass on each PLL */
'''
self
.
_add_reg_writes
(
reg_sets
)
self
.
cfile
+=
'}
\n\n
'
def
dci_calibration
(
self
,
reg_sets
,
ddr
):
#ddr is an instance of ezynq_ddr.EzynqDDR
if
len
(
reg_sets
)
==
0
:
print
'No DCI calibration register data is provided, skipping generating dci_calibration()'
return
dci_status_comment
=
ddr
.
ddriob_register_set
.
get_register_comments
(
'ddriob_dci_status'
)
address
,
mask
,
_
=
ddr
.
ddriob_register_set
.
get_bitfield_address_mask_comments
(
'ddriob_dci_status'
,
'done'
)
self
.
cfile
+=
'''/* Calibrate DDR DCI, wait for completion */
inline void dci_calibration(void)
{
\t
/* Toggle active-low DCI reset, initialize DCI calibration */
\t
/* Toggle active-low DCI reset, initialize DCI calibration
, wait for DONE
*/
'''
self
.
_add_reg_writes
(
reg_sets
)
self
.
cfile
+=
'''
\t
/* Wait DCI calibration is DONE */
\t
while ((readl (0x
%
x) & 0x
%
x) != 0x
%
x); /* slcr.ddriob_dci_status
%
s */
'''
%
(
address
,
mask
,
mask
,
dci_status_comment
)
self
.
cfile
+=
'}
\n\n
'
self
.
sections
.
append
(
'dci_calibration'
)
def
ddr_start
(
self
,
reg_sets
,
ddr
):
#ddr is an instance of ezynq_ddr.EzynqDDR
if
len
(
reg_sets
)
==
0
:
print
'No DDR start data is provided, skipping generating ddr_start()'
return
ddrc_status_comment
=
ddr
.
ddrc_register_set
.
get_register_comments
(
'mode_sts_reg'
)
address
,
mask
,
_
=
ddr
.
ddrc_register_set
.
get_bitfield_address_mask_comments
(
'mode_sts_reg'
,
'ddrc_reg_operating_mode'
)
self
.
cfile
+=
'''/* Start DDRC, wait for initialization complete */
inline void ddr_start(void)
{
\t
/* Release DDRC active-low reset */
'''
self
.
_add_reg_writes
(
reg_sets
)
self
.
cfile
+=
'''
\t
/* DDRC operation mode is INITIALIZED */
\t
while ((readl (0x
%
x) & 0x
%
x) == 0); /* ddrc.mode_sts_reg
%
s */
'''
%
(
address
,
mask
,
ddrc_status_comment
)
self
.
cfile
+=
'}
\n\n
'
self
.
sections
.
append
(
'ddr_start'
)
def
make_lowlevel_init
(
self
):
self
.
cfile
+=
'''/* Initialize clocks, DDR memory, copy OCM to DDR */
void lowlevel_init(void)
{
/*
'''
if
'uart_init'
in
self
.
sections
:
self
.
cfile
+=
'''/* Initialize UART fdro debug information output */
\t
uart_init();
'''
self
.
cfile
+=
'''/*
Unlock SLCR and write PLL and clocks registers as the code is now running in the OCM and no
peripherals are needed
*/
...
...
ezynqcfg.py
View file @
01e77ff5
This diff is collapsed.
Click to expand it.
test.mk
View file @
01e77ff5
#COnfiguration for the microzed board
CONFIG_EZYNQ_BOOT_DEBUG=y # configure UARTx and send register dumps there
CONFIG_EZYNQ_LED_DEBUG=47 # toggle LED during boot
CONFIG_EZYNQ_UART1_BAUD_RATE=115200
#Configuration for the microzed board
CONFIG_EZYNQ_MIO_0_VOLT=3.3
CONFIG_EZYNQ_MIO_1_VOLT=1.8
#CONFIG_EZYNQ_MIO_0_PULLUP=y #default pullup for MIO0 - may be overwritten for individual pins
...
...
@@ -86,20 +90,6 @@ CONFIG_EZYNQ_START_EXEC= 0x00 # start of execution address
#just software testing - remove later
#CONFIG_EZYNQ_DDR_SETREG_ctrl_reg1__reg_ddrc_selfref_en_PRE = 1
#CONFIG_EZYNQ_DDR_SETREG_ctrl_reg1__reg_ddrc_lpr_num_entries_PRE = 5
#CONFIG_EZYNQ_DDR_SETREG_phy_wr_dqs_cfg0_PRE = 0xAAAAA
#CONFIG_EZYNQ_DDR_SETREG_phy_wr_dqs_cfg0__reg_phy_wr_dqs_slave_delay_PRE = 0x77
#CONFIG_EZYNQ_DDR_ARB_PAGE_BANK = N # Y # default N, testing
# not yet processed
CONFIG_EZYNQ_DCI_PERIPHERAL_FREQMHZ = 10.158731 # Taking available CLK and divisors into account?
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment