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: ...@@ -893,7 +893,7 @@ class EzynqClk:
# reg uart_clk_ctrl, offs=0x154 dflt:0x3f03 actual: 0xa02 # reg uart_clk_ctrl, offs=0x154 dflt:0x3f03 actual: 0xa02
if 'UART' in self.iface_divs: if 'UART' in self.iface_divs:
print self.iface_divs['UART'] # print self.iface_divs['UART']
if self.iface_divs['UART']['PLL']=='ARM': if self.iface_divs['UART']['PLL']=='ARM':
uart_srcsel= 2 uart_srcsel= 2
elif self.iface_divs['UART']['PLL']=='DDR': elif self.iface_divs['UART']['PLL']=='DDR':
......
...@@ -28,6 +28,7 @@ import ezynq_registers ...@@ -28,6 +28,7 @@ import ezynq_registers
import ezynq_ddrcfg_defs import ezynq_ddrcfg_defs
import ezynq_feature_config import ezynq_feature_config
import ezynq_ddriob_def import ezynq_ddriob_def
import ezynq_slcr_clk_def
def set_random_bits(old,d,bits): def set_random_bits(old,d,bits):
data = 0 data = 0
mask = 0 mask = 0
...@@ -45,6 +46,13 @@ class EzynqDDR: ...@@ -45,6 +46,13 @@ class EzynqDDR:
self.ddrc_register_set= ezynq_registers.EzynqRegisters(self.DDRC_DEFS,0,regs_masked,permit_undefined_bits) 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) 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): def parse_parameters(self,raw_configs):
self.features.parse_features(raw_configs) self.features.parse_features(raw_configs)
......
...@@ -699,11 +699,11 @@ SLCR_CLK_DEFS={ #not all fields are defined currently ...@@ -699,11 +699,11 @@ SLCR_CLK_DEFS={ #not all fields are defined currently
'FIELDS':{ 'FIELDS':{
'reserved': {'r':( 1,31),'d':0, 'c':'reserved'}, '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'}}}, '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', 'COMMENTS':'DDR Command queue state',
'FIELDS':{ 'FIELDS':{
'reserved': {'r':( 1,31),'d':0, 'c':'reserved'}, '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', 'ddr_urgent_sel': {'OFFS': 0x61c,'DFLT':0,'RW':'RW',
'COMMENTS':'DDR Urgent select', 'COMMENTS':'DDR Urgent select',
'FIELDS':{ 'FIELDS':{
......
...@@ -330,14 +330,15 @@ void dump_ddrc_regs(void) ...@@ -330,14 +330,15 @@ void dump_ddrc_regs(void)
def make_slcr_register_dump(self): def make_slcr_register_dump(self):
self.sections.append('slcr_dump') self.sections.append('slcr_dump')
self.cfile+='''/* Dump all SLCR */ self.cfile+='''/* Dump all SLCR */
void dump_slxr_regs(void) void dump_slcr_regs(void)
{ {
\tuart_dump_regs(0xf8000000, 0xf8000b74, 16); \tuart_dump_regs(0xf8000000, 0xf8000b74, 16);
\tuart_puts("\\r\\n"); \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: if len(reg_sets)==0:
print 'No DCI calibration register data is provided, skipping generating dci_calibration()' print 'No DCI calibration register data is provided, skipping generating dci_calibration()'
return return
...@@ -346,11 +347,12 @@ inline void dci_calibration(void) ...@@ -346,11 +347,12 @@ inline void dci_calibration(void)
{ {
\t/* Toggle active-low DCI reset, initialize DCI calibration, wait for DONE */ \t/* Toggle active-low DCI reset, initialize DCI calibration, wait for DONE */
''' '''
self._add_reg_writes(reg_sets)
self.cfile+='}\n\n' self.cfile+='}\n\n'
self.sections.append('dci_calibration') 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: if len(reg_sets)==0:
print 'No DDR start data is provided, skipping generating ddr_start()' print 'No DDR start data is provided, skipping generating ddr_start()'
return return
...@@ -362,6 +364,17 @@ inline void ddr_start(void) ...@@ -362,6 +364,17 @@ inline void ddr_start(void)
self.cfile+='}\n\n' self.cfile+='}\n\n'
self.sections.append('ddr_start') 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): def _cp_led(self,name):
led_cp=self.features.get_par_value_or_none(name) led_cp=self.features.get_par_value_or_none(name)
...@@ -407,10 +420,10 @@ void lowlevel_init(void) ...@@ -407,10 +420,10 @@ void lowlevel_init(void)
self._cp_led('LED_CHECKPOINT_5') # After UART is programmed self._cp_led('LED_CHECKPOINT_5') # After UART is programmed
if self.features.get_par_value_or_none('DUMP_SLCR_EARLY'): 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' 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'): 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+='\tdump_ddrc_regs(); /*Dump all DDRC registers before DCI/DDR initialization */\n'
self.cfile+='''/* self.cfile+='''/*
Calibrate DDR DCI impedance and wait for completion Calibrate DDR DCI impedance and wait for completion
...@@ -427,10 +440,10 @@ void lowlevel_init(void) ...@@ -427,10 +440,10 @@ void lowlevel_init(void)
''' '''
self._cp_led('LED_CHECKPOINT_7') # After DDR is initialized self._cp_led('LED_CHECKPOINT_7') # After DDR is initialized
if self.features.get_par_value_or_none('DUMP_SLCR_LATE'): 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' 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'): 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+='\tdump_ddrc_regs(); /*Dump all DDRC registers after DCI/DDR initialization */\n'
self.cfile+='''/* 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
...@@ -440,9 +453,8 @@ void lowlevel_init(void) ...@@ -440,9 +453,8 @@ void lowlevel_init(void)
\twhile (s< ((int *)0x30000)) *d++=*s++; \twhile (s< ((int *)0x30000)) *d++=*s++;
''' '''
# CONFIG_EZYNQ_LED_CHECKPOINT_10 = OFF # Before relocation down to address 0 self.cfile+='\tddrc_wait_queue_empty(); /* Wait no commands are pending in DDRC queue */\n'
# 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._cp_led('LED_CHECKPOINT_8') # Before relocation to DDR (to 0x4000000+ )
self.cfile+='''/* 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
...@@ -452,6 +464,8 @@ void lowlevel_init(void) ...@@ -452,6 +464,8 @@ void lowlevel_init(void)
\tasm("add pc, pc, #0x4000000" ); \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._cp_led('LED_CHECKPOINT_9') # After relocation to DDR (to 0x4000000+ )
self.cfile+='''/* self.cfile+='''/*
Remap DDR to zero, FILTERSTART Remap DDR to zero, FILTERSTART
...@@ -479,6 +493,9 @@ void lowlevel_init(void) ...@@ -479,6 +493,9 @@ void lowlevel_init(void)
\ts= (int *) 0x4000000; \ts= (int *) 0x4000000;
\td= (int *) 0; \td= (int *) 0;
\twhile (d < ((int *) 0x30000)) *d++=*s++; \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, 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 currently executing somewhere above 0x4000000. But as soon as we will return
...@@ -493,6 +510,9 @@ void lowlevel_init(void) ...@@ -493,6 +510,9 @@ void lowlevel_init(void)
\t/* Urgent write, ports S2/S3 */ \t/* Urgent write, ports S2/S3 */
\twritel(0xC, &slcr_base->ddr_urgent); \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._cp_led('LED_CHECKPOINT_12') # Before leaving lowlevel_init()
self.cfile+='''/* Lock SLCR back after everything with it is done */ self.cfile+='''/* Lock SLCR back after everything with it is done */
\tlock_slcr(); \tlock_slcr();
......
...@@ -354,7 +354,6 @@ if raw_config_value('CONFIG_EZYNQ_SKIP_DDR', raw_configs) is None: ...@@ -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'}) segments.append({'TO':len(reg_sets),'RBL':True,'NAME':'DDR0','TITLE':'DDR registers configuration'})
else: else:
print 'Debug mode: skipping DDR-related configuration' print 'Debug mode: skipping DDR-related configuration'
#initialize clocks #initialize clocks
# unlock slcr - it is locked by RBL, but attempt to unlock in RBL will fail (and hang the system) # 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) reg_sets=clk.clocks_regs_setup(reg_sets,force)
...@@ -405,6 +404,14 @@ if not led_debug_mio_pin is None: ...@@ -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_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 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'})
#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): # 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
...@@ -504,9 +511,14 @@ if 'UART_XMIT' in segment_dict: ...@@ -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 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']])
if 'DDR' in segment_dict: if 'DDR_START' in segment_dict:
u_boot.ddr_start (reg_sets[segment_dict['DDR']['FROM']:segment_dict['DDR']['TO']],ddr) 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.make_lowlevel_init()
u_boot.output_c_file(args.lowlevel) u_boot.output_c_file(args.lowlevel)
#print u_boot.get_c_file() #print u_boot.get_c_file()
...@@ -10,10 +10,10 @@ CONFIG_EZYNQ_DUMP_DDRC_LATE = y # Dump DDRC registers after DDR memory is initia ...@@ -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 #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 #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_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_2 = OFF # First after getting to user code
#CONFIG_EZYNQ_LED_CHECKPOINT_3 = ON # After setting clock registers 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_4 = OFF # After PLL bypass is OFF
#CONFIG_EZYNQ_LED_CHECKPOINT_5 = ON # After UART is programmed CONFIG_EZYNQ_LED_CHECKPOINT_5 = ON # After UART is programmed
CONFIG_EZYNQ_LED_CHECKPOINT_6 = OFF # After DCI is calibrated CONFIG_EZYNQ_LED_CHECKPOINT_6 = OFF # After DCI is calibrated
CONFIG_EZYNQ_LED_CHECKPOINT_7 = ON # After DDR is initialized 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_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