Commit fe897345 authored by Andrey Filippov's avatar Andrey Filippov

debugging, made generated lowlevel.c produce working image

parent ea7d60dc
......@@ -893,7 +893,7 @@ class EzynqClk:
# reg uart_clk_ctrl, offs=0x154 dflt:0x3f03 actual: 0xa02
if 'UART' in self.iface_divs:
print self.iface_divs['UART']
# print self.iface_divs['UART']
if self.iface_divs['UART']['PLL']=='ARM':
uart_srcsel= 2
elif self.iface_divs['UART']['PLL']=='DDR':
......
......@@ -28,6 +28,7 @@ import ezynq_registers
import ezynq_ddrcfg_defs
import ezynq_feature_config
import ezynq_ddriob_def
import ezynq_slcr_clk_def
def set_random_bits(old,d,bits):
data = 0
mask = 0
......@@ -44,7 +45,14 @@ class EzynqDDR:
self.features=ezynq_feature_config.EzynqFeatures(self.DDR_CFG_DEFS,0) #DDR_CFG_DEFS
self.ddrc_register_set= ezynq_registers.EzynqRegisters(self.DDRC_DEFS,0,regs_masked,permit_undefined_bits)
self.ddriob_register_set=ezynq_registers.EzynqRegisters(self.DDRIOB_DEFS,0,regs_masked,permit_undefined_bits)
def generate_command_queue_empty(self):
# generate code to be included in u-boot for testing DDR command queue
reg_set= ezynq_registers.EzynqRegisters(ezynq_slcr_clk_def.SLCR_CLK_DEFS,0,[])
reg_set.wait_reg_field_values('ddr_cmd_sta', # DDR Command queue state
(('cmd_q_empty', 0)), True) # 0 - no commands for DDRC are queued, 1 - commands pending
return reg_set.get_register_sets(sort_addr=True,apply_new=True)
def parse_parameters(self,raw_configs):
self.features.parse_features(raw_configs)
......
......@@ -699,11 +699,11 @@ SLCR_CLK_DEFS={ #not all fields are defined currently
'FIELDS':{
'reserved': {'r':( 1,31),'d':0, 'c':'reserved'},
'start_ref': {'r':( 0, 0),'d':0, 'c':'1 - Start Refresh (self-clearing). Only needed if auto refresh is disabled in reg_ddrc_dis_auto_refresh'}}},
'ddr_cmd_sta': {'OFFS': 0x618,'DFLT':0,'RO':'RW',
'ddr_cmd_sta': {'OFFS': 0x618,'DFLT':0,'RW':'RO',
'COMMENTS':'DDR Command queue state',
'FIELDS':{
'reserved': {'r':( 1,31),'d':0, 'c':'reserved'},
'vmd_q_empty': {'r':( 0, 0),'d':0, 'm':'R', 'c':'0 - no commands fro DDRC are queued, 1 - commands pending'}}},
'cmd_q_empty': {'r':( 0, 0),'d':0, 'm':'R', 'c':'0 - no commands for DDRC are queued, 1 - commands pending'}}},
'ddr_urgent_sel': {'OFFS': 0x61c,'DFLT':0,'RW':'RW',
'COMMENTS':'DDR Urgent select',
'FIELDS':{
......
......@@ -330,14 +330,15 @@ void dump_ddrc_regs(void)
def make_slcr_register_dump(self):
self.sections.append('slcr_dump')
self.cfile+='''/* Dump all SLCR */
void dump_slxr_regs(void)
void dump_slcr_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):
if len(reg_sets)==0:
print 'No DCI calibration register data is provided, skipping generating dci_calibration()'
return
......@@ -346,11 +347,12 @@ inline void dci_calibration(void)
{
\t/* Toggle active-low DCI reset, initialize DCI calibration, wait for DONE */
'''
self._add_reg_writes(reg_sets)
self.cfile+='}\n\n'
self.sections.append('dci_calibration')
def ddr_start (self, reg_sets,ddr): #ddr is an instance of ezynq_ddr.EzynqDDR
def ddr_start (self, reg_sets):
if len(reg_sets)==0:
print 'No DDR start data is provided, skipping generating ddr_start()'
return
......@@ -362,6 +364,17 @@ inline void ddr_start(void)
self.cfile+='}\n\n'
self.sections.append('ddr_start')
def ddrc_wait_empty_queue (self,reg_sets):
if len(reg_sets)==0:
print 'No DDR start data is provided, skipping generating ddrc_status()'
return
self.cfile+='''/* Verify there are no commands in DDRC queue pending */
inline void ddrc_wait_queue_empty(void)
{
'''
self._add_reg_writes(reg_sets)
self.cfile+='}\n\n'
self.sections.append('ddrc_status')
def _cp_led(self,name):
led_cp=self.features.get_par_value_or_none(name)
......@@ -407,10 +420,10 @@ void lowlevel_init(void)
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+='\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+='\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
......@@ -427,10 +440,10 @@ void lowlevel_init(void)
'''
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+='\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+='\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
......@@ -440,9 +453,8 @@ void lowlevel_init(void)
\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.cfile+='\tddrc_wait_queue_empty(); /* Wait no commands are pending in DDRC queue */\n'
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
......@@ -452,6 +464,8 @@ void lowlevel_init(void)
\tasm("add pc, pc, #0x4000000" );
'''
# seems some delay is needed before remapping DDR memory
self.cfile+='\tddrc_wait_queue_empty(); /* seems some delay is needed here before remapping DDR memory */\n'
self._cp_led('LED_CHECKPOINT_9') # After relocation to DDR (to 0x4000000+ )
self.cfile+='''/*
Remap DDR to zero, FILTERSTART
......@@ -479,6 +493,9 @@ void lowlevel_init(void)
\ts= (int *) 0x4000000;
\td= (int *) 0;
\twhile (d < ((int *) 0x30000)) *d++=*s++;
\tddrc_wait_queue_empty(); /* Wait no commands are pending in DDRC queue */
/*
Continue with the original low-level init, Now we have 2 copies of the code again,
currently executing somewhere above 0x4000000. But as soon as we will return
......@@ -493,6 +510,9 @@ void lowlevel_init(void)
\t/* Urgent write, ports S2/S3 */
\twritel(0xC, &slcr_base->ddr_urgent);
'''
if 'uart_xmit' in self.sections:
self.cfile+='\tuart_wait_tx_fifo_empty(); /* u-boot may re-program UART differently, wait all is sent before getting there */\n'
#uart_wait_tx_fifo_empty() - add if u-boot debug is on
self._cp_led('LED_CHECKPOINT_12') # Before leaving lowlevel_init()
self.cfile+='''/* Lock SLCR back after everything with it is done */
\tlock_slcr();
......
......@@ -354,7 +354,6 @@ if raw_config_value('CONFIG_EZYNQ_SKIP_DDR', raw_configs) is None:
segments.append({'TO':len(reg_sets),'RBL':True,'NAME':'DDR0','TITLE':'DDR registers configuration'})
else:
print 'Debug mode: skipping DDR-related configuration'
#initialize clocks
# unlock slcr - it is locked by RBL, but attempt to unlock in RBL will fail (and hang the system)
reg_sets=clk.clocks_regs_setup(reg_sets,force)
......@@ -405,6 +404,14 @@ if not led_debug_mio_pin is None:
reg_sets_led=mio_regs.generate_led_off_on(led_debug_mio_pin)
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'})
#add code to check DDRC status (no commands in queue)
reg_sets_ddrc_sta=ddr.generate_command_queue_empty()
reg_sets.extend (reg_sets_ddrc_sta) # just to be listed, not to be loaded
segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'DDRC_STA','TITLE':'resgister to test DDRC comamnd queue status - listed out of sequence'})
# def generate_led_off_on(self, mio_pin):
#CONFIG_EZYNQ_LED_DEBUG=47 # toggle LED during boot
#CONFIG_EZYNQ_BOOT_DEBUG
......@@ -504,9 +511,14 @@ if 'UART_XMIT' in segment_dict:
#if not u_boot.features.get_par_value_or_none('BOOT_DEBUG') is None:
if 'DCI' in segment_dict:
u_boot.dci_calibration(reg_sets[segment_dict['DCI']['FROM']:segment_dict['DCI']['TO']],ddr)
if 'DDR' in segment_dict:
u_boot.ddr_start (reg_sets[segment_dict['DDR']['FROM']:segment_dict['DDR']['TO']],ddr)
u_boot.dci_calibration(reg_sets[segment_dict['DCI']['FROM']:segment_dict['DCI']['TO']])
if 'DDR_START' in segment_dict:
u_boot.ddr_start (reg_sets[segment_dict['DDR_START']['FROM']:segment_dict['DDR_START']['TO']])
if 'DDRC_STA' in segment_dict:
u_boot.ddrc_wait_empty_queue(reg_sets[segment_dict['DDRC_STA']['FROM']:segment_dict['DDRC_STA']['TO']])
#segments.append({'TO':len(reg_sets),'RBL':False,'NAME':'DDRC_STA','TITLE':'resgister to test DDRC comamnd queue status - listed out of sequence'})
u_boot.make_lowlevel_init()
u_boot.output_c_file(args.lowlevel)
#print u_boot.get_c_file()
......@@ -10,10 +10,10 @@ CONFIG_EZYNQ_DUMP_DDRC_LATE = y # Dump DDRC registers after DDR memory is initia
#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_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+ )
......
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