Commit ea7d60dc authored by Andrey Filippov's avatar Andrey Filippov

implemented more debug features during boot

parent d38a7e9f
...@@ -29,8 +29,8 @@ class EzynqFeatures: ...@@ -29,8 +29,8 @@ class EzynqFeatures:
'ERR_NOT_A_FLOAT': 'Value is not a float', 'ERR_NOT_A_FLOAT': 'Value is not a float',
'ERR_NOT_A_BOOLEAN': 'Value is not a boolean' 'ERR_NOT_A_BOOLEAN': 'Value is not a boolean'
} }
BOOLEANS=(('0','FALSE','DISABLE','DISABLED','N'), BOOLEANS=(('0','FALSE','DISABLE','DISABLED','N','OFF'),
('1','TRUE', 'ENABLE','ENABLED','Y')) ('1','TRUE', 'ENABLE','ENABLED','Y','ON'))
# defines - a list, order determines HTML output order # defines - a list, order determines HTML output order
# Each element has fields: # Each element has fields:
# 'NAME' - unique name to access this parameter # 'NAME' - unique name to access this parameter
...@@ -146,9 +146,10 @@ class EzynqFeatures: ...@@ -146,9 +146,10 @@ class EzynqFeatures:
all_set=False all_set=False
print "Configuration file is missing mandatory parameter "+self.defs[name]['CONF_NAME']+': '+self.defs[name]['DESCRIPTION'] print "Configuration file is missing mandatory parameter "+self.defs[name]['CONF_NAME']+': '+self.defs[name]['DESCRIPTION']
else: else:
if not self.defs[name]['DEFAULT'] is None:
# use default parameter # use default parameter
# print 'Adding default : ',name,'=', self.defs[name]['DEFAULT'] # print 'Adding default : ',name,'=', self.defs[name]['DEFAULT']
self.pars[name]=self.defs[name]['DEFAULT'] self.pars[name]=self.defs[name]['DEFAULT']
return all_set return all_set
def get_par_names(self): def get_par_names(self):
# name_offs=sorted([(name,self.registers[name]['OFFS']) for name in self.registers], key = lambda l: l[1]) # name_offs=sorted([(name,self.registers[name]['OFFS']) for name in self.registers], key = lambda l: l[1])
...@@ -174,6 +175,16 @@ class EzynqFeatures: ...@@ -174,6 +175,16 @@ class EzynqFeatures:
except: except:
raise Exception (name+' not found in self.defs') # should not happen with wrong data, program bug raise Exception (name+' not found in self.defs') # should not happen with wrong data, program bug
def get_par_value_or_none(self,name):
try:
return self.pars[name]
except:
try:
_=self.defs[name]['CONF_NAME']
except:
raise Exception (name+' not found in self.defs') # should not happen with wrong data, program bug
return
def get_par_value(self,name): def get_par_value(self,name):
try: try:
return self.pars[name] return self.pars[name]
...@@ -222,6 +233,10 @@ class EzynqFeatures: ...@@ -222,6 +233,10 @@ class EzynqFeatures:
def is_specified(self,name): # directly specified def is_specified(self,name): # directly specified
return name in self.defined return name in self.defined
def undefine_parameter(self,name):
if name in self.pars:
self.pars[name]=None
def set_calculated_value(self,name,value,force=True): def set_calculated_value(self,name,value,force=True):
if (not force) and (name in self.defined): if (not force) and (name in self.defined):
...@@ -255,11 +270,14 @@ class EzynqFeatures: ...@@ -255,11 +270,14 @@ class EzynqFeatures:
# name= self.config_names[conf_name] # name= self.config_names[conf_name]
feature= self.defs[name] feature= self.defs[name]
value= self.get_par_value(name) value= self.get_par_value(name)
if isinstance(value,int): if value is None:
if (feature['TYPE']=='H'): value='None'
value=hex(value) else:
else: if isinstance(value,int):
value=str(value) if (feature['TYPE']=='H'):
value=hex(value)
else:
value=str(value)
try: try:
target_value=self.get_par_target(name) target_value=self.get_par_target(name)
if isinstance(target_value,int): if isinstance(target_value,int):
......
...@@ -299,6 +299,16 @@ class EzynqMIO: ...@@ -299,6 +299,16 @@ class EzynqMIO:
('tri_enable', 1))) # ,force,warn) ('tri_enable', 1))) # ,force,warn)
return led_register_set.get_register_sets(sort_addr=True,apply_new=True) return led_register_set.get_register_sets(sort_addr=True,apply_new=True)
def rbl_led_on_off(self, mio_pin, led_on, reg_sets):
# generate code to be included in RBL register setup
if led_on:
led_on=1
led_register_set= ezynq_registers.EzynqRegisters(self.MIO_PINS_DEFS,0,reg_sets)
led_register_set.set_bitfields('mio_pin_%02i'%mio_pin, ( # output 0 - LED off
('pullup', 1-led_on),
('tri_enable', 1-led_on))) # ,force,warn)
return led_register_set.get_register_sets(sort_addr=True,apply_new=True)
def parse_config_mio(self,raw_configs): def parse_config_mio(self,raw_configs):
attrib_suffix='ATTRIB' attrib_suffix='ATTRIB'
options = {} options = {}
......
...@@ -45,12 +45,12 @@ class EzynqUART: ...@@ -45,12 +45,12 @@ class EzynqUART:
self.channel=None self.channel=None
return return
self.channel=max(uarts) self.channel=max(uarts)
self.features=ezynq_feature_config.EzynqFeatures(self.UART_CFG_DEFS,self.channel) #DDR_CFG_DEFS self.features=ezynq_feature_config.EzynqFeatures(self.UART_CFG_DEFS,self.channel)
self.features.parse_features(raw_configs) self.features.parse_features(raw_configs)
if len(uarts)>1: if len(uarts)>1:
if 'DEBUG_CHANNEL' in self.features.pars: if 'DEBUG_CHANNEL' in self.features.pars:
self.channel=self.features.pars['DEBUG_CHANNEL'] self.channel=self.features.pars['DEBUG_CHANNEL']
self.features=ezynq_feature_config.EzynqFeatures(self.UART_CFG_DEFS,self.channel) #DDR_CFG_DEFS self.features=ezynq_feature_config.EzynqFeatures(self.UART_CFG_DEFS,self.channel)
self.features.parse_features(raw_configs) self.features.parse_features(raw_configs)
self.uart_register_set= ezynq_registers.EzynqRegisters(self.UART_DEFS,self.channel,[],permit_undefined_bits) self.uart_register_set= ezynq_registers.EzynqRegisters(self.UART_DEFS,self.channel,[],permit_undefined_bits)
self.slcr_register_set= ezynq_registers.EzynqRegisters(self.SLCR_CLK_DEFS,0,[],permit_undefined_bits) self.slcr_register_set= ezynq_registers.EzynqRegisters(self.SLCR_CLK_DEFS,0,[],permit_undefined_bits)
...@@ -98,7 +98,23 @@ class EzynqUART: ...@@ -98,7 +98,23 @@ class EzynqUART:
self.bdiv,self.cd,self.baud_rate=get_bdiv_cd_baud(self.baud_rate,min_bdiv) self.bdiv,self.cd,self.baud_rate=get_bdiv_cd_baud(self.baud_rate,min_bdiv)
self.features.set_calculated_value('BAUD_RATE',self.baud_rate,force=True) self.features.set_calculated_value('BAUD_RATE',self.baud_rate,force=True)
# these instructions will be usen to generate C code.
# when defined here (as register writes/tests) they will appear in the overall list
# of registers (HTML file)
def set_uart_codes(self):
uart_extra_set= ezynq_registers.EzynqRegisters(self.UART_DEFS,self.channel,[])
# wait transmitter FIFO empty (use before proceeding to risky of reboot code )
uart_extra_set.wait_reg_field_values('channel_sts', # Channel status
(('tempty', 1)), True) # Transmitter FIFO empty (continuous)
uart_extra_set.flush() # to separate codes, not to combine in one write
# wait transmitter FIFO not full (OK to put more characters)
uart_extra_set.wait_reg_field_values('channel_sts', # Channel status
(('tful', 0)), True) # Transmitter FIFO full (continuous)
uart_extra_set.flush()
uart_extra_set.set_bitfields('tx_rx_fifo',( # TX/RX FIFO character data write/read
('fifo', self.cd)),True) # read/write FIFO character data
return uart_extra_set.get_register_sets(sort_addr=True,apply_new=True)
def setup_uart(self,current_reg_sets,force=False,warn=False): def setup_uart(self,current_reg_sets,force=False,warn=False):
...@@ -157,89 +173,3 @@ class EzynqUART: ...@@ -157,89 +173,3 @@ class EzynqUART:
('rxres', 0)), True, warn) ('rxres', 0)), True, warn)
return uart_register_set.get_register_sets(sort_addr=True,apply_new=True) return uart_register_set.get_register_sets(sort_addr=True,apply_new=True)
#
#
# 'channel_sts': {'OFFS': 0x02c,'DFLT':0x0,'RW':'R',
# 'COMMENTS':'Channel status',
# 'FIELDS':{
# 'reserved1': {'r':(15,31),'d':0,'m':'R'},
# 'tnful': {'r':(14,14),'d':0,'m':'R', 'c':'Transmitter FIFO nearly full'},
# 'ttrig': {'r':(13,13),'d':0,'m':'R', 'c':'Transmitter FIFO level >= preset TTRIG value'},
# 'fdelt': {'r':(12,12),'d':0,'m':'R', 'c':'Receiver FIFO level >= preset FDEL value'},
# 'tactive': {'r':(11,11),'d':0,'m':'R', 'c':'Transmitter active'},
# 'ractive': {'r':(10,10),'d':0,'m':'R', 'c':'Receiver active'},
# 'reserved2': {'r':( 9, 9),'d':0,'m':'R', 'c':''},
# 'reserved3': {'r':( 8, 8),'d':0,'m':'R', 'c':''},
# 'reserved4': {'r':( 7, 7),'d':0,'m':'R', 'c':''},
# 'reserved5': {'r':( 6, 6),'d':0,'m':'R', 'c':''},
# 'reserved6': {'r':( 5, 5),'d':0,'m':'R', 'c':''},
# 'tful': {'r':( 4, 4),'d':0,'m':'R', 'c':'Transmitter FIFO full (continuous)'},
# 'tempty': {'r':( 3, 3),'d':0,'m':'R', 'c':'Transmitter FIFO empty (continuous)'},
# 'rful': {'r':( 2, 2),'d':0,'m':'R', 'c':'Receiver FIFO full (continuous)'},
# 'rempty': {'r':( 1, 1),'d':0,'m':'R', 'c':'Receiver FIFO empty (continuous)'},
# 'rtrig': {'r':( 0, 0),'d':0,'m':'R', 'c':'Receiver FIFO level >= preset RTRIG value (continuous)'}}},
# 'uart_rst_ctrl': {'OFFS': 0x228,'DFLT':0,'RW':'RW', # Never set
# 'COMMENTS':'UART software reset control for reference clock and CPU_1x (AMBA) clock domains',
# 'FIELDS':{
# 'reserved': {'r':( 4,31),'d':0, 'c':'reserved'},
# 'uart1_ref_rst': {'r':( 3, 3),'d':0, 'c':'UART 1 reference clock domain reset: 0 - normal, 1 - reset'},
# 'uart0_ref_rst': {'r':( 2, 2),'d':0, 'c':'UART 0 reference clock domain reset: 0 - normal, 1 - reset'},
# 'uart1_cpu1x_rst': {'r':( 1, 1),'d':0, 'c':'UART 1 CPU_1x clock domain (AMBA) reset: 0 - normal, 1 - reset'},
# 'uart0_cpu1x_rst': {'r':( 0, 0),'d':0, 'c':'UART 0 CPU_1x clock domain (AMBA) reset: 0 - normal, 1 - reset'}}},
#MIN_SAMPLES_PER_BIT
# 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),
# ('pll_bypass_qual', 0)),force,warn)
# writel(0x0000000f, &slcr_base->uart_rst_ctrl); /* UART reset on */
#
# //&slcr_base->uart_rst_ctrl
# // writel(0x0000000f, &slcr_base->uart_rst_ctrl); /* UART reset on */
# /* delay ??? move reset on earlier?*/
# writel(0x00000000, &slcr_base->uart_rst_ctrl); /* UART reset off */
#
# /* uart 1 */
# writel(0x00000020, &uart1_base->mode); /* UART character frame */
# /* a. Disable the Rx path: set uart.Control_reg0 [RXEN] = 0 and [RXDIS] = 1.
# b. Disable the Txpath: set uart.Control_reg0 [TXEN] = 0 and [TXDIS] = 1. */
# writel(0x00000028, &uart1_base->control); /*a,b */
# /* c. Write the calculated CD value into the uart.Baud_rate_gen_reg0 [CD] bit field. */
# writel(12, &uart1_base->baud_rate_gen); /*c - for 25MHz and 115200 CD=12, (BDIV+1)=18 */
# /* d. Write the calculated BDIV value into the uart.Baud_rate_divider_reg0 [BDIV] bit value. */
# writel(17, &uart1_base->baud_rate_div); /*d - for 25MHz and 115200 CD=12, (BDIV+1)=18 */
# writel(0x117, &uart1_base->control); /* restart and enable ug585v1.6.1. p 555 */
# writel(0x14, &uart1_base->control); /*just a delay - 1-st character is usually lost */
# def ddr_dci_calibrate(self,current_reg_sets,force=False,warn=False):
# 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.flush() # close previous register settings
# ddriob_register_set.set_bitfields('ddriob_dci_ctrl', ('reset',0),force,warn)
# ddriob_register_set.flush()# 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)
# # 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
...@@ -131,6 +131,12 @@ UART_DEFS={ #not all fields are defined currently ...@@ -131,6 +131,12 @@ UART_DEFS={ #not all fields are defined currently
'rful': {'r':( 2, 2),'d':0,'m':'R', 'c':'Receiver FIFO full (continuous)'}, 'rful': {'r':( 2, 2),'d':0,'m':'R', 'c':'Receiver FIFO full (continuous)'},
'rempty': {'r':( 1, 1),'d':0,'m':'R', 'c':'Receiver FIFO empty (continuous)'}, 'rempty': {'r':( 1, 1),'d':0,'m':'R', 'c':'Receiver FIFO empty (continuous)'},
'rtrig': {'r':( 0, 0),'d':0,'m':'R', 'c':'Receiver FIFO level >= preset RTRIG value (continuous)'}}}, 'rtrig': {'r':( 0, 0),'d':0,'m':'R', 'c':'Receiver FIFO level >= preset RTRIG value (continuous)'}}},
'tx_rx_fifo': {'OFFS': 0x030,'DFLT':0,'RW':'RW',
'COMMENTS':'TX/RX FIFO character data write/read',
'FIELDS':{
'reserved': {'r':( 8,31),'d':0},
'fifo': {'r':( 0, 7),'d':0, 'c':'read/write FIFO character data'}}},
'baud_rate_div': {'OFFS': 0x034,'DFLT':0xf,'RW':'RW', 'baud_rate_div': {'OFFS': 0x034,'DFLT':0xf,'RW':'RW',
'COMMENTS':'Number of bit sample periods minus 1', 'COMMENTS':'Number of bit sample periods minus 1',
......
...@@ -21,7 +21,76 @@ __version__ = "3.0+" ...@@ -21,7 +21,76 @@ __version__ = "3.0+"
__maintainer__ = "Andrey Filippov" __maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com" __email__ = "andrey@elphel.com"
__status__ = "Development" __status__ = "Development"
import os
#import ezynq_clk #import ezynq_clk
import ezynq_feature_config
#Use 'TYPE':'I' for decimal output, 'H' - for hex. On input both are accepted
UBOOT_CFG_DEFS=[
{'NAME':'BOOT_DEBUG', 'CONF_NAME':'CONFIG_EZYNQ_BOOT_DEBUG','TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':False,
'DESCRIPTION':'Enable debug features during boot'},
{'NAME':'LED_DEBUG', 'CONF_NAME':'CONFIG_EZYNQ_LED_DEBUG','TYPE':'I','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'Specify MIO pin to use for debug purposed during boot process'},
{'NAME':'UART_DEBUG_USE_LED', 'CONF_NAME':'CONFIG_EZYNQ_UART_DEBUG_USE_LED','TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':False,
'DESCRIPTION':'Turn debug LED off/on while waiting for UART FIFO not full'},
{'NAME':'DUMP_SLCR_EARLY', 'CONF_NAME':'CONFIG_EZYNQ_DUMP_SLCR_EARLY','TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':False,
'DESCRIPTION':'Dump SLCR registers as soon as UART is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG)'},
{'NAME':'DUMP_DDRC_EARLY', 'CONF_NAME':'CONFIG_EZYNQ_DUMP_DDRC_EARLY','TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':False,
'DESCRIPTION':'Dump DDRC registers as soon as UART is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG)'},
{'NAME':'DUMP_SLCR_LATE', 'CONF_NAME':'CONFIG_EZYNQ_DUMP_SLCR_LATE','TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':False,
'DESCRIPTION':'Dump SLCR registers after DDR memory is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG)'},
{'NAME':'DUMP_DDRC_LATE', 'CONF_NAME':'CONFIG_EZYNQ_DUMP_DDRC_LATE','TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':False,
'DESCRIPTION':'Dump DDRC registers after DDR memory is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG)'},
{'NAME':'LED_CHECKPOINT_1', 'CONF_NAME':'CONFIG_EZYNQ_LED_CHECKPOINT_1', 'TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'LED ON/OFF in RBL (just after MIO is set up)'},
{'NAME':'LED_CHECKPOINT_2', 'CONF_NAME':'CONFIG_EZYNQ_LED_CHECKPOINT_2', 'TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'LED ON/OFF first after getting to user code'},
{'NAME':'LED_CHECKPOINT_3', 'CONF_NAME':'CONFIG_EZYNQ_LED_CHECKPOINT_3', 'TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'LED ON/OFF first after getting to user code'},
{'NAME':'LED_CHECKPOINT_4', 'CONF_NAME':'CONFIG_EZYNQ_LED_CHECKPOINT_4', 'TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'LED ON/OFF after PLL bypass is OFF'},
{'NAME':'LED_CHECKPOINT_5', 'CONF_NAME':'CONFIG_EZYNQ_LED_CHECKPOINT_5', 'TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'LED ON/OFF after UART is programmed'},
{'NAME':'LED_CHECKPOINT_6', 'CONF_NAME':'CONFIG_EZYNQ_LED_CHECKPOINT_6', 'TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'LED ON/OFF after DCI is calibrated'},
{'NAME':'LED_CHECKPOINT_7', 'CONF_NAME':'CONFIG_EZYNQ_LED_CHECKPOINT_7', 'TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'LED ON/OFF after DDR is initialized'},
{'NAME':'LED_CHECKPOINT_8', 'CONF_NAME':'CONFIG_EZYNQ_LED_CHECKPOINT_8', 'TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'LED ON/OFF before relocation to DDR (to 0x4000000+ )'},
{'NAME':'LED_CHECKPOINT_9', 'CONF_NAME':'CONFIG_EZYNQ_LED_CHECKPOINT_9', 'TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'LED ON/OFF after relocation to DDR (to 0x4000000+ )'},
{'NAME':'LED_CHECKPOINT_10', 'CONF_NAME':'CONFIG_EZYNQ_LED_CHECKPOINT_10','TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'LED ON/OFF before remapping OCM0-OCM2 high'},
{'NAME':'LED_CHECKPOINT_11', 'CONF_NAME':'CONFIG_EZYNQ_LED_CHECKPOINT_11','TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'LED ON/OFF after remapping OCM0-OCM2 high'},
{'NAME':'LED_CHECKPOINT_12', 'CONF_NAME':'CONFIG_EZYNQ_LED_CHECKPOINT_12','TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'LED ON/OFF before leaving lowlevel_init()'},
]
#
# CONFIG_EZYNQ_BOOT_DEBUG = y # configure UARTx and send register dumps there
# CONFIG_EZYNQ_LED_DEBUG = 47 # toggle LED during boot
# CONFIG_EZYNQ_UART_DEBUG_USE_LED = y # turn on/off LED while waiting for transmit FIFO not full
#
# CONFIG_EZYNQ_DUMP_SLCR_EARLY = y # Dump SLCR registers as soon as UART is initilaized (depends on CONFIG_EZYNQ_BOOT_DEBUG)
# CONFIG_EZYNQ_DUMP_DDRC_EARLY = y # Dump DDRC registers as soon as UART is initilaized (depends on CONFIG_EZYNQ_BOOT_DEBUG)
# CONFIG_EZYNQ_DUMP_SLCR_LATE = y # Dump SLCR registers after DDR memory is initilaized (depends on CONFIG_EZYNQ_BOOT_DEBUG)
# CONFIG_EZYNQ_DUMP_DDRC_LATE = y # Dump DDRC registers after DDR memory is initilaized (depends on CONFIG_EZYNQ_BOOT_DEBUG)
#
# #Turning LED on/off at different stages of the boot process. Requires CONFIG_EZYNQ_LED_DEBUG to be set
# #If defined, each can be 0,1, ON or OFF
# CONFIG_EZYNQ_LED_CHECKPOINT_1 = ON # in RBL setup, as soon as MIO is programmed
# CONFIG_EZYNQ_LED_CHECKPOINT_2 = OFF # First after getting to user code
# CONFIG_EZYNQ_LED_CHECKPOINT_3 = OFF # After setting clock registers
# CONFIG_EZYNQ_LED_CHECKPOINT_4 = ON # After PLL bypass is OFF
# CONFIG_EZYNQ_LED_CHECKPOINT_5 = ON # After UART is programmed
# CONFIG_EZYNQ_LED_CHECKPOINT_6 = OFF # After DCI is calibrated
# CONFIG_EZYNQ_LED_CHECKPOINT_7 = ON # After DDR is initialized
# CONFIG_EZYNQ_LED_CHECKPOINT_8 = OFF # Before relocation to DDR (to 0x4000000+ )
# CONFIG_EZYNQ_LED_CHECKPOINT_9 = ON # After relocation to DDR (to 0x4000000+ )
# CONFIG_EZYNQ_LED_CHECKPOINT_10 = OFF # Before remapping OCM0-OCM2 high
# CONFIG_EZYNQ_LED_CHECKPOINT_11 = ON # After remapping OCM0-OCM2 high
# CONFIG_EZYNQ_LED_CHECKPOINT_12 = OFF # Before leaving lowlevel_init()
class EzynqUBoot: class EzynqUBoot:
license="""/* license="""/*
* This file is automatically generated by the Free Software program using open information from the * This file is automatically generated by the Free Software program using open information from the
...@@ -40,10 +109,31 @@ class EzynqUBoot: ...@@ -40,10 +109,31 @@ class EzynqUBoot:
""" """
def __init__(self, verbosity): def __init__(self, raw_configs, verbosity):
self.cfile=self.license + self.include_section self.cfile=self.license + self.include_section
self.verbosity=verbosity self.verbosity=verbosity
self.sections=['license','include'] self.sections=['license','include']
self.features=ezynq_feature_config.EzynqFeatures(UBOOT_CFG_DEFS)
self.features.parse_features(raw_configs)
self.features.check_missing_features()
# undefine all if debug is disabled
if not self.features.get_par_value_or_none('BOOT_DEBUG'):
for name in self.features.get_par_names():
self.features.undefine_parameter(name)
elif self.features.get_par_value_or_none('LED_DEBUG') is None:
for name in self.features.get_par_names():
if 'LED' in name:
self.features.undefine_parameter(name)
def html_list_features(self,html_file):
if not html_file:
return
html_file.write('<h2>Boot process debug features setup</h2>\n')
self.features.html_list_features(html_file)
# print self.features.get_par_names()
def get_c_file(self): def get_c_file(self):
return self.cfile return self.cfile
def _opt_hex(self,d): def _opt_hex(self,d):
...@@ -70,14 +160,14 @@ class EzynqUBoot: ...@@ -70,14 +160,14 @@ class EzynqUBoot:
self.sections.append('slcr_lock_unlock_setup') self.sections.append('slcr_lock_unlock_setup')
self.cfile+=""" self.cfile+="""
/* Lock SLCR registers - may be called after everything is done. */ /* Lock SLCR registers - may be called after everything is done. */
void lock_slcr(void) /*not to conflict with another slcr_lock() in u-boot void lock_slcr(void)
{ {
""" """
self._add_reg_writes(reg_sets[:1]) self._add_reg_writes(reg_sets[:1])
self.cfile+="""} self.cfile+="""}
/* Unlock SLCR registers - SHOULD be called first before writing any SLCR registers. */ /* Unlock SLCR registers - SHOULD be called first before writing any SLCR registers. */
void unlock_slcr(void) /*not to conflict with another slcr_unlock() in u-boot void unlock_slcr(void)
{ {
""" """
self._add_reg_writes(reg_sets[1:]) self._add_reg_writes(reg_sets[1:])
...@@ -86,41 +176,19 @@ void unlock_slcr(void) /*not to conflict with another slcr_unlock() in u-boot ...@@ -86,41 +176,19 @@ void unlock_slcr(void) /*not to conflict with another slcr_unlock() in u-boot
def make_led_on_off(self, reg_sets): def make_led_on_off(self, reg_sets):
self.sections.append('led_on_off') self.sections.append('led_on_off')
self.cfile+=""" self.cfile+="""
/* Turn LED on/off for debugging of the early stages of boot process. */ /* Turn LED ON for debugging of the early stages of boot process. */
void led_on_off(int on) /*not to conflict with another slcr_lock() in u-boot inline void debug_led_on(void)
{
"""
self._add_reg_writes([reg_sets[1]])
self.cfile+="""}
/* Turn LED OFF for debugging of the early stages of boot process. */
inline void debug_led_off(void)
{ {
""" """
self.cfile+='\tif (on)'
self._add_reg_writes(reg_sets[1:])
self.cfile+='\telse'
self._add_reg_writes(reg_sets[:1]) self._add_reg_writes(reg_sets[:1])
self.cfile+='}\n' self.cfile+='}\n'
#make_led_on_off
# void led_off(void){
# writel(0x00000200, &slcr_base->mio_pin[47]); /* LED off */
# }
# void led_on(void){
# writel(0x00001201, &slcr_base->mio_pin[47]); /* LED on */
# }
#
# void poll_fifo_empty(void){
# while ((readl(&uart1_base->channel_sts) & 0x8) ==0) ; /* wait transmitter buffer is empty */
# }
#
# void poll_putc(int d){
# led_off();
# while ((readl(&uart1_base->channel_sts) & 0x10) !=0) ; /* wait transmitter buffer is not full */
# led_on();
# writel(d, &uart1_base->tx_rx_fifo);
# }
# void poll_puts(char * line){
# int i=0;
# while (line[i]!=0) poll_putc(line[i++]);
# }
def registers_setup(self, reg_sets,clk,num_rbl_regs): #clk is an instance of ezynq_clk.EzynqClk def registers_setup(self, reg_sets,clk,num_rbl_regs): #clk is an instance of ezynq_clk.EzynqClk
self.sections.append('registers_setup') self.sections.append('registers_setup')
...@@ -145,7 +213,7 @@ inline void pll_setup(void) ...@@ -145,7 +213,7 @@ inline void pll_setup(void)
self._add_reg_writes(reg_sets) self._add_reg_writes(reg_sets)
self.cfile+='}\n\n' self.cfile+='}\n\n'
def uart_init (self, reg_sets,clk): def uart_init (self, reg_sets):
self.sections.append('uart_init') self.sections.append('uart_init')
self.cfile+='''/* Initilize UART to output debug info during boot */ self.cfile+='''/* Initilize UART to output debug info during boot */
inline void uart_init(void) inline void uart_init(void)
...@@ -155,7 +223,119 @@ inline void uart_init(void) ...@@ -155,7 +223,119 @@ inline void uart_init(void)
self._add_reg_writes(reg_sets) self._add_reg_writes(reg_sets)
self.cfile+='}\n\n' self.cfile+='}\n\n'
#uart_transmit (should be called after LED control is set)
def uart_transmit (self, reg_sets):
use_led=self.features.get_par_value_or_none('UART_DEBUG_USE_LED')
self.sections.append('uart_xmit')
# op, addr, data, mask, module_name, register_name, r_def=reg_sets[2]
_, addr, _, _, module_name, register_name, r_def=reg_sets[2]
try:
comments=r_def['COMMENTS']
except:
comments=''
self.cfile+='''/* Wait FIFO is empty (call before getting to risky for reboot code
to make sure all output has been actually sent */
void uart_wait_tx_fifo_empty(void)
{
'''
self._add_reg_writes([reg_sets[0]])
self.cfile+='''}
/* Wait FIFO is not full, send one character
to make sure all output has been actually sent */
void uart_putc(int c)
{
'''
if use_led:
self.cfile+='\tdebug_led_off(); /* turn LED off */\n'
self._add_reg_writes([reg_sets[1]]) # wait FIFO not full
if use_led:
self.cfile+='\tdebug_led_on(); /* turn LED on */\n'
self.cfile+='\twritel(c, 0x%08x); /* %s.%s %s */\n'%(addr,module_name,register_name,comments)
self.cfile+='''}
void uart_puts(char * line){
\tint i=0;
\twhile (line[i]!=0) uart_putc(line[i++]);
}
inline void uart_put_hex_digit(int c)
{
\tuart_putc(c+ ((c>9)? ('a'-10):'0'));
}
void uart_put_hex(int d)
{
\tint i;
\tfor (i=28;i>=0;i-=4) uart_put_hex_digit((d>>i) & 0xf);
}
void uart_dump_regs(int addr_from, int addr_to, int num_per_line )
{
\tint a;
\taddr_from &= ~3;
\tint addr_display= (num_per_line * (((addr_from>>2) & 0x3fffffff)/num_per_line))<<2;
\tfor (a=addr_display; a<=addr_to; a+=4){
\t\tint r= (((a-addr_display)>>2) & 0x3fffffff) % num_per_line;
\t\tif (r==0) {
\t\t\tuart_put_hex(a);
\t\t\tuart_putc(':');
\t\t}
\t\tuart_putc(' ');
\t\tif (a<addr_from){
\t\t\tint j;
\t\t\tfor (j=0;j<8;j++) uart_putc('-');
\t\t} else {
\t\t\tuart_put_hex(readl(a));
\t\t}
\t\tif (r==(num_per_line-1)) {
\t\t\tuart_puts("\\r\\n");
\t\t}
\t}
\tuart_puts("\\r\\n");
}
'''
def make_ddrc_register_dump(self):
self.sections.append('ddrc_dump')
self.cfile+='''/* Dump all DDR Controller registers that do not hang the system */
void dump_ddrc_regs(void)
{
\tuart_puts("DDRC registers\\r\\n");
\tuart_dump_regs(0xf8006000,0xf800607c, 16); /* access to 0xf8006080 hangs */
\tuart_puts("\\r\\n");
\tuart_dump_regs(0xf80060a0, 0xf80060b8, 16);
\tuart_puts("\\r\\n");
\tuart_dump_regs(0xf80060c4, 0xf80060fc, 16);
\tuart_puts("\\r\\n");
\tuart_dump_regs(0xf8006114, 0xf8006194, 16); /* 0xf8006198 hangs */
\tuart_puts("\\r\\n");
\tuart_dump_regs(0xf80061a4, 0xf80061e8, 16); /* 0xf80061f0 hangs */
\tuart_puts("\\r\\n");
\tuart_dump_regs(0xf8006200, 0xf8006224, 16); /* 0xf8006228 hangs */
\tuart_puts("\\r\\n");
\tuart_dump_regs(0xf8006294, 0xf80062b4, 16);
\tuart_puts("\\r\\n");
}
'''
def make_slcr_register_dump(self):
self.sections.append('slcr_dump')
self.cfile+='''/* Dump all SLCR */
void dump_slxr_regs(void)
{
\tuart_dump_regs(0xf8000000, 0xf8000b74, 16);
\tuart_puts("\\r\\n");
'''
def dci_calibration (self, reg_sets,ddr): #ddr is an instance of ezynq_ddr.EzynqDDR def dci_calibration (self, reg_sets,ddr): #ddr is an instance of ezynq_ddr.EzynqDDR
if len(reg_sets)==0: if len(reg_sets)==0:
...@@ -183,57 +363,97 @@ inline void ddr_start(void) ...@@ -183,57 +363,97 @@ inline void ddr_start(void)
self.sections.append('ddr_start') self.sections.append('ddr_start')
def _cp_led(self,name):
led_cp=self.features.get_par_value_or_none(name)
# print name, led_cp
if not led_cp is None:
if led_cp:
self.cfile+='\tdebug_led_on(); /* Turn debug LED ON */\n'
else:
self.cfile+='\tdebug_led_off(); /* Turn debug LED OFF */\n'
def make_lowlevel_init (self): def make_lowlevel_init (self):
self.cfile+='''/* Initialize clocks, DDR memory, copy OCM to DDR */ self.cfile+='''/* Initialize clocks, DDR memory, copy OCM to DDR */
void lowlevel_init(void) void lowlevel_init(void)
{ {
''' /* Unlock SLCR */
if 'uart_init' in self.sections:
self.cfile+='''/* Initialize UART fdro debug information output */
\tuart_init();
'''
self.cfile+='''/*
Unlock SLCR
*/
\tunlock_slcr(); \tunlock_slcr();
/* '''
self._cp_led('LED_CHECKPOINT_2') # First after getting to user code
self.cfile+='''/*
Write PLL and clocks registers as the code is now completely loaded to the OCM and no Write PLL and clocks registers as the code is now completely loaded to the OCM and no
peripherals are needed immediately peripherals are needed immediately
*/ */
\tregister_setup(); \tregister_setup();
/* '''
self._cp_led('LED_CHECKPOINT_3') # After setting clock registers
self.cfile+='''/*
Wait PLLs locked and turn off bypass - all clocks should have specified values now Wait PLLs locked and turn off bypass - all clocks should have specified values now
*/ */
\tpll_setup(); \tpll_setup();
/* '''
self._cp_led('LED_CHECKPOINT_4') # After PLL bypass is OFF
if 'uart_init' in self.sections:
self.cfile+='''/* Initialize UART for debug information output */
\tuart_init();
'''
self._cp_led('LED_CHECKPOINT_5') # After UART is programmed
if self.features.get_par_value_or_none('DUMP_SLCR_EARLY'):
self.cfile+='\tuart_puts("SLCR registers before DCI/DDR initialization\\r\\n")\n'
self.cfile+='\tdump_slcr_regs(); /*Dump all SLCR registers before DCI/DDR initialization */\n'
if self.features.get_par_value_or_none('DUMP_DDRC_EARLY'):
self.cfile+='\tuart_puts("DDRC registers before DCI/DDR initialization\\r\\n")\n'
self.cfile+='\tdump_ddrc_regs(); /*Dump all DDRC registers before DCI/DDR initialization */\n'
self.cfile+='''/*
Calibrate DDR DCI impedance and wait for completion Calibrate DDR DCI impedance and wait for completion
*/ */
\tdci_calibration(); \tdci_calibration();
/* '''
self._cp_led('LED_CHECKPOINT_6') # After DCI is calibrated
self.cfile+='''/*
Remove soft reset from DDR controller - that starts initialization. Wait for completion Remove soft reset from DDR controller - that starts initialization. Wait for completion
*/ */
\tddr_start(); \tddr_start();
/*
'''
self._cp_led('LED_CHECKPOINT_7') # After DDR is initialized
if self.features.get_par_value_or_none('DUMP_SLCR_LATE'):
self.cfile+='\tuart_puts("SLCR registers after DCI/DDR initialization\\r\\n")\n'
self.cfile+='\tdump_slcr_regs(); /*Dump all SLCR registers after DCI/DDR initialization */\n'
if self.features.get_par_value_or_none('DUMP_DDRC_LATE'):
self.cfile+='\tuart_puts("DDRC registers after DCI/DDR initialization\\r\\n")\n'
self.cfile+='\tdump_ddrc_regs(); /*Dump all DDRC registers after DCI/DDR initialization */\n'
self.cfile+='''/*
Copy 3 pages of OCM from 0x00000.0x2ffff to DDR 0x4000000.0x402ffff Copy 3 pages of OCM from 0x00000.0x2ffff to DDR 0x4000000.0x402ffff
*/ */
\tint * s= (int *) 0; \tint * s= (int *) 0;
\tint * d= (int *) 0x4000000; \tint * d= (int *) 0x4000000;
\twhile (s< ((int *)0x30000)) *d++=*s++; \twhile (s< ((int *)0x30000)) *d++=*s++;
/*
'''
# CONFIG_EZYNQ_LED_CHECKPOINT_10 = OFF # Before relocation down to address 0
# CONFIG_EZYNQ_LED_CHECKPOINT_11 = ON # After relocation down to address 0
# CONFIG_EZYNQ_LED_CHECKPOINT_12 = OFF # Before leaving lowlevel_init()
self._cp_led('LED_CHECKPOINT_8') # Before relocation to DDR (to 0x4000000+ )
self.cfile+='''/*
Now jump to the same instruction in the DDR copy of the currently executed code in OCM Now jump to the same instruction in the DDR copy of the currently executed code in OCM
Be careful not to call functions or access data stored in the 3 lower OCM pages. Be careful not to call functions or access data stored in the 3 lower OCM pages.
writel() is OK as it is just a macro, not a function call writel() is OK as it is just a macro, not a function call
*/ */
\tasm("add pc, pc, #0x4000000" ); \tasm("add pc, pc, #0x4000000" );
/*
'''
self._cp_led('LED_CHECKPOINT_9') # After relocation to DDR (to 0x4000000+ )
self.cfile+='''/*
Remap DDR to zero, FILTERSTART Remap DDR to zero, FILTERSTART
*/ */
\twritel(0, &scu_base->filter_start); \twritel(0, &scu_base->filter_start);
...@@ -242,13 +462,17 @@ void lowlevel_init(void) ...@@ -242,13 +462,17 @@ void lowlevel_init(void)
*/ */
\twritel(0x757BDF0D, &devcfg_base->unlock); \twritel(0x757BDF0D, &devcfg_base->unlock);
\twritel(0xFFFFFFFF, &devcfg_base->rom_shadow); \twritel(0xFFFFFFFF, &devcfg_base->rom_shadow);
/* '''
self._cp_led('LED_CHECKPOINT_10') # Before remapping OCM0-OCM2 high
self.cfile+='''/*
Now as the code is executed outside of the OCM it is possible to remap the 3 lower Now as the code is executed outside of the OCM it is possible to remap the 3 lower
OCM pages to high memory. OCM pages to high memory.
OCM_CFG, Mask out the ROM, map ram into upper addresses OCM_CFG, Mask out the ROM, map ram into upper addresses
*/ */
\twritel(0x1F, &slcr_base->ocm_cfg); \twritel(0x1F, &slcr_base->ocm_cfg);
/* '''
self._cp_led('LED_CHECKPOINT_11') # After remapping OCM0-OCM2 high
self.cfile+='''/*
Copy program memory that we are currently executing to low DRAM (0x0.0x2ffff) Copy program memory that we are currently executing to low DRAM (0x0.0x2ffff)
Not possible to call library memcpy() as it will try to access not-yet copied code Not possible to call library memcpy() as it will try to access not-yet copied code
*/ */
...@@ -268,6 +492,9 @@ void lowlevel_init(void) ...@@ -268,6 +492,9 @@ void lowlevel_init(void)
\twritel(0x0, &slcr_base->ddr_urgent_sel); \twritel(0x0, &slcr_base->ddr_urgent_sel);
\t/* Urgent write, ports S2/S3 */ \t/* Urgent write, ports S2/S3 */
\twritel(0xC, &slcr_base->ddr_urgent); \twritel(0xC, &slcr_base->ddr_urgent);
'''
self._cp_led('LED_CHECKPOINT_12') # Before leaving lowlevel_init()
self.cfile+='''/* Lock SLCR back after everything with it is done */
\tlock_slcr(); \tlock_slcr();
/* /*
This code was called from low OCM, so return should just get back correctly This code was called from low OCM, so return should just get back correctly
...@@ -278,7 +505,7 @@ void lowlevel_init(void) ...@@ -278,7 +505,7 @@ void lowlevel_init(void)
def output_c_file(self,cname): def output_c_file(self,cname):
if not cname: if not cname:
return return
print 'Writing generated u-boot lowlevel() function to ',cname print 'Writing generated u-boot lowlevel() function to ',os.path.abspath(cname)
c_out_file=open(cname,'w') c_out_file=open(cname,'w')
c_out_file.write(self.cfile) c_out_file.write(self.cfile)
c_out_file.close() c_out_file.close()
...@@ -21,6 +21,7 @@ __version__ = "3.0+" ...@@ -21,6 +21,7 @@ __version__ = "3.0+"
__maintainer__ = "Andrey Filippov" __maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com" __email__ = "andrey@elphel.com"
__status__ = "Development" __status__ = "Development"
import os
import struct import struct
import argparse # http://docs.python.org/2/howto/argparse.html import argparse # http://docs.python.org/2/howto/argparse.html
...@@ -289,6 +290,7 @@ permit_undefined_bits=False ...@@ -289,6 +290,7 @@ permit_undefined_bits=False
force=True #False force=True #False
warn_notfit=True # False warn_notfit=True # False
regs_masked=[] regs_masked=[]
u_boot=ezynq_uboot.EzynqUBoot(raw_configs,args.verbosity)
mio_regs=ezynq_mio.EzynqMIO(args.verbosity,QUALIFIER_CHAR,[],permit_undefined_bits) # does not use regs_masked mio_regs=ezynq_mio.EzynqMIO(args.verbosity,QUALIFIER_CHAR,[],permit_undefined_bits) # does not use regs_masked
mio_regs.process_mio(raw_configs,WARN) # does not use regs_masked mio_regs.process_mio(raw_configs,WARN) # does not use regs_masked
...@@ -312,32 +314,39 @@ ddr_mhz=clk.get_ddr_mhz() ...@@ -312,32 +314,39 @@ ddr_mhz=clk.get_ddr_mhz()
if MIO_HTML: if MIO_HTML:
f=open(MIO_HTML,'w') html_file=open(MIO_HTML,'w')
print 'Generating HTML output',os.path.abspath(MIO_HTML)
else: else:
f=False html_file=False
u_boot.html_list_features(html_file)
#output_slcr_lock(registers,f,False,MIO_HTML_MASK) #prohibited by RBL #output_slcr_lock(registers,f,False,MIO_HTML_MASK) #prohibited by RBL
mio_regs.output_mio(f,MIO_HTML_MASK) mio_regs.output_mio(html_file,MIO_HTML_MASK)
# def process_mio(self,raw_configs,warn): # def process_mio(self,raw_configs,warn):
# def output_mio(self,f,MIO_HTML_MASK) # def output_mio(self,f,MIO_HTML_MASK)
# setregs_mio(self,current_reg_sets,force=True): # setregs_mio(self,current_reg_sets,force=True):
clk.html_list_clocks(f) clk.html_list_clocks(html_file)
#output_mio(registers,f,mio,MIO_HTML_MASK) #output_mio(registers,f,mio,MIO_HTML_MASK)
ddr.calculate_dependent_pars(ddr_mhz) ddr.calculate_dependent_pars(ddr_mhz)
ddr.pre_validate() # before applying default values (some timings should be undefined, not defaults) ddr.pre_validate() # before applying default values (some timings should be undefined, not defaults)
ddr.check_missing_features() #and apply default values ddr.check_missing_features() #and apply default values
ddr.html_list_features(f) #verify /fix values after defaults are applied ddr.html_list_features(html_file) #verify /fix values after defaults are applied
#clk.calculate_dependent_pars() #clk.calculate_dependent_pars()
clk.html_list_features(f) clk.html_list_features(html_file)
reg_sets=[] reg_sets=[]
segments=[] segments=[]
reg_sets=mio_regs.setregs_mio(reg_sets,force) # reg Sets include now MIO reg_sets=mio_regs.setregs_mio(reg_sets,force) # reg Sets include now MIO
segments.append({'TO':len(reg_sets),'RBL':True,'NAME':'MIO','TITLE':'MIO registers configuration'}) segments.append({'TO':len(reg_sets),'RBL':True,'NAME':'MIO','TITLE':'MIO registers configuration'})
led_debug_mio_pin= u_boot.features.get_par_value_or_none('LED_DEBUG')
if not led_debug_mio_pin is None:
led_cp_1=u_boot.features.get_par_value_or_none('LED_CHECKPOINT_1')
if not led_cp_1 is None:
reg_sets=mio_regs.rbl_led_on_off(led_debug_mio_pin, led_cp_1, reg_sets)
segments.append({'TO':len(reg_sets),'RBL':True,'NAME':'RBL_LED','TITLE':'Setting debug LED during RBL to '+('OFF','ON')[led_cp_1]})
#adding ddr registers #adding ddr registers
if raw_config_value('CONFIG_EZYNQ_SKIP_DDR', raw_configs) is None: if raw_config_value('CONFIG_EZYNQ_SKIP_DDR', raw_configs) is None:
ddr.ddr_init_memory(reg_sets,False,False) ddr.ddr_init_memory(reg_sets,False,False)
...@@ -353,11 +362,10 @@ segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'CLK','TITLE':'Clock regi ...@@ -353,11 +362,10 @@ segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'CLK','TITLE':'Clock regi
#print 'Debug mode: CLK/PLL configuration by u-boot' #print 'Debug mode: CLK/PLL configuration by u-boot'
reg_sets=clk.clocks_pll_bypass_off(reg_sets,force) reg_sets=clk.clocks_pll_bypass_off(reg_sets,force)
segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'PLL','TITLE':'Registers to switch to PLL'}) segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'PLL','TITLE':'Registers to switch to PLL'})
if not raw_config_value('CONFIG_EZYNQ_BOOT_DEBUG', raw_configs) is None: if u_boot.features.get_par_value_or_none('BOOT_DEBUG'):
uart=ezynq_uart.EzynqUART() uart=ezynq_uart.EzynqUART()
uart.parse_parameters(raw_configs,used_mio_interfaces,False) uart.parse_parameters(raw_configs,used_mio_interfaces,False)
uart.check_missing_features() uart.check_missing_features()
uart_channel=uart.channel uart_channel=uart.channel
if not uart_channel is None: if not uart_channel is None:
try: try:
...@@ -372,11 +380,15 @@ else: ...@@ -372,11 +380,15 @@ else:
uart_channel=None uart_channel=None
if not uart_channel is None: if not uart_channel is None:
uart.html_list_features(f) uart.html_list_features(html_file)
# Generate UART initialization, putc and wait FIFO empty code
reg_sets=uart.setup_uart(reg_sets,force=False,warn=False) reg_sets=uart.setup_uart(reg_sets,force=False,warn=False)
segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'UART_INIT','TITLE':'Registers to initialize UART'}) segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'UART_INIT','TITLE':'Registers to initialize UART'})
reg_sets_uart_extra=uart.set_uart_codes()
reg_sets.extend (reg_sets_uart_extra) # just to be listed, not to be loaded
segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'UART_XMIT','TITLE':'UART register tests sets to output debug data'})
if raw_config_value('CONFIG_EZYNQ_SKIP_DDR', raw_configs) is None: if raw_config_value('CONFIG_EZYNQ_SKIP_DDR', raw_configs) is None:
reg_sets=ddr.ddr_dci_calibrate(reg_sets,False,False) reg_sets=ddr.ddr_dci_calibrate(reg_sets,False,False)
segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'DCI','TITLE':'DDR DCI Calibration'}) segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'DCI','TITLE':'DDR DCI Calibration'})
...@@ -389,13 +401,10 @@ reg_sets_lock_unlock=clk.generate_lock_unlock() ...@@ -389,13 +401,10 @@ reg_sets_lock_unlock=clk.generate_lock_unlock()
reg_sets.extend (reg_sets_lock_unlock) # just to be listed, not to be loaded reg_sets.extend (reg_sets_lock_unlock) # just to be listed, not to be loaded
segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'SLCR_LOCK_UNLOCK','TITLE':'SLCR lock/unlock registers - listed out of sequence'}) segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'SLCR_LOCK_UNLOCK','TITLE':'SLCR lock/unlock registers - listed out of sequence'})
try: if not led_debug_mio_pin is None:
led_mio_pin=int (raw_config_value('CONFIG_EZYNQ_LED_DEBUG', raw_configs),0) reg_sets_led=mio_regs.generate_led_off_on(led_debug_mio_pin)
reg_sets_led=mio_regs.generate_led_off_on(led_mio_pin)
reg_sets.extend (reg_sets_led) # just to be listed, not to be loaded reg_sets.extend (reg_sets_led) # just to be listed, not to be loaded
segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'LED','TITLE':'registers/data to turn on/off debug LED - listed out of sequence'}) segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'LED','TITLE':'registers/data to turn on/off debug LED - listed out of sequence'})
except:
led_mio_pin=None
# def generate_led_off_on(self, mio_pin): # def generate_led_off_on(self, mio_pin):
#CONFIG_EZYNQ_LED_DEBUG=47 # toggle LED during boot #CONFIG_EZYNQ_LED_DEBUG=47 # toggle LED during boot
#CONFIG_EZYNQ_BOOT_DEBUG #CONFIG_EZYNQ_BOOT_DEBUG
...@@ -426,27 +435,27 @@ for segment in segments: ...@@ -426,27 +435,27 @@ for segment in segments:
show_comments= MIO_HTML_MASK & 0x200 show_comments= MIO_HTML_MASK & 0x200
filter_fields=not MIO_HTML_MASK & 0x400 filter_fields=not MIO_HTML_MASK & 0x400
all_used_fields= False all_used_fields= False
ezynq_registers.print_html_reg_header(f, ezynq_registers.print_html_reg_header(html_file,
segment['TITLE']+" (%s)"%(('U-BOOT','RBL')[segment['RBL']]), segment['TITLE']+" (%s)"%(('U-BOOT','RBL')[segment['RBL']]),
show_bit_fields, show_comments, filter_fields) show_bit_fields, show_comments, filter_fields)
# print segment['TITLE']+" (%s)"%(('U-BOOT','RBL')[segment['RBL']]), start,end # print segment['TITLE']+" (%s)"%(('U-BOOT','RBL')[segment['RBL']]), start,end
ezynq_registers.print_html_registers(f, ezynq_registers.print_html_registers(html_file,
reg_sets[:end], reg_sets[:end],
start, start,
show_bit_fields, show_bit_fields,
show_comments, show_comments,
filter_fields, filter_fields,
all_used_fields) all_used_fields)
ezynq_registers.print_html_reg_footer(f) ezynq_registers.print_html_reg_footer(html_file)
if f: if html_file:
f.write('<h4>Total number of registers set up in the RBL header is <b>'+str(num_rbl_regs)+"</b> of maximal 256</h4>") html_file.write('<h4>Total number of registers set up in the RBL header is <b>'+str(num_rbl_regs)+"</b> of maximal 256</h4>")
if num_rbl_regs<len(reg_sets): if num_rbl_regs<len(reg_sets):
f.write('<h4>Number of registers set up in u-boot is <b>'+str(len(reg_sets)-num_rbl_regs)+"</b></h4>") html_file.write('<h4>Number of registers set up in u-boot is <b>'+str(len(reg_sets)-num_rbl_regs)+"</b></h4>")
# #
if MIO_HTML: if MIO_HTML:
f.close html_file.close
#if args.verbosity >= 1: #if args.verbosity >= 1:
# print registers # print registers
image =[ 0 for k in range (0x8c0/4)] image =[ 0 for k in range (0x8c0/4)]
...@@ -476,9 +485,7 @@ if args.outfile: ...@@ -476,9 +485,7 @@ if args.outfile:
# segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'UART_INIT','TITLE':'Registers to initialize UART'}) # segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'UART_INIT','TITLE':'Registers to initialize UART'})
# segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'DCI','TITLE':'DDR DCI Calibration'}) # segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'DCI','TITLE':'DDR DCI Calibration'})
# segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'DDR_START','TITLE':'DDR initialization start'}) # segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'DDR_START','TITLE':'DDR initialization start'})
#CONFIG_EZYNQ_UART_DEBUG_USE_LED
u_boot=ezynq_uboot.EzynqUBoot(args.verbosity)
if 'SLCR_LOCK_UNLOCK' in segment_dict: if 'SLCR_LOCK_UNLOCK' in segment_dict:
u_boot.make_slcr_lock_unlock (reg_sets[segment_dict['SLCR_LOCK_UNLOCK']['FROM']:segment_dict['SLCR_LOCK_UNLOCK']['TO']]) u_boot.make_slcr_lock_unlock (reg_sets[segment_dict['SLCR_LOCK_UNLOCK']['FROM']:segment_dict['SLCR_LOCK_UNLOCK']['TO']])
if 'LED' in segment_dict: if 'LED' in segment_dict:
...@@ -489,7 +496,12 @@ if 'CLK' in segment_dict: ...@@ -489,7 +496,12 @@ if 'CLK' in segment_dict:
if 'PLL' in segment_dict: if 'PLL' in segment_dict:
u_boot.pll_setup (reg_sets[segment_dict['PLL']['FROM']:segment_dict['PLL']['TO']],clk) u_boot.pll_setup (reg_sets[segment_dict['PLL']['FROM']:segment_dict['PLL']['TO']],clk)
if 'UART_INIT' in segment_dict: if 'UART_INIT' in segment_dict:
u_boot.uart_init (reg_sets[segment_dict['UART_INIT']['FROM']:segment_dict['UART_INIT']['TO']],clk) u_boot.uart_init (reg_sets[segment_dict['UART_INIT']['FROM']:segment_dict['UART_INIT']['TO']])
if 'UART_XMIT' in segment_dict:
u_boot.uart_transmit (reg_sets[segment_dict['UART_XMIT']['FROM']:segment_dict['UART_XMIT']['TO']])
u_boot.make_ddrc_register_dump()
u_boot.make_slcr_register_dump()
#if not u_boot.features.get_par_value_or_none('BOOT_DEBUG') is None:
if 'DCI' in segment_dict: if 'DCI' in segment_dict:
u_boot.dci_calibration(reg_sets[segment_dict['DCI']['FROM']:segment_dict['DCI']['TO']],ddr) u_boot.dci_calibration(reg_sets[segment_dict['DCI']['FROM']:segment_dict['DCI']['TO']],ddr)
......
CONFIG_EZYNQ_BOOT_DEBUG=y # configure UARTx and send register dumps there CONFIG_EZYNQ_BOOT_DEBUG = y # configure UARTx and send register dumps there
CONFIG_EZYNQ_LED_DEBUG=47 # toggle LED during boot CONFIG_EZYNQ_LED_DEBUG = 47 # toggle LED during boot
CONFIG_EZYNQ_UART_DEBUG_USE_LED = y # turn on/off LED while waiting for transmit FIFO not full
CONFIG_EZYNQ_DUMP_SLCR_EARLY = y # Dump SLCR registers as soon as UART is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG)
CONFIG_EZYNQ_DUMP_DDRC_EARLY = y # Dump DDRC registers as soon as UART is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG)
CONFIG_EZYNQ_DUMP_SLCR_LATE = y # Dump SLCR registers after DDR memory is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG)
CONFIG_EZYNQ_DUMP_DDRC_LATE = y # Dump DDRC registers after DDR memory is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG)
#Turning LED on/off at different stages of the boot process. Requires CONFIG_EZYNQ_LED_DEBUG to be set
#If defined, each can be 0,1, ON or OFF
CONFIG_EZYNQ_LED_CHECKPOINT_1 = ON # in RBL setup, as soon as MIO is programmed
#CONFIG_EZYNQ_LED_CHECKPOINT_2 = OFF # First after getting to user code
#CONFIG_EZYNQ_LED_CHECKPOINT_3 = ON # After setting clock registers
#CONFIG_EZYNQ_LED_CHECKPOINT_4 = OFF # After PLL bypass is OFF
#CONFIG_EZYNQ_LED_CHECKPOINT_5 = ON # After UART is programmed
CONFIG_EZYNQ_LED_CHECKPOINT_6 = OFF # After DCI is calibrated
CONFIG_EZYNQ_LED_CHECKPOINT_7 = ON # After DDR is initialized
CONFIG_EZYNQ_LED_CHECKPOINT_8 = OFF # Before relocation to DDR (to 0x4000000+ )
CONFIG_EZYNQ_LED_CHECKPOINT_9 = ON # After relocation to DDR (to 0x4000000+ )
CONFIG_EZYNQ_LED_CHECKPOINT_10 = OFF # Before remapping OCM0-OCM2 high
CONFIG_EZYNQ_LED_CHECKPOINT_11 = ON # After remapping OCM0-OCM2 high
CONFIG_EZYNQ_LED_CHECKPOINT_12 = OFF # Before leaving lowlevel_init()
CONFIG_EZYNQ_UART1_BAUD_RATE=115200 CONFIG_EZYNQ_UART1_BAUD_RATE=115200
#Configuration for the microzed board #Configuration for the microzed board
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment