Commit ca3abcf6 authored by Andrey Filippov's avatar Andrey Filippov

troubleshooting sporadic boot failures - fixed

parent 637fe000
......@@ -290,8 +290,26 @@ class EzynqMIO:
self.verbosity= verbosity
self.slcr_register_set= ezynq_registers.EzynqRegisters(self.MIO_PINS_DEFS,0,regs_masked,permit_undefined_bits)
self.gpio_register_set= ezynq_registers.EzynqRegisters(self.GPIO_DEFS,0,regs_masked,permit_undefined_bits)
def generate_led_off_on(self, mio_pin):
if ('DATA_OUT' in self.mio[mio_pin]) or (('INOUT' in self.mio[mio_pin]) and (self.mio[mio_pin]['INOUT'] == 'OUT')):
return self.generate_gpio_led_off_on(mio_pin)
else:
return self.generate_led_off_on_pullup(mio_pin)
def generate_gpio_led_off_on(self,mio_pin):
mask_data_regs_mio=('mask_data_0_lsw','mask_data_0_msw','mask_data_1_lsw','mask_data_1_msw');
led_register_set= ezynq_registers.EzynqRegisters(self.GPIO_DEFS,0,[])
led_register_set.set_bitfields(mask_data_regs_mio[mio_pin/16],
(('mask%02i'%mio_pin,0), # enable setting bit
('data%02i'%mio_pin,0))) # data to set
led_register_set.flush()
led_register_set.set_bitfields(mask_data_regs_mio[mio_pin/16],
(('mask%02i'%mio_pin,0), # enable setting bit
('data%02i'%mio_pin,1))) # data to set
return led_register_set.get_register_sets(True,True)
def generate_led_off_on_pullup(self, mio_pin):
# generate code to be included in u-boot for debugging early boot stages
led_register_set= ezynq_registers.EzynqRegisters(self.MIO_PINS_DEFS,0,[])
led_register_set.set_bitfields('mio_pin_%02i'%mio_pin, ( # output 0 - LED off
......@@ -301,7 +319,7 @@ class EzynqMIO:
led_register_set.set_bitfields('mio_pin_%02i'%mio_pin, ( # input+pullup LED on
('pullup', 1),
('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(True,True)
def rbl_led_on_off(self, mio_pin, led_on, reg_sets):
# generate code to be included in RBL register setup
......
......@@ -88,6 +88,8 @@ UBOOT_CFG_DEFS=[
'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()'},
{'NAME':'LAST_PRINT_DEBUG', 'CONF_NAME':'CONFIG_EZYNQ_LAST_PRINT_DEBUG','TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':None,
'DESCRIPTION':'Output to UART before exiting arch_cpu_init()'},
]
#
# CONFIG_EZYNQ_BOOT_DEBUG = y # configure UARTx and send register dumps there
......@@ -422,9 +424,9 @@ inline void ddrc_wait_queue_empty(void)
# print name, led_cp
if not led_cp is None:
if led_cp:
self.cfile+='\tdebug_led_on(); /* Turn debug LED ON */\n'
self.cfile+='\tdebug_led_on(); /* Turn debug LED ON: %s */\n'%name
else:
self.cfile+='\tdebug_led_off(); /* Turn debug LED OFF */\n'
self.cfile+='\tdebug_led_off(); /* Turn debug LED OFF: %s*/\n'%name
def _read_bit_field(self,reg_set,reg_name,field_name,channel=0): #accepts bit field tuple instead of the field name
addr=reg_set['BASE_ADDR'][channel]+ reg_set[reg_name]['OFFS']
if isinstance(field_name,tuple):
......@@ -494,18 +496,14 @@ void report_training(void)
self._report_bit_field('BIST errors from reg_6d (1 bit per slice)',DDRC_DEFS,'reg_6d','phy_reg_bist_err')
self.cfile+='\tuart_puts("\\r\\n");\n'
self.cfile+='\tuart_puts("Adjusted always:\\r\\n");\n'
self._report_bit_field('FIFO WE DLL SLICE 0',DDRC_DEFS,'reg_69','phy_reg_status_fifo_we_slave_dll_value')
self._report_bit_field('FIFO WE DLL SLICE 1',DDRC_DEFS,'reg_6a','phy_reg_status_fifo_we_slave_dll_value')
self._report_bit_field('FIFO WE DLL SLICE 2',DDRC_DEFS,'reg_6c','phy_reg_status_fifo_we_slave_dll_value')
self._report_bit_field('FIFO WE DLL SLICE 3',DDRC_DEFS,'reg_6d','phy_reg_status_fifo_we_slave_dll_value')
self.cfile+='\tuart_puts("\\r\\n");\n'
# self._report_bit_field('Ratio from Read Gate Training SLICE 0', DDRC_DEFS,'reg_69','phy_reg_rdlvl_fifowein_ratio')
# self._report_bit_field('Ratio from Read Gate Training SLICE 1', DDRC_DEFS,'reg_6a','phy_reg_rdlvl_fifowein_ratio')
# self._report_bit_field('Ratio from Read Gate Training SLICE 2', DDRC_DEFS,'reg_6c','phy_reg_rdlvl_fifowein_ratio')
# self._report_bit_field('Ratio from Read Gate Training SLICE 3', DDRC_DEFS,'reg_6d','phy_reg_rdlvl_fifowein_ratio')
# self.cfile+='\tuart_puts("\\r\\n");\n'
self.cfile+='\tuart_puts("Adjusted when CONFIG_EZYNQ_DDR_TRAIN_READ_GATE is set :\\r\\n");\n'
self._report_multi_bit_fields('FIFO WE ratio SLICE 0',DDRC_DEFS,(('reg_6a',( 9, 9)),('reg_69',( 9,18))))
self._report_multi_bit_fields('FIFO WE ratio SLICE 1',DDRC_DEFS,(('reg_6c',( 9,10)),('reg_6a',(10,18))))
self._report_multi_bit_fields('FIFO WE ratio SLICE 2',DDRC_DEFS,(('reg_6d',( 9,11)),('reg_6c',(11,18))))
......@@ -514,36 +512,42 @@ void report_training(void)
('reg_6d',(12,18))))
self.cfile+='\tuart_puts("\\r\\n");\n'
self.cfile+='\tuart_puts("Adjusted when CONFIG_EZYNQ_DDR_TRAIN_DATA_EYE is set :\\r\\n");\n'
self._report_bit_field('DQS ratio from Read Data Eye Training SLICE 0',DDRC_DEFS,'reg_6e','phy_reg_rdlvl_dqs_ratio')
self._report_bit_field('DQS ratio from Read Data Eye Training SLICE 1',DDRC_DEFS,'reg_6f','phy_reg_rdlvl_dqs_ratio')
self._report_bit_field('DQS ratio from Read Data Eye Training SLICE 2',DDRC_DEFS,'reg_70','phy_reg_rdlvl_dqs_ratio')
self._report_bit_field('DQS ratio from Read Data Eye Training SLICE 3',DDRC_DEFS,'reg_71','phy_reg_rdlvl_dqs_ratio')
self.cfile+='\tuart_puts("\\r\\n");\n'
self.cfile+='\tuart_puts("Adjusted when CONFIG_EZYNQ_DDR_TRAIN_WRITE_LEVEL is set :\\r\\n");\n'
self._report_bit_field('DQ write data ratio from Write Leveling Training SLICE 0',DDRC_DEFS,'reg_6e','phy_reg_wrlvl_dq_ratio')
self._report_bit_field('DQ write data ratio from Write Leveling Training SLICE 1',DDRC_DEFS,'reg_6f','phy_reg_wrlvl_dq_ratio')
self._report_bit_field('DQ write data ratio from Write Leveling Training SLICE 2',DDRC_DEFS,'reg_70','phy_reg_wrlvl_dq_ratio')
self._report_bit_field('DQ write data ratio from Write Leveling Training SLICE 3',DDRC_DEFS,'reg_71','phy_reg_wrlvl_dq_ratio')
self.cfile+='\tuart_puts("\\r\\n");\n'
self.cfile+='\tuart_puts("Adjusted when CONFIG_EZYNQ_DDR_TRAIN_WRITE_LEVEL is set :\\r\\n");\n'
self._report_bit_field('DQS write ratio from Write Leveling Training SLICE 0',DDRC_DEFS,'reg_6e','phy_reg_wrlvl_dqs_ratio')
self._report_bit_field('DQS write ratio from Write Leveling Training SLICE 1',DDRC_DEFS,'reg_6f','phy_reg_wrlvl_dqs_ratio')
self._report_bit_field('DQS write ratio from Write Leveling Training SLICE 2',DDRC_DEFS,'reg_70','phy_reg_wrlvl_dqs_ratio')
self._report_bit_field('DQS write ratio from Write Leveling Training SLICE 3',DDRC_DEFS,'reg_71','phy_reg_wrlvl_dqs_ratio')
self.cfile+='\tuart_puts("\\r\\n");\n'
self.cfile+='\tuart_puts("Adjusted when CONFIG_EZYNQ_DDR_TRAIN_WRITE_LEVEL is set :\\r\\n");\n'
self._report_bit_field('Delay for write DQS slave DLL SLICE 0',DDRC_DEFS,'phy_dll_sts0','phy_reg_status_wr_dqs_slave_dll_value')
self._report_bit_field('Delay for write DQS slave DLL SLICE 1',DDRC_DEFS,'phy_dll_sts1','phy_reg_status_wr_dqs_slave_dll_value')
self._report_bit_field('Delay for write DQS slave DLL SLICE 2',DDRC_DEFS,'phy_dll_sts2','phy_reg_status_wr_dqs_slave_dll_value')
self._report_bit_field('Delay for write DQS slave DLL SLICE 3',DDRC_DEFS,'phy_dll_sts3','phy_reg_status_wr_dqs_slave_dll_value')
self.cfile+='\tuart_puts("\\r\\n");\n'
self.cfile+='\tuart_puts("Adjusted when CONFIG_EZYNQ_DDR_TRAIN_WRITE_LEVEL is set :\\r\\n");\n'
self._report_bit_field('Delay for write DQ slave DLL SLICE 0',DDRC_DEFS,'phy_dll_sts0','phy_reg_status_wr_data_slave_dll_value')
self._report_bit_field('Delay for write DQ slave DLL SLICE 1',DDRC_DEFS,'phy_dll_sts1','phy_reg_status_wr_data_slave_dll_value')
self._report_bit_field('Delay for write DQ slave DLL SLICE 2',DDRC_DEFS,'phy_dll_sts2','phy_reg_status_wr_data_slave_dll_value')
self._report_bit_field('Delay for write DQ slave DLL SLICE 3',DDRC_DEFS,'phy_dll_sts3','phy_reg_status_wr_data_slave_dll_value')
self.cfile+='\tuart_puts("\\r\\n");\n'
self.cfile+='\tuart_puts("Adjusted always:\\r\\n");\n'
self._report_bit_field('Delay for read DQ slave DLL SLICE 0',DDRC_DEFS,'phy_dll_sts0','phy_reg_status_rd_dqs_slave_dll_value')
self._report_bit_field('Delay for read DQ slave DLL SLICE 1',DDRC_DEFS,'phy_dll_sts1','phy_reg_status_rd_dqs_slave_dll_value')
self._report_bit_field('Delay for read DQ slave DLL SLICE 2',DDRC_DEFS,'phy_dll_sts2','phy_reg_status_rd_dqs_slave_dll_value')
......@@ -579,6 +583,9 @@ int arch_cpu_init(void)
\tunlock_slcr();
'''
#Setup GPIO outputs (To be used by LED)
if 'gpio_out' in self.sections:
self.cfile+='\tsetup_gpio_outputs(); /* Setup GPIO outputs */\n'
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
......@@ -685,6 +692,12 @@ int arch_cpu_init(void)
\tddrc_wait_queue_empty(); /* Wait no commands are pending in DDRC queue */
\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
......@@ -699,7 +712,8 @@ int arch_cpu_init(void)
\t/* Urgent write, ports S2/S3 */
\twritel(0xC, &slcr_base->ddr_urgent);
'''
if 'uart_xmit' in self.sections:
if ('uart_xmit' in self.sections) and self.features.get_par_value_or_none('LAST_PRINT_DEBUG'):
self.cfile+='\tuart_put_hex(readl(0xe000002c));\n'
self.cfile+='\tuart_putc(0xd);\n'
self.cfile+='\tuart_putc(0xa);\n'
......@@ -720,15 +734,14 @@ int arch_cpu_init(void)
self.cfile+='\tuart_putc(0xd);\n'
self.cfile+='\tuart_putc(0xa);\n'
self.cfile+='\twhile((readl(0xe000002c) & 0x808) != 8); /* uart0.channel_sts Channel status */\n'
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()
#Setup GPIO outputs (after LED debug is over)
if 'gpio_out' in self.sections:
self.cfile+='\tsetup_gpio_outputs(); /* Setup GPIO outputs */\n'
# #Setup GPIO outputs (after LED debug is over)
# if 'gpio_out' in self.sections:
# self.cfile+='\tsetup_gpio_outputs(); /* Setup GPIO outputs */\n'
#LOCK_SLCR
if self.features.get_par_value_or_none('LOCK_SLCR') is False:
......
......@@ -30,35 +30,37 @@
#define CONFIG_EZYNQ_BOOT_DEBUG Y /* configure UARTx and send register dumps there.*/
#define CONFIG_EZYNQ_LOCK_SLCR OFF /* Lock SLCR registers when all is done. */
#define CONFIG_EZYNQ_DUMP_SLCR_EARLY /* Dump SLCR registers as soon as UART is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG) */
#define CONFIG_EZYNQ_DUMP_DDRC_EARLY /* Dump DDRC registers as soon as UART is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG) */
#define CONFIG_EZYNQ_DUMP_SLCR_LATE /* Dump SLCR registers after DDR memory is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG) */
#define CONFIG_EZYNQ_DUMP_DDRC_LATE /* Dump DDRC registers after DDR memory is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG) */
#define CONFIG_EZYNQ_DUMP_TRAINING_EARLY N /* Training results registers before DDRC initialization */
#define CONFIG_EZYNQ_DUMP_TRAINING_LATE Y /* Training results registers after DDRC initialization */
#define CONFIG_EZYNQ_DUMP_OCM /* Dump (some of) OCM data */
#define CONFIG_EZYNQ_DUMP_DDR /* Dump (some of) DDR data */
#if 0
#define CONFIG_EZYNQ_DUMP_SLCR_EARLY N /* Dump SLCR registers as soon as UART is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG) */
#define CONFIG_EZYNQ_DUMP_DDRC_EARLY N /* Dump DDRC registers as soon as UART is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG) */
#define CONFIG_EZYNQ_DUMP_SLCR_LATE N /* Dump SLCR registers after DDR memory is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG) */
#define CONFIG_EZYNQ_DUMP_DDRC_LATE N /* Dump DDRC registers after DDR memory is initialized (depends on CONFIG_EZYNQ_BOOT_DEBUG) */
#define CONFIG_EZYNQ_DUMP_TRAINING_EARLY N /* Training results registers before DDRC initialization */
#define CONFIG_EZYNQ_DUMP_TRAINING_LATE Y /* Training results registers after DDRC initialization */
#define CONFIG_EZYNQ_DUMP_OCM N /* Dump (some of) OCM data */
#define CONFIG_EZYNQ_DUMP_DDR N /* Dump (some of) DDR data */
#if 1
#define CONFIG_EZYNQ_DUMP_OCM_LOW 0x0 /* OCM dump start (deafault 0) */
#define CONFIG_EZYNQ_DUMP_OCM_HIGH 0x2ff /* OCM dump end (deafault 0x2ff, full - 0x2ffff) */
#define CONFIG_EZYNQ_DUMP_DDR_LOW 0x4000000 /* DDR dump start (deafault 0x4000000, start of the OCM copy) */
#define CONFIG_EZYNQ_DUMP_DDR_HIGH 0x40002ff /* DDR dump end (deafault 0x40002ff) */
#define CONFIG_EZYNQ_DUMP_DDR_LOW 0x4001014 /* DDR dump start (deafault 0x4000000, start of the OCM copy) */
//#define CONFIG_EZYNQ_DUMP_DDR_HIGH 0x400152f /* DDR dump end (deafault 0x40002ff) */
#define CONFIG_EZYNQ_DUMP_DDR_HIGH 0x300152f /* DDR dump end (deafault 0x40002ff) */
#endif
/* Turning LED on/off at different stages of the boot process. Requires CONFIG_EZYNQ_LED_DEBUG and CONFIG_EZYNQ_BOOT_DEBUG to be set
If defined, each can be 0,1, ON or OFF */
#define CONFIG_EZYNQ_LED_CHECKPOINT_1 ON /* in RBL setup, as soon as MIO is programmed */
#define CONFIG_EZYNQ_LED_CHECKPOINT_1 OFF /* in RBL setup, as soon as MIO is programmed, should be OFF to use GPIO */
#define CONFIG_EZYNQ_LED_CHECKPOINT_2 OFF /* First after getting to user code */
#define CONFIG_EZYNQ_LED_CHECKPOINT_3 ON /* After setting clock registers */
#define CONFIG_EZYNQ_LED_CHECKPOINT_3 OFF /* After setting clock registers */
#define CONFIG_EZYNQ_LED_CHECKPOINT_4 OFF /* After PLL bypass is OFF */
#define CONFIG_EZYNQ_LED_CHECKPOINT_5 ON /* After UART is programmed */
#define CONFIG_EZYNQ_LED_CHECKPOINT_5 OFF /* After UART is programmed */
#define CONFIG_EZYNQ_LED_CHECKPOINT_6 OFF /* After DCI is calibrated */
#define CONFIG_EZYNQ_LED_CHECKPOINT_7 ON /* After DDR is initialized */
#define CONFIG_EZYNQ_LED_CHECKPOINT_7 OFF /* After DDR is initialized */
#define CONFIG_EZYNQ_LED_CHECKPOINT_8 OFF /* Before relocation to DDR (to 0x4000000+ ) */
#define CONFIG_EZYNQ_LED_CHECKPOINT_9 ON /* After relocation to DDR (to 0x4000000+ ) */
#define CONFIG_EZYNQ_LED_CHECKPOINT_10 OFF /* Before remapping OCM0-OCM2 high */
#define CONFIG_EZYNQ_LED_CHECKPOINT_9 OFF /* After relocation to DDR (to 0x4000000+ ) */
#define CONFIG_EZYNQ_LED_CHECKPOINT_10 ON /* Before remapping OCM0-OCM2 high */
#define CONFIG_EZYNQ_LED_CHECKPOINT_11 ON /* After remapping OCM0-OCM2 high */
#define CONFIG_EZYNQ_LED_CHECKPOINT_12 OFF /* Before leaving lowlevel_init() */
#define CONFIG_EZYNQ_LED_CHECKPOINT_12 ON /* Before leaving lowlevel_init() */
#define CONFIG_EZYNQ_LAST_PRINT_DEBUG N /* 'Output to UART before exiting arch_cpu_init() */
/* MIO configuration */
#define CONFIG_EZYNQ_OCM /* not used */
#define CONFIG_EZYNQ_MIO_0_VOLT 1.8
......@@ -67,7 +69,9 @@
#define CONFIG_EZYNQ_NAND__SLOW
#define CONFIG_EZYNQ_MIO_ETH_0__SLOW
/* TODO: enable MDIO */
/*#define CONFIG_EZYNQ_MIO_ETH_MDIO__SLOW */
#define CONFIG_EZYNQ_MIO_USB_0__SLOW
#define CONFIG_EZYNQ_MIO_USB_0__PULLUP
......@@ -103,9 +107,9 @@ output (or undefined) - off
#define CONFIG_EZYNQ_DDR_ARB_PAGE_BANK N /* Enable Arbiter prioritization based on page/bank match */
#define CONFIG_EZYNQ_DDR_ECC Disabled /* Enable ECC for the DDR memory */
#define CONFIG_EZYNQ_DDR_BUS_WIDTH 32 /* SoC DDR bus width */
#define CONFIG_EZYNQ_DDR_TRAIN_WRITE_LEVEL 0 /* Automatically train write leveling during initialization */
#define CONFIG_EZYNQ_DDR_TRAIN_READ_GATE 0 /* Automatically train read gate timing during initialization */
#define CONFIG_EZYNQ_DDR_TRAIN_DATA_EYE 0 /* Automatically train data eye during initialization */
#define CONFIG_EZYNQ_DDR_TRAIN_WRITE_LEVEL 1 /* Automatically train write leveling during initialization */
#define CONFIG_EZYNQ_DDR_TRAIN_READ_GATE 1 /* Automatically train read gate timing during initialization */
#define CONFIG_EZYNQ_DDR_TRAIN_DATA_EYE 1 /* Automatically train data eye during initialization */
#define CONFIG_EZYNQ_DDR_CLOCK_STOP_EN 0 /* Enable clock stop */
#define CONFIG_EZYNQ_DDR_USE_INTERNAL_VREF 0 /* Use internal Vref */
......@@ -212,7 +216,9 @@ output (or undefined) - off
/* Below will overwrite calculated values (not yet calculated) */
#if 1 /*testing old version */
/* LED will be ON */
#define CONFIG_EZYNQ_MIO_INOUT_53 OUT /* Make output, do not set data. Will be set after debug will be over */
// #define CONFIG_EZYNQ_MIO_INOUT_53 OUT /* Make output, do not set data. Will be set after debug will be over */
#define CONFIG_EZYNQ_MIO_GPIO_OUT_53 0 /* Set selected GPIO output to 0/1 */
#undef CONFIG_EZYNQ_DDR_DS_CKE
#define CONFIG_EZYNQ_DDR_DS_CKE 4 /* CKE min pulse width (in tCK) */
......@@ -223,7 +229,7 @@ output (or undefined) - off
#define CONFIG_EZYNQ_LED_DEBUG 53 /* toggle LED during boot - temporary, normal use - MDIO_D */
#define CONFIG_EZYNQ_UART_DEBUG_USE_LED /* turn on/off LED while waiting for transmit FIFO not full */
#define CONFIG_EZYNQ_UART_DEBUG_USE_LED N /* turn on/off LED while waiting for transmit FIFO not full */
#define CONFIG_EZYNQ_SILICON 3 /* 3 */ /* Silicon revision */
#define CONFIG_EZYNQ_PHY_WRLV_INIT_RATIO_0 0x0 /* Initial ratio for write leveling FSM, slice 0 */
......
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