Commit ca3abcf6 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

troubleshooting sporadic boot failures - fixed

parent 637fe000
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -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
+27 −14
Original line number Diff line number Diff line
@@ -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:
+29 −23
Original line number Diff line number Diff line
@@ -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_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              /* Dump (some of) OCM data */
#define CONFIG_EZYNQ_DUMP_DDR              /* Dump (some of) DDR data */
#if 0
#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 */