Commit 496a0d6f authored by Eyesisbox Elphel's avatar Eyesisbox Elphel

Working on DDR configuration

parent 5b2e54e8
#!/usr/bin/env python
# Copyright (C) 2013, Elphel.inc.
# Definitions of configuration parameters for DDR memory
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
__author__ = "Andrey Filippov"
__copyright__ = "Copyright 2013, Elphel, Inc."
__license__ = "GPL"
__version__ = "3.0+"
__maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__status__ = "Development"
DDR_CFG_DEFS={
'TARGET_FREQ_MHZ': {'CONF_NAME':'CONFIG_EZYNQ_DDR_TARGET_FREQ_MHZ','TYPE':'F','MANDATORY':True,'DERIVED':True,'DEFAULT':533.333333,
'DESCRIPTION':'Target DDR clock frequency in MHz (actual frequency will depend on the clock/clock muxes)'},
'FREQ_MHZ': {'CONF_NAME':'CONFIG_EZYNQ_DDR_FREQ_MHZ','TYPE':'F','MANDATORY':True,'DERIVED':True,'DEFAULT':533.333333,
'DESCRIPTION':'Actual DDR clock frequency in MHz, may be derived form CONFIG_EZYNQ_DDR_TARGET_FREQ_MHZ and clock multiplexer settings'},
'CL': {'CONF_NAME':'CONFIG_EZYNQ_DDR_CL','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':7,
'DESCRIPTION':'CAS read latency (in tCK)'},
'AL': {'CONF_NAME':'CONFIG_EZYNQ_DDR_CL','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':0,
'DESCRIPTION':'Posted CAS additive latency (in tCK)'},
'CWL': {'CONF_NAME':'CONFIG_EZYNQ_DDR_CWL','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':6,
'DESCRIPTION':'CAS write latency (in tCK)'},
'RCD': {'CONF_NAME':'CONFIG_EZYNQ_DDR_RCD','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':7,
'DESCRIPTION':'RAS to CAS delay (in tCK)'},
'RP': {'CONF_NAME':'CONFIG_EZYNQ_DDR_RP','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':7,
'DESCRIPTION':'Row Precharge time (in tCK)'},
'T_RC': {'CONF_NAME':'CONFIG_EZYNQ_DDR_T_RC','TYPE':'F','MANDATORY':True,'DERIVED':False,'DEFAULT':48.75,
'DESCRIPTION':'Activate to Activate or Refresh command period (ns)'},
'T_RAS_MIN': {'CONF_NAME':'CONFIG_EZYNQ_DDR_T_RAS_MIN','TYPE':'F','MANDATORY':True,'DERIVED':False,'DEFAULT':35.0,
'DESCRIPTION':'Minimal Row Active time (ns)'},
'T_FAW': {'CONF_NAME':'CONFIG_EZYNQ_DDR_T_FAW','TYPE':'F','MANDATORY':True,'DERIVED':False,'DEFAULT':40.0,
'DESCRIPTION':'Minimal running window for 4 page activates (ns)'},
'BANK_ADDR_COUNT': {'CONF_NAME':'CONFIG_EZYNQ_DDR_BANK_ADDR_COUNT','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':3,
'Number of DDR banks'},
'ROW_ADDR_COUNT': {'CONF_NAME':'CONFIG_EZYNQ_DDR_ROW_ADDR_COUNT','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':15,
'Number of DDR banks'},
'COL_ADDR_COUNT': {'CONF_NAME':'CONFIG_EZYNQ_DDR_COL_ADDR_COUNT','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':10,
'Number of DDR banks'},
'ENABLE': {'CONF_NAME':'CONFIG_EZYNQ_DDR_ENABLE','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':True,
'Enable DDR memory'},
'MEMORY_TYPE': {'CONF_NAME':'CONFIG_EZYNQ_DDR_MEMORY_TYPE','TYPE':('DDR3','DDR2','LPDDR2'),'MANDATORY':True,'DERIVED':False,'DEFAULT':'DDR3',
'DDR memory type'},
'ECC': {'CONF_NAME':'CONFIG_EZYNQ_DDR_ECC','TYPE':'B','MANDATORY':False,'DERIVED':False,'DEFAULT':False,
'Enable ECC for the DDR memory'},
'BUS_WIDTH': {'CONF_NAME':'CONFIG_EZYNQ_DDR_BUS_WIDTH','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':32,
'SoC DDR bus width'},
'BL': {'CONF_NAME':'CONFIG_EZYNQ_DDR_BL','TYPE':(4,8),'MANDATORY':True,'DERIVED':False,'DEFAULT':8, # DDR2 may have different lengths?
'Burst length'},
'HIGH_TEMP': {'CONF_NAME':'CONFIG_EZYNQ_DDR_HIGH_TEMP','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
'High temperature (influences refresh)'},
'PARTNO': {'CONF_NAME':'CONFIG_EZYNQ_DDR_PARTNO','TYPE':'T','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
'Memory part number (currently not used - derive some parameters late)'},
'DRAM_WIDTH': {'CONF_NAME':'CONFIG_EZYNQ_DDR_DRAM_WIDTH','TYPE':'I','MANDATORY':True,'DERIVED':False,'DEFAULT':16,
'Memory chip bus width'},
'SPEED_BIN': {'CONF_NAME':'CONFIG_EZYNQ_DDR_SPEED_BIN','TYPE':'T','MANDATORY':True,'DERIVED':False,'DEFAULT':16,
'Memory speed bin (currently not used - derive timing later)'},
'TRAIN_WRITE_LEVEL':{'CONF_NAME':'CONFIG_EZYNQ_DDR_TRAIN_WRITE_LEVEL','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
'Automatically train write leveling during initialization'},
'TRAIN_READ_GATE': {'CONF_NAME':'CONFIG_EZYNQ_DDR_TRAIN_READ_GATE','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
'Automatically train read gate timing during initialization'},
'TRAIN_DATA_EYE': {'CONF_NAME':'CONFIG_EZYNQ_DDR_TRAIN_DATA_EYE','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
'Automatically train data eye during initialization'},
'CLOCK_STOP_EN': {'CONF_NAME':'CONFIG_EZYNQ_DDR_CLOCK_STOP_EN','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
'Enable clock stop'},
'INTERNAL_VREF': {'CONF_NAME':'CONFIG_EZYNQ_DDR_USE_INTERNAL_VREF','TYPE':'B','MANDATORY':True,'DERIVED':False,'DEFAULT':False,
'Use internal Vref'},
}
#TODO make some of (possibly) derived, leave '_T_' for ns only!
# CONFIG_EZYNQ_DDR_FREQ_MHZ = 533.333333 *
# CONFIG_EZYNQ_DDR_CL = 7 *
# CONFIG_EZYNQ_DDR_CWL = 6 *
# CONFIG_EZYNQ_DDR_RCD = 7 (was CONFIG_EZYNQ_DDR_T_RCD = 7) *
# CONFIG_EZYNQ_DDR_RP = 7 (was CONFIG_EZYNQ_DDR_T_RP = 7) *
# CONFIG_EZYNQ_DDR_T_RC = 48.75 *
# CONFIG_EZYNQ_DDR_T_RAS_MIN = 35.0 *
# CONFIG_EZYNQ_DDR_T_FAW = 40.0 *
# CONFIG_EZYNQ_DDR_AL = 0 *
# CONFIG_EZYNQ_DDR_BANK_ADDR_COUNT = 3 *
# CONFIG_EZYNQ_DDR_ROW_ADDR_COUNT = 15 *
# CONFIG_EZYNQ_DDR_COL_ADDR_COUNT = 10 *
# CONFIG_EZYNQ_DDR_ENABLE = 1 *
# CONFIG_EZYNQ_DDR_MEMORY_TYPE = DDR3 *
# CONFIG_EZYNQ_DDR_ECC = Disabled *
# CONFIG_EZYNQ_DDR_BUS_WIDTH = 32 *
# CONFIG_EZYNQ_DDR_BL = 8 *
# CONFIG_EZYNQ_DDR_HIGH_TEMP = Normal *
# CONFIG_EZYNQ_DDR_PARTNO = MT41K256M16RE-125 *
# CONFIG_EZYNQ_DDR_DRAM_WIDTH = 16 *
# CONFIG_EZYNQ_DDR_SPEED_BIN = DDR3_1066F *
# CONFIG_EZYNQ_DDR_TRAIN_WRITE_LEVEL = 0
# CONFIG_EZYNQ_DDR_TRAIN_READ_GATE = 0
# CONFIG_EZYNQ_DDR_TRAIN_DATA_EYE = 0
# CONFIG_EZYNQ_DDR_CLOCK_STOP_EN = 0
# CONFIG_EZYNQ_DDR_USE_INTERNAL_VREF = 0
#CONFIG_EZYNQ_DDR_DEVICE_CAPACITY_MBITS = 4096 - can be calculated
#!/usr/bin/env python
# Copyright (C) 2013, Elphel.inc.
# configuration of the DDR-related registers
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
__author__ = "Andrey Filippov"
__copyright__ = "Copyright 2013, Elphel, Inc."
__license__ = "GPL"
__version__ = "3.0+"
__maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__status__ = "Development"
import ezynq_ddrc_defs
import ezynq_registers
class EzynqDDR:
def __init__(self,permit_undefined_bits=False,force=False,warn=False):
self.DDRC_DEFS=ezynq_ddrc_defs.DDRC_DEFS
self.register_sets= {'PRE':ezynq_registers.EzynqRegisters(self.DDRC_DEFS,0,permit_undefined_bits),
'MAIN':ezynq_registers.EzynqRegisters(self.DDRC_DEFS,0,permit_undefined_bits),
'POST':ezynq_registers.EzynqRegisters(self.DDRC_DEFS,0,permit_undefined_bits)}
# self.set_names=('PRE','MAIN','POST')
self.set_attribs=(
{'NAME':'PRE','POSTFIX':'_PRE','PREFIX':'CONFIG_EZYNQ_DDR_SETREG_','TITLE':"DDR Controller Register Pre-Set"},
{'NAME':'MAIN','POSTFIX':'','PREFIX':'CONFIG_EZYNQ_DDR_SETREG_','TITLE':"DDR Controller Register Set"},
{'NAME':'POST','POSTFIX':'_POST','PREFIX':'CONFIG_EZYNQ_DDR_SETREG_','TITLE':"DDR Controller Register Post-Set"})
self.postfixes=[attrib['POSTFIX'] for attrib in self.set_attribs]
def parse_raw_register_set(self,raw_configs,qualifier_char,force=True,warn=True):
# for i,attribs in enumerate(self.set_attribs):
for attribs in self.set_attribs:
reg_set_name=attribs['NAME']
reg_set= self.register_sets[reg_set_name]
prefix= attribs['PREFIX']
postfix= attribs['POSTFIX']
reg_set.parse_options_set(raw_configs,prefix,postfix,self.postfixes,qualifier_char,force,warn) #force - readonly/undefined fields, warn: data does not fit in the bit field
def print_html_registers(self, html_file, show_bit_fields=True, show_comments=True):
for attribs in self.set_attribs:
reg_set_name=attribs['NAME']
reg_set= self.register_sets[reg_set_name]
if len(reg_set.get_reg_names())>0:
html_file.write('<h2>'+attribs['TITLE']+'</h2>\n')
reg_set.print_html_registers(html_file, show_bit_fields, show_comments)
html_file.write('<br/>\n')
#ddr=Ezynq_DDR()
#print ddr.DDRC_DEFS
# def __init__(self,defines,channel=0,permit_undefined_bits=False):
# def parse_options_set(self,raw_configs,prefix,postfix,qualifier_char,force=True,warn=True): #force - readonly/undefined fields, warn: data does not fit in the bit field
\ No newline at end of file
#!/usr/bin/env python
# Copyright (C) 2013, Elphel.inc.
# Definitions of Zynq DDRC registers
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
__author__ = "Andrey Filippov"
__copyright__ = "Copyright 2013, Elphel, Inc."
__license__ = "GPL"
__version__ = "3.0+"
__maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__status__ = "Development"
# DDRC Registers
DDRC_DEFS={ #not all fields are defined currently
'BASE_ADDR':(0xF8006000,),
'ddrc_ctrl': {'OFFS': 0x000,'DFLT':0x00000200,'RW':'RW','FIELDS':{
'reg_ddrc_dis_auto_refresh':{'r':(16,16),'d':0,'c':'Dynamic. 1 - disable autorefresh'},
'reg_ddrc_dis_act_bypass': {'r':(15,15),'d':0,'c':'Debug. 1 - disable bypass for high priority read activity'},
'reg_ddrc_dis_rd_bypass': {'r':(14,14),'d':0,'c':'Debug. 1 - disable bypass for high priority read page hits'},
'reg_ddrc_dis_rd_bypass': {'r':( 7,13),'d':0x4,'c':'Switch to alternative transactions store after this inactivity'},
'reg_ddrc_burst8_refresh': {'r':( 4, 6),'d':0,'c':'Refresh accumulate: 0 - single refresh, 1 - burst of 2 refresh, 7 - burst of 8 refresh'},
'reg_ddrc_data_bus_width': {'r':( 2, 3),'d':0,'c':'DDR bus width: 0 - 32, 1 - 16, >=2 - reserved'},
'reg_ddrc_powerdown_en': {'r':( 1, 1),'d':0,'c':'Dynamic: 1 - enable power down on idle'},
'reg_ddrc_soft_rstb': {'r':( 0, 0),'d':0,'c':'Dynamic: Active low soft DDRC reset (and update non-dynamic registers/bit fields'}}},
'two_rank_cfg': {'OFFS': 0x004,'DFLT':0x000C1076,'RW':'RW','FIELDS':{
'reserved1': {'r':(28,28),'d':0,'c':'reserved'},
'reserved2': {'r':(27,27),'d':0,'c':'reserved'},
'reserved3': {'r':(22,26),'d':0,'c':'reserved'},
'reserved4': {'r':(21,21),'d':0,'c':'reserved'},
'reserved5': {'r':(19,20),'d':0x1,'c':'reserved'},
'reg_ddrc_addrmap_cs_ bit0':{'r':(14,18),'d':0x10,'c':'must be manually set to 0'},
'reserved6': {'r':(12,13),'d':0x1,'c':'reserved'},
'reg_ddrc_t_rfc_nom_x32': {'r':( 0,11),'d':0x76,'c':'Dynamic. tREFI, default set for DDR3'}}},
'hpr_reg': {'OFFS': 0x008,'DFLT':0x03C0780F,'RW':'RW','FIELDS':{
'reg_ddrc_hpr_xact_run_length': {'r':(22,25),'d':0xF,'c':'HPR queue transactions to be served after going critical'},
'reg_ddrc_hpr_max_starve_x32': {'r':(11,21),'d':0xF,'c':'Number of 32x clocks HPR may be starved before going critical'},
'reg_ddrc_hpr_min_non_critical_x32':{'r':( 0,10),'d':0xF,'c':'Number off 32x clocks HPR queue is guaranteed to be non-critical'}}},
'lpr_reg': {'OFFS': 0x00C,'DFLT':0x03C0780F,'RW':'RW','FIELDS':{
'reg_ddrc_lpr_xact_run_length': {'r':(22,25),'d':0xF,'c':'LPR queue transactions to be served after going critical'},
'reg_ddrc_lpr_max_starve_x32': {'r':(11,21),'d':0xF,'c':'Number of 32x clocks LPR may be starved before going critical'},
'reg_ddrc_lpr_min_non_critical_x32':{'r':( 0,10),'d':0xF,'c':'Number off 32x clocks LPR queue is guaranteed to be non-critical'}}},
'wr_reg': {'OFFS': 0x010,'DFLT':0x0007F80F,'RW':'RW','FIELDS':{
'reg_ddrc_w_max_starve_x32': {'r':(15,25),'d':0xF,'c':'Number of 32x clocks write queue may be starved before going critical'},
'reg_ddrc_w_xact_run_length': {'r':(11,14),'d':0xF,'c':'write queue transactions to be served after going critical'},
'reg_ddrc_w_min_non_critical_x32': {'r':( 0,10),'d':0xF,'c':'Number off 32x clocks write queue is guaranteed to be non-critical'}}},
'dram_param_reg0': {'OFFS': 0x014,'DFLT':0x00041016,'RW':'RW','FIELDS':{
'reg_ddrc_post_selfref_ gap_x32': {'r':(14,20),'d':0x10,'c':'DRAM-related, minimal time after self refresh'},
'reg_ddrc_t_rfc_min': {'r':( 6,15),'d':0x40,'c':'Dynamic, tRFC'},
'reg_ddrc_t_rc': {'r':( 0, 5),'d':0x16,'c':'DRAM-related tRC'}}},
'dram_param_reg1': {'OFFS': 0x018,'DFLT':0x351B48D9,'RW':'RW','FIELDS':{
'reg_ddrc_t_cke': {'r':(28,31),'d': 0x3,'c':'tCKE'},
'reg_ddrc_t_ras_min': {'r':(22,26),'d': 0x14,'c':'tRAS min (clocks)'},
'reg_ddrc_t_ras_max': {'r':(16,21),'d': 0x1b,'c':'tRAS max (x1024 clocks)'},
'reg_ddrc_t_faw': {'r':(10,15),'d': 0x12,'c':'tFAW (not more than 4 banks activated in this rolling time, clocks'},
'reg_ddrc_powerdown_ to_x32': {'r':( 5, 9),'d': 0x6,'c':'power down after this many clocks of NOP/DESELECT (if enabled in mcr)'},
'reg_ddrc_wr2pre': {'r':( 0, 4),'d': 0x19,'c':'minimal write-to-precharge, clocks'}}},
'dram_param_reg2': {'OFFS': 0x01C,'DFLT':0x83015904,'RW':'RW','FIELDS':{
'reg_ddrc_t_rcd': {'r':(28,31),'d': 0x8,'c':'tRCD-AL'},
'reg_ddrc_rd2pre': {'r':(23,27),'d': 0x6,'c':'Read to precharge in the same bank'},
'reg_ddrc_pad_pd': {'r':(20,22),'d': 0x0,'c':'non-DFI only: pads in/out powersave, in clocks'},
'reg_ddrc_t_xp': {'r':(15,19),'d': 0x2,'c':'tXP - power down exit to any operation'},
'reg_ddrc_wr2rd': {'r':(10,13),'d': 0x16,'c':'tWTR - write -to -read (clocks)'},
'reg_ddrc_rd2wr': {'r':( 5, 9),'d': 0x8,'c':'tRTW - read -to -write (clocks)'},
'reg_ddrc_write_latency': {'r':( 0, 4),'d': 0x4,'c':'one clock less than actual DDR write latency'}}},
'dram_param_reg3': {'OFFS': 0x020,'DFLT':0x250882D0,'RW':'M','FIELDS':{
'reserved': {'r':(31,31),'d': 0,'c':'reserved'},
'reg_ddrc_dis_pad_pd': {'r':(30,30),'d': 0,'c':'Disable pad power down'},
'reg_phy_mode_ddr1_d dr2': {'r':(29,29),'d': 1,'c':'Unused'},
'reg_ddrc_read_latency': {'r':(24,28),'d': 0x5,'c':'Read Latency, clocks'},
'reg_ddrc_en_dfi_dram_clk_disable': {'r':(23,23),'d': 0,'c':'Enables clock disable...'},
'reg_ddrc_mobile': {'r':(22,22),'d': 0,'c':'0 - DDR2/DDR3, 1 - LPDDR2'},
'reserved1': {'r':(21,21),'d': 0,'c':'reserved'},
'reg_ddrc_refresh_to_x32': {'r':(16,20),'d': 0x8,'c':'Dynamic, "speculative refresh"'},
'reg_ddrc_t_rp': {'r':(12,15),'d': 0x8,'c':'tRP'},
'reg_ddrc_refresh_margin': {'r':( 8,11),'d': 0x2,'c':'do refresh this cycles before timer expires'},
'reg_ddrc_t_rrd': {'r':( 5, 7),'d': 0x6,'c':'tRRD Minimal time between activates of different banks'},
'reg_ddrc_t_ccd': {'r':( 2, 4),'d': 0x4,'c':'tCCD One less than minimal time between reads of writes to different banks'},
'reserved2': {'r':( 0, 1),'d': 0,'m':'R','c':'reserved'}}},
'dram_param_reg4': {'OFFS': 0x024,'DFLT':0x0000003C,'RW':'M','FIELDS':{
'reg_ddrc_mr_rdata_valid': {'r':(27,27),'d': 0,'m':'R','c':'cleared by reading mode_reg_read (0x2a4), set when mode_reg_read gets new data'},
'reg_ddrc_mr_type': {'r':(26,26),'d': 0,'c':'0 - mode register write, 1 - mode register read'},
'ddrc_reg_mr_wr_busy': {'r':(25,25),'d': 0,'m':'R','c':'1 - do not issue mode register R/W (wait 0)'},
'reg_ddrc_mr_data': {'r':( 9,24),'d': 0,'c':'DDR2/3: Mode Register Write data'},
'reg_ddrc_mr_addr': {'r':( 7, 8),'d': 0,'c':'DDR2/3: Mode Register address (0 - MR0, ... 3 - MR3)'},
'reg_ddrc_mr_wr': {'r':( 6, 6),'d': 0,'m':'W','c':'low-to-high starts mode reg r/w (if not ddrc_reg_mr_wr_busy)'},
'reserved1': {'r':( 2, 5),'d': 0xF,'c':'reserved'},
'reg_ddrc_prefer_write': {'r':( 1, 1),'d': 0,'c':'1: Bank selector prefers writes over reads'},
'reg_ddrc_en_2t_timing_mode': {'r':( 0, 0),'d': 0,'c':'0 - DDRC uses 1T timing, 1 - 2T timing'}}},
'dram_init_param': {'OFFS': 0x028,'DFLT':0x00002007,'RW':'RW','FIELDS':{
'reg_ddrc_t_mrd': {'r':(11,13),'d': 0x4,'c':'tMRD - cycles between Load Mode commands (default is set for DDR3)'},
'reg_ddrc_pre_ocd_x32': {'r':( 7,10),'d': 0,'c':'OCD complete delay (may be 0)'},
'reg_ddrc_final_wait_x32': {'r':( 0, 6),'d': 0x7,'c':'Wait after DDR INIT (set for DDR3)'}}},
'dram_emr_reg': {'OFFS': 0x02C,'DFLT':0x00000008,'RW':'RW','FIELDS':{
'reg_ddrc_emr3': {'r':(16,31),'d': 0,'c':'DDR3: Value loaded into MR3 reg, DDR2: EMR3, LPDDR2 - unused'},
'reg_ddrc_emr2': {'r':( 0,15),'d': 0x8,'c':'DDR3: Value loaded into MR2 reg, DDR2: EMR2, LPDDR2 - MR3'}}},
'dram_emr_mr_reg': {'OFFS': 0x030,'DFLT':0x00000940,'RW':'RW','FIELDS':{
'reg_ddrc_emr': {'r':(16,31),'d': 0,'c':'DDR3: Value loaded into MR1 reg, DDR2: EMR1, LPDDR2 - MR2'},
'reg_ddrc_mr': {'r':( 0,15),'d': 0x940,'c':'DDR3: Value loaded into MR0 reg, DDR2: MR, LPDDR2 - MR1'}}},
'dram_burst8_rdwr': {'OFFS': 0x034,'DFLT':0x00020304,'RW':'M','FIELDS':{
'reg_ddrc_burstchop': {'r':(28,28),'d':0,'c':' Not supported, 1 - burstchop mode'},
'reserved1': {'r':(26,27),'d':0,'m':'R','c':'reserved'},
'reg_ddrc_post_cke_x1024': {'r':(16,25),'d':0x2,'c':'CKE high to initialization'},
'reserved2': {'r':(15,14),'d':0,'m':'R','c':'reserved'},
'reg_ddrc_post_cke_x1024': {'r':( 4,13),'d':0x3,'c':'soft reset to CKE high'},
'reg_ddrc_burst_rdwr': {'r':( 0, 3),'d':0x4,'c':'2 - burst length 4, 4 - b.l. 8, 0x10 - b.l. 16, others reserved'}}},
'dram_disable_dq': {'OFFS': 0x038,'DFLT':0x00000000,'RW':'M','FIELDS':{
'reserved1': {'r':( 9,12),'d':0,'c':'reserved'},
'reserved2': {'r':( 8, 8),'d':0,'c':'reserved'},
'reserved3': {'r':( 7, 7),'d':0,'c':'reserved'},
'reserved4': {'r':( 6, 6),'d':0,'c':'reserved'},
'reserved5': {'r':( 2, 5),'d':0,'m':'R','c':''},
'reg_ddrc_dis_dq': {'r':( 1, 1),'d':0,'c':'Dynamic, debug. Stop dequeue transactions, no DDR operations'},
'reg_ddrc_force_low_pri_n': {'r':( 0, 0),'d':0,'c':'0 - read transactions low priority (1 - high read priority if enabled in AXI pri read)'}}},
'dram_addr_map_bank': {'OFFS': 0x03C,'DFLT':0x00000F77,'RW':'RW','FIELDS':{
'reg_ddrc_addrmap_col_b6': {'r':(16,19),'d':0,'c':'Selects address bits for column address bit 7, half bus width - column address bits 8, int. base=9'},
'reg_ddrc_addrmap_col_b5': {'r':(12,15),'d':0,'c':'Selects address bits for column address bit 6, half bus width - column address bits 7, int. base=8'},
'reg_ddrc_addrmap_ba nk_b2': {'r':( 8,11),'d':0xf,'c':'Selects AXI address bit for bank2. Valid 0..15. Int. base=7. If 15, bank2 is set to 0'},
'reg_ddrc_addrmap_ba nk_b2': {'r':( 4, 7),'d':0x7,'c':'Selects AXI address bit for bank1. Valid 0..14. Int. base=6.'},
'reg_ddrc_addrmap_ba nk_b2': {'r':( 0, 3),'d':0x7,'c':'Selects AXI address bit for bank0. Valid 0..14. Int. base=5.'}}},
'dram_addr_map_col': {'OFFS': 0x040,'DFLT':0xFFF00000,'RW':'RW','FIELDS':{
'reg_ddrc_addrmap_col_b11': {'r':(28,31),'d':0xF,'c':'Selects address bits for col. addr. bit 13 (LP - 12), Valid 0..7 and 15, half width - unused (LP-13), int. base=14'},
'reg_ddrc_addrmap_col_b10': {'r':(24,27),'d':0xF,'c':'Selects address bits for col. addr. bit 12 (LP - 11), Valid 0..7 and 15, half width - 13 (LP-12), int. base=13'},
'reg_ddrc_addrmap_col_b9': {'r':(20,23),'d':0xF,'c':'Selects address bits for col. addr. bit 11 (LP - 10), Valid 0..7 and 15, half width - 12 (LP-11), int. base=12'},
'reg_ddrc_addrmap_col_b8': {'r':(16,19),'d':0,'c':'Selects address bits for col. addr. bit 9, Valid 0..7 and 15, half width - 11 (LP-10), int. base=11'},
'reg_ddrc_addrmap_col_b7': {'r':(12,15),'d':0,'c':'Selects address bits for col. addr. bit 8, Valid 0..7 and 15, half width - 9, int. base=10'},
'reg_ddrc_addrmap_col_b4': {'r':( 8,11),'d':0,'c':'Selects address bits for col. addr. bit 5, Valid 0..7, half width - bit 6, int. base=7'},
'reg_ddrc_addrmap_col_b3': {'r':( 4, 7),'d':0,'c':'Selects address bits for col. addr. bit 4, Valid 0..7, half width - bit 5, int. base=6'},
'reg_ddrc_addrmap_col_b2': {'r':( 0, 3),'d':0,'c':'Selects address bits for col. addr. bit 3, Valid 0..7, half width - bit 4, int. base=5'}}},
'dram_addr_map_row': {'OFFS': 0x044,'DFLT':0x0FF55555,'RW':'RW','FIELDS':{
'reg_ddrc_addrmap_row_b15': {'r':(24,27),'d':0xF,'c':'Selects address bits for row. addr. bit 15, Valid 0..5 and 15, int. base=24 if 15 - address bit 15 is set to 0'},
'reg_ddrc_addrmap_row_b14': {'r':(20,23),'d':0xF,'c':'Selects address bits for row. addr. bit 14, Valid 0..6 and 15, int. base=23 if 15 - address bit 14 is set to 0'},
'reg_ddrc_addrmap_row_b13': {'r':(16,19),'d':0x5,'c':'Selects address bits for row. addr. bit 13, Valid 0..7 and 15, int. base=22 if 15 - address bit 13 is set to 0'},
'reg_ddrc_addrmap_row_b12': {'r':(12,15),'d':0x5,'c':'Selects address bits for row. addr. bit 12, Valid 0..8 and 15, int. base=21 if 15 - address bit 12 is set to 0'},
'reg_ddrc_addrmap_row_b2_11': {'r':( 8,11),'d':0x5,'c':'Selects address bits for row. addr. bits 2 to 11, Valid 0..11, int. base=11 (for a2) to 20 (for a 11)'},
'reg_ddrc_addrmap_row_b1': {'r':( 4, 7),'d':0x5,'c':'Selects address bits for row. addr. bit 1, Valid 0..11, int. base=10'},
'reg_ddrc_addrmap_row_b0': {'r':( 0, 3),'d':0x5,'c':'Selects address bits for row. addr. bit 0, Valid 0..11, int. base=9'}}},
'dram_odt_reg': {'OFFS': 0x048,'DFLT':0x00000249,'RW':'RW','FIELDS':{
'reserved1': {'r':(29,27),'d':0,'c':'reserved'},
'reserved2': {'r':(24,26),'d':0,'c':'reserved'},
'reserved3': {'r':(21,23),'d':0,'c':'reserved'},
'reserved4': {'r':(18,20),'d':0,'c':'reserved'},
'reg_phy_idle_local_odt': {'r':(16,17),'d':0,'c':'2-bit drive ODT when OE is inactive and no read (power save)'},
'reg_phy_wr_local_odt': {'r':(14,15),'d':0,'c':'ODT strength during write leveling'},
'reg_phy_rd_local_odt': {'r':(12,13),'d':0,'c':'ODT strength during read'},
'reserved5': {'r':( 9,11),'d':0x1,'c':'reserved'},
'reserved6': {'r':( 6, 8),'d':0x1,'c':'reserved'},
'reserved7': {'r':( 3, 5),'d':0x1,'c':'reserved'},
'reserved8': {'r':( 0, 2),'d':0x1,'c':'reserved'}}},
'phy_dbg_reg': {'OFFS': 0x04C,'DFLT':0x00000000,'RW':'R','FIELDS':{
'phy_reg_bc_fifo_re3': {'r':(19,19),'d':0,'m':'R','c':'Debug read capture FIFO read enable for data slice 3'},
'phy_reg_bc_fifo_we3': {'r':(18,18),'d':0,'m':'R','c':'Debug read capture FIFO write enable for data slice 3'},
'phy_reg_bc_dqs_oe3': {'r':(17,17),'d':0,'m':'R','c':'Debug DQS output enable for data slice 3'},
'phy_reg_bc_dq_oe3': {'r':(16,16),'d':0,'m':'R','c':'Debug DQ output enable for data slice 3'},
'phy_reg_bc_fifo_re2': {'r':(15,15),'d':0,'m':'R','c':'Debug read capture FIFO read enable for data slice 2'},
'phy_reg_bc_fifo_we2': {'r':(14,14),'d':0,'m':'R','c':'Debug read capture FIFO write enable for data slice 2'},
'phy_reg_bc_dqs_oe2': {'r':(13,13),'d':0,'m':'R','c':'Debug DQS output enable for data slice 2'},
'phy_reg_bc_dq_oe2': {'r':(12,12),'d':0,'m':'R','c':'Debug DQ output enable for data slice 2'},
'phy_reg_bc_fifo_re1': {'r':(11,11),'d':0,'m':'R','c':'Debug read capture FIFO read enable for data slice 1'},
'phy_reg_bc_fifo_we1': {'r':(10,10),'d':0,'m':'R','c':'Debug read capture FIFO write enable for data slice 1'},
'phy_reg_bc_dqs_oe1': {'r':( 9, 9),'d':0,'m':'R','c':'Debug DQS output enable for data slice 1'},
'phy_reg_bc_dq_oe1': {'r':( 8, 8),'d':0,'m':'R','c':'Debug DQ output enable for data slice 1'},
'phy_reg_bc_fifo_re0': {'r':( 9, 7),'d':0,'m':'R','c':'Debug read capture FIFO read enable for data slice 0'},
'phy_reg_bc_fifo_we0': {'r':( 6, 6),'d':0,'m':'R','c':'Debug read capture FIFO write enable for data slice 0'},
'phy_reg_bc_dqs_oe0': {'r':( 5, 5),'d':0,'m':'R','c':'Debug DQS output enable for data slice 0'},
'phy_reg_bc_dq_oe0': {'r':( 4, 4),'d':0,'m':'R','c':'Debug DQ output enable for data slice 0'},
'phy_reg_rdc_fifo_rst_err_cnt': {'r':( 0, 3),'d':0,'m':'R','c':'FIFO read pointers mismatch counter'}}},
'phy_cmd_timeout_rddata_cpt':{'OFFS': 0x050,'DFLT':0x00010200,'RW':'M','FIELDS':{
'reg_phy_wrlvl_num_of_dq0': {'r':(28,31),'d':0,'c':'Number of sample for ratio increment during write leveling (recommended 8)'},
'reg_phy_gatelvl_num_of_dq0': {'r':(24,27),'d':0,'c':'Number of sample for ratio increment during gate training (recommended 8)'},
'reserved1': {'r':(20,23),'d':0,'m':'R','c':'reserved'},
'reg_phy_clk_stall_level': {'r':(19,19),'d':0,'c':'1- Stall clock for DLL aging control'},
'reg_phy_dis_phy_ctrl_rstn': {'r':(18,18),'d':0,'c':'1 - disable reset to PHY control'},
'reg_phy_rdc_fifo_rst_err_cnt_clr': {'r':(17,17),'d':0,'c':'1 - reset phy_dbg_reg.phy_reg_rdc_fifo_rst_err_cnt'},
'reg_phy_use_fixed_re': {'r':(16,16),'d':0x1,'c':'... (should be high during training/leveling'},
'reg_phy_rdc_fifo_rst_disable': {'r':(15,15),'d':0,'c':'1 - disable counting phy_dbg_reg.phy_reg_rdc_fifo_rst_err_cnt'},
'reserved2': {'r':(12,14),'d':0,'m':'R','c':'reserved'},
'reg_phy_rdc_we_to_re_delay': {'r':( 8,11),'d':0x2,'c':'use for fixed delay, when reg_phy_use_fixed_re==1'},
'reg_phy_wr_cmd_to_data': {'r':( 4, 7),'d':0,'c':'Not used in DFI PHY'},
'reg_phy_rd_cmd_to_data': {'r':( 0, 3),'d':0,'c':'Not used in DFI PHY'}}},
'mode_sts_reg': {'OFFS': 0x054,'DFLT':0x00000000,'RW':'R','FIELDS':{
'ddrc_reg_dbg_hpr_q_depth': {'r':(16,20),'d':0,'m':'R','c':'number in high priority read CAM'},
'ddrc_reg_dbg_lpr_q_depth': {'r':(10,15),'d':0,'m':'R','c':'number in low priority read CAM'},
'ddrc_reg_dbg_wr_q_depth': {'r':( 4, 9),'d':0,'m':'R','c':'number in write CAM '},
'ddrc_reg_dbg_stall': {'r':( 3, 3),'d':0,'m':'R','c':'1 - commands accepted by controller'},
'ddrc_reg_operating_mode': {'r':( 0, 2),'d':0,'m':'R','c':'DDRC init, 1 - normal, 2 - power down, 3 - self refresh, >=4 - deep power down LPDDR2'}}},
'dll_calib': {'OFFS': 0x058,'DFLT':0x00000101,'RW':'RW','FIELDS':{
'reg_ddrc_dis_dll_calib': {'r':(16,16),'d':0,'c':'Dynamic: 1- disable DLL_calib, 0 - issue DLL_calib periodically'},
'reserved1': {'r':( 8,15),'d':0,'c':'reserved'},
'reserved2': {'r':( 0, 7),'d':0,'c':'reserved'}}},
'odt_delay_hold': {'OFFS': 0x05C,'DFLT':0x00000023,'RW':'RW','FIELDS':{
'reg_ddrc_wr_odt_hold': {'r':(12,15),'d':0,'c':'(Cycles to hold ODT for write command-1). For burst4 - 2, for burst8 - 4'},
'reg_ddrc_rd_odt_hold': {'r':( 8,11),'d':0,'c':'unused'},
'reg_ddrc_wr_odt_delay': {'r':( 4, 7),'d':0x2,'c':'From issuing write to setting ODT for write. Recommended for DDR3 - 0, for DDR2 (WL-5)'},
'reg_ddrc_rd_odt_delay': {'r':( 0, 3),'d':0x3,'c':'unused'}}},
'ctrl_reg1': {'OFFS': 0x060,'DFLT':0x0000003E,'RW':'M','FIELDS':{
'reg_ddrc_selfref_en': {'r':(12,12),'d':0,'c':'Dynamic - 1 - go to Self Refresh when transaction store is empty'},
'reserved1': {'r':(11,11),'d':0,'m':'R','c':'reserved'},
'reg_ddrc_dis_collision_page_opt': {'r':(10,10),'d':0,'c':'Disable autoprecharge for collisions (write+write or read+write to the same address) when reg_ddrc_dis_wc==1'},
'reg_ddrc_dis_wc': {'r':( 9, 9),'d':0,'c':'1 - disable write combine, 0 - enable'},
'reg_ddrc_refresh_update_level': {'r':( 8, 8),'d':0,'c':'Dynamic: toggle to indicate refressh register(s) update'},
'reg_ddrc_auto_pre_en': {'r':( 7, 7),'d':0,'c':'1 - most R/W will be with autoprecharge'},
'reg_ddrc_lpr_num_entries': {'r':( 1, 6),'d':0x1F,'c':'(bit 6 ignored) (Size of low priority transaction store+1). HPR - 32 - this value'},
'reg_ddrc_pageclose': {'r':( 0, 0),'d':0,'c':'1 - close bank if no transactions in the store for it, 0 - keep open until not needed by other'}}},
'ctrl_reg2': {'OFFS': 0x064,'DFLT':0x00020000,'RW':'M','FIELDS':{
'reg_arb_go2critical_en': {'r':(17,17),'d':0x1,'c':'0 - ignore "urgent" from AXI master, 1 - grant'},
'reserved1': {'r':(13,16),'d':0,'m':'R','c':'reserved'},
'reg_ddrc_go2critical_hysteresis': {'r':( 5,12),'d':0,'c':'Latency of moving to critical state'},
'reserved2': {'r':( 0, 4),'d':0,'m':'R','c':'reserved'}}},
'ctrl_reg3': {'OFFS': 0x068,'DFLT':0x00284027,'RW':'RW','FIELDS':{ # in code it was called 'rd_dll_force' TODO: Update hardware.h
'reg_ddrc_dfi_t_wlmrd': {'r':(16,25),'d':0x28,'c':'DDR3 only: tMLRD from DRAM specs'},
'reg_ddrc_rdlvl_rr': {'r':( 8,15),'d':0x40,'c':'DDR3 read leveling read-to-read delay'},
'reg_ddrc_wrlvl_ww': {'r':( 0, 7),'d':0x27,'c':'DDR3 and LPDDR2 - write leveling write-to-write delay'}}},
'ctrl_reg4': {'OFFS': 0x06C,'DFLT':0x00001610,'RW':'RW','FIELDS':{ # in code it was called 'rd_dll_force0'
'dfi_t_ctrlupd_interval_max_x1024': {'r':( 8,15),'d':0x16,'c':'maximal time between DFI update requests in 1024 clocks'},
'dfi_t_ctrlupd_interval_min_x1024': {'r':( 0, 7),'d':0x10,'c':'minimal time between DFI update requests in 1024 clocks'}}},
'rd_dll_force1': {'OFFS': 0x070},
'wr_ratio_reg': {'OFFS': 0x074},
'ctrl_reg5': {'OFFS': 0x078,'DFLT':0x00455111,'RW':'M','FIELDS':{# in code it was called 'rd_ratio_reg'
'reserved1': {'r':(26,31),'d':0,'m':'R','c':'reserved'},
'reg_ddrc_t_ckesr': {'r':(20,25),'d':0x4,'c':'Min CKE low for self refresh, recomm.: DDR3:tCKE+1,DDR2:tCKE,LPDDR2:tCKESR'},
'reg_ddrc_t_cksrx': {'r':(16,19),'d':0x5,'c':'CK valid before self refresh exit, recomm. DDR3:tCKSRX,DDR2:1,LPDDR2:2'},
'reg_ddrc_t_cksre': {'r':(12,15),'d':0x5,'c':'CK valid after self refresh entry, recomm. DDR3:tCKSRE,DDR2:1,LPDDR2:2'},
'reg_ddrc_dfi_t_dram_clk_enable': {'r':( 8,11),'d':0x1,'c':'deassert dfi_dram_clock disable to PHY clock enable in DFI clock cycles'},
'reg_ddrc_dfi_t_dram_clk_disable': {'r':( 4, 7),'d':0x1,'c':'assert dfi_dram_clock disable to PHY clock disable in DFI clock cycles'},
'reg_ddrc_dfi_t_ctrl_delay': {'r':( 0, 3),'d':0x1,'c':'assert/deassert DFI control signals to PHY-DRAM control signals'}}},
'ctrl_reg6': {'OFFS': 0x07C,'DFLT':0x00032222,'RW':'M','FIELDS':{# in code it was called 'mstr_dll_status1_reg'
'reserved1': {'r':(20,31),'d':0,'m':'R','c':'reserved'},
'reg_ddrc_t_ckcsx': {'r':(16,19),'d':0x3,'c':'Clock stable before exiting clock stop. Recommended for LPDDR2: tXP+2'},
'reg_ddrc_t_ckdpdx': {'r':(12,15),'d':0x2,'c':'Clock stable before Deep Power Down exit. Recommended for LPDDR2: 2'},
'reg_ddrc_t_ckdpde': {'r':( 8,11),'d':0x2,'c':'Maintain clock after Deep Power Down entry. Recommended for LPDDR2: 2'},
'reg_ddrc_t_ckpdx': {'r':( 4, 7),'d':0x2,'c':'Clock stable before Power Down exit. Recommended for LPDDR2: 2'},
'reg_ddrc_t_ckpde': {'r':( 0, 3),'d':0x2,'c':'Maintain clock after Power Down entry. Recommended for LPDDR2: 2'}}},
'ddr_rd_slave_status0_reg':{'OFFS': 0x080},
'ddr_rd_slave_status1_reg':{'OFFS': 0x084},
'of_status0_reg': {'OFFS': 0x088},
'of_status1_reg': {'OFFS': 0x08C},
'of_status2_reg': {'OFFS': 0x090},
'of_status3_reg': {'OFFS': 0x094},
'mstr_dll_status2_reg': {'OFFS': 0x098},
'wr_dll_force1_reg': {'OFFS': 0x09C},
'refresh_timer01_reg': {'OFFS': 0x0A0,'DFLT':0x00008000,'RW':'RW','FIELDS':{
'reserved1': {'r':(12,23),'d':0x8,'c':'reserved'},
'reserved2': {'r':( 0,11),'d':0,'c':'reserved'}}},
't_zq_reg': {'OFFS': 0x0A4,'DFLT':0x10300802,'RW':'RW','FIELDS':{
'reg_ddrc_t_zq_short_nop': {'r':(22,31),'d':0x40,'c':'DDR3 and LPDDR2 only: number of NOP after ZQCS (ZQ calibration short)'},
'reg_ddrc_t_zq_long_nop': {'r':(12,21),'d':0x300,'c':'DDR3 and LPDDR2 only: number of NOP after ZQCL (ZQ calibration long)'},
'reg_ddrc_t_mod': {'r':( 2,11),'d':0x200,'c':'Mode register set command update delay >=0x80'},
'reg_ddrc_ddr3': {'r':( 1, 1),'d':0x1,'c':'0 - DDR2, 1 - DDR3'},
'reg_ddrc_dis_auto_zq ': {'r':( 0, 0),'d':0,'c':'DDR3 and LPDDR2 only: 1 - disable auto generation of ZQCS, 0 - enable'}}},
't_zq_short_interval_reg': {'OFFS': 0x0A8,'DFLT':0x0020003A,'RW':'RW','FIELDS':{
'dram_rstn_x1024': {'r':(20,27),'d':0x2,'c':'DDR3 only: Number of cycles to assert reset during init sequence (in 1024 cycles)'},
't_zq_short_interval_x1024': {'r':( 0,19),'d':0x3a,'c':'DDR3 and LPDDR2 only: AVerage interval between automatic ZQCS in 1024 clock cycles'}}},
#
' deep_pwrdwn_reg':{'OFFS': 0x0AC,'DFLT':0x00000000,'RW':'RW','FIELDS':{ # in code it was called 'status_data_sl_dll_01_reg'
'deeppowerdown_to_x1024': {'r':( 1, 8),'d':0,'c':'LPDDR2 only: minimal deep power down time in 1024 clk (specs - 500usec)'},
'deeppowerdown_en': {'r':( 0, 0),'d':0,'c':'LPDDR2 only: 0 - normal, 1 - go to deep power down when transaction store is empty'}}},
'reg_2c': {'OFFS': 0x0B0,'DFLT':0x00000000,'RW':'M','FIELDS':{ # in code it was called 'status_data_sl_dll_23_reg'
'reg_ddrc_dfi_rd_data_eye_train': {'r':(28,28),'d':0,'c':'DDR3 and LPDDR2 only: 1 - read data eye training (part of init sequence)'},
'reg_ddrc_dfi_rd_dqs_gate_level': {'r':(27,27),'d':0,'c':'1 - Read DQS gate leveling mode (DDR3 DFI only)'},
'reg_ddrc_dfi_wr_level_en': {'r':(26,26),'d':0,'c':'1 - Write leveling mode (DDR3 DFI only)'},
'ddrc_reg_trdlvl_max_error': {'r':(25,25),'d':0,'m':'R','c':'DDR3 and LPDDR2 only: leveling/gate training timeout (clear on write)'},
'ddrc_reg_twrlvl_max_error': {'r':(24,24),'d':0,'m':'R','c':'DDR3 only: write leveling timeout (clear on write)'},
'dfi_rdlvl_max_x1024': {'r':(12,23),'d':0,'c':'Read leveling maximal time in 1024 clk. Typical value 0xFFF'},
'dfi_wrlvl_max_x1024': {'r':( 0,11),'d':0,'c':'Write leveling maximal time in 1024 clk. Typical value 0xFFF'}}},
'reg_2d': {'OFFS': 0x0B4,'DFLT':0x00000200,'RW':'RW','FIELDS':{ # in code it was called 'status_dqs_sl_dll_01_reg'
'reserved1': {'r':(10,10),'d':0,'c':'reserved'},
'reg_ddrc_skip_ocd': {'r':( 9, 9),'d':0x1,'c':'should be 1, 0 is not supported. 1 - skip OCD adjustment step during DDR2 init, use OCD_Default and OCD_exit'},
'reserved2': {'r':( 0, 8),'d':0,'c':'reserved'}}},
'dfi_timimg': {'OFFS': 0x0B8,'DFLT':0x00200067,'RW':'RW','FIELDS':{ # in code it was called 'status_dqs_sl_dll_23_reg'
'reg_ddrc_dfi_t_ctrlup_max': {'r':(15,24),'d':0x40,'c':'Maximal number of clocks ddrc_dfi_ctrlupd_req can assert'},
'reg_ddrc_dfi_t_ctrlup_min': {'r':( 5,14),'d':0x3,'c':'Minimal number of clocks ddrc_dfi_ctrlupd_req must be asserted'},
'reg_ddrc_dfi_t_rddata_en': {'r':( 0, 4),'d':0x7,'c':'LPDDR2 - RL, DDR2 and DDR3 - RL-1'}}},
# u32 reserved1[0x2];
'che_ecc_control_reg_offset':{'OFFS': 0x0C4,'DFLT':0x0,'RW':'RW', 'FIELDS':{
'clear_correctable_dram_ecc_error': {'r':(1, 1),'d':0,'c':'1 - clear correctable log (valid+counters)'},
'clear_uncorrectable_dram_ecc_error':{'r':(0, 0),'d':0,'c':'1 - clear uncorrectable log (valid+counters)'}}},
'che_corr_ecc_log_reg_offset':{'OFFS': 0x0C8,'DFLT':0x0,'RW':'M', 'FIELDS':{
'ecc_corrected_bit_num': {'r':( 1, 7),'d':0,'m':'CW','c':'encoded error bits for up to 72-bit data'},
'corr_ecc_log_valid': {'r':( 0, 0),'d':0,'m':'R','c':'set to 1 when correctable error is captured'}}},
'che_corr_ecc_addr_reg_offset':{'OFFS': 0x0CC,'DFLT':0x0,'RW':'R', 'FIELDS':{
'corr_ecc_log_bank': {'r':(28,30),'d':0,'m':'R','c':'bank [0:2]'},
'corr_ecc_log_row': {'r':(12,27),'d':0,'m':'R','c':'row [0:15]'},
'corr_ecc_log_col': {'r':( 0,11),'d':0,'m':'R','c':'col [0:11]'}}},
'che_corr_ecc_data_31_0_reg_offset':{'OFFS': 0x0D0,'DFLT':0x0,'RW':'R', 'FIELDS':{
'corr_ecc_dat_31_0': {'r':( 0,31),'d':0,'m':'R','c':'bits[0:31] of the word with correctable ECC error. actually only 0:7 have valid data, 8:31 are 0'}}},
'che_corr_ecc_data_63_32_reg_offset':{'OFFS': 0x0D4,'DFLT':0x0,'RW':'R', 'FIELDS':{
'corr_ecc_dat_63_32': {'r':( 0,31),'d':0,'m':'R','c':'bits[32:63] of the word with correctable ECC error. actually all are 0'}}},
'che_corr_ecc_data_71_64_reg_offset':{'OFFS': 0x0D8,'DFLT':0x0,'RW':'R', 'FIELDS':{
'corr_ecc_dat_71_64': {'r':( 0,31),'d':0,'m':'R','c':'bits[64:71] of the word with correctable ECC error. only lower 5 bits have data, the rest are 0'}}},
'che_uncorr_ecc_log_reg_offset':{'OFFS': 0x0DC,'DFLT':0x0,'RW':'R', 'FIELDS':{
'uncorr_ecc_log_valid': {'r':( 0, 0),'d':0,'m':'R','c':'Set to 1 when uncorrectable error is capture (no more captured until cleared), cleared by che_ecc_control_reg_offset'}}},
'che_uncorr_ecc_addr_reg_offset':{'OFFS': 0x0E0,'DFLT':0x0,'RW':'R', 'FIELDS':{
'uncorr_ecc_log_bank': {'r':(28,30),'d':0,'m':'R','c':'bank [0:2]'},
'uncorr_ecc_log_row': {'r':(12,27),'d':0,'m':'R','c':'row [0:15]'},
'uncorr_ecc_log_col': {'r':( 0,11),'d':0,'m':'R','c':'col [0:11]'}}},
'che_uncorr_ecc_data_31_0_reg_offset':{'OFFS': 0x0E4,'DFLT':0x0,'RW':'R', 'FIELDS':{
'uncorr_ecc_dat_31_0': {'r':( 0,31),'d':0,'m':'R','c':'bits[0:31] of the word with uncorrectable ECC error. actually only 0:7 have valid data, 8:31 are 0'}}},
'che_uncorr_ecc_data_63_32_reg_offset':{'OFFS': 0x0E8,'DFLT':0x0,'RW':'R', 'FIELDS':{
'uncorr_ecc_dat_63_32': {'r':( 0,31),'d':0,'m':'R','c':'bits[32:63] of the word with uncorrectable ECC error. actually all are 0'}}},
'che_uncorr_ecc_data_71_64_reg_offset':{'OFFS': 0x0EC,'DFLT':0x0,'RW':'R', 'FIELDS':{
'uncorr_ecc_dat_71_64': {'r':( 0,31),'d':0,'m':'R','c':'bits[64:71] of the word with uncorrectable ECC error. only lower 5 bits have data, the rest are 0'}}},
'che_ecc_stats_reg_offset':{'OFFS': 0x0F0,'DFLT':0x00000000,'RW':'CW', 'FIELDS':{
'stat_num_corr_err': {'r':( 8,15),'d':0,'m':'R','c':'Number of correctable ECC errors since 1 written to bit 1 of che_ecc_control_reg_offset (0xC4)'},
'stat_num_uncorr_err': {'r':( 0, 7),'d':0,'m':'R','c':'Number of uncorrectable ECC errors since 1 written to bit 0 of che_ecc_control_reg_offset (0xC4)'}}},
'ecc_scrub': {'OFFS': 0x0F4,'DFLT':0x00000008,'RW':'RW', 'FIELDS':{
'reg_ddrc_dis_scrub': {'r':( 3, 3),'d':1,'c':'1 - disable ECC scrubs, 0 - enable ECC scrubs'},
'reg_ddrc_ecc_mode': {'r':( 0, 2),'d':0,'c':'DRAM ECC mode. Valid only 0(no ECC) and 0x4 - "SEC/DED over 1-beat'}}},
'che_ecc_corr_bit_mask_31_0_reg_offset':{'OFFS': 0x0F8,'DFLT':0x0,'RW':'R', 'FIELDS':{
'ddrc_reg_ecc_corr_bit_mask': {'r':( 0,31),'d':0,'m':'R','c':'bits[0:31] of the mask of the corrected data (1 - corrected, 0 - uncorrected). Only 0:7 have valid data, 8:31 are 0'}}},
'che_ecc_corr_bit_mask_63_32_reg_offset':{'OFFS': 0x0FC,'DFLT':0x0,'RW':'R', 'FIELDS':{
'ddrc_reg_ecc_corr_bit_mask': {'r':( 0,31),'d':0,'m':'R','c':'bits[32:63] of the mask of the corrected data (1 - corrected, 0 - uncorrected). all bits are 0'}}},
# u32 reserved2[0x14];
'phy_rcvr_enable': {'OFFS': 0x114,'DFLT':0x00000000,'RW':'RW','FIELDS':{
'reg_phy_dif_off': {'r':( 4, 7),'d':0,'c':'"Off" value of the drive of the receiver-enabled pins'},
'reg_phy_dif_on': {'r':( 0, 3),'d':0,'c':'"On" value of the drive of the receiver-enabled pins'}}},
'phy_config0': {'OFFS': 0x118,'DFLT':0x40000001,'RW':'RW','FIELDS':{
'reg_phy_dq_offset': {'r':(24,30),'d':0x40,'c':'Offset value of DQS to DQ during write leveling of data slice 0. Default is 0x40 for 90-degree shift'},
'reserved1': {'r':(15,23),'d':0,'c':'reserved'},
'reserved2': {'r':( 6,14),'d':0,'c':'reserved'},
'reserved3': {'r':( 5, 5),'d':0,'c':'reserved'},
'reserved4': {'r':( 4, 4),'d':0,'c':'reserved'},
'reg_phy_wrlvl_inc_mode': {'r':( 3, 3),'d':0,'c':'reserved'},
'reg_phy_gatelvl_inc_mode': {'r':( 2, 2),'d':0,'c':'reserved'},
'reg_phy_rdlvl_inc_mode': {'r':( 1, 1),'d':0,'c':'reserved'},
'reg_phy_data_slice_in_use': {'r':( 0, 0),'d':1,'c':'Data bus width for read FIFO generation. 0 - read data responses are ignored, 1 - data slice 0 is valid (always 1)'}}},
'phy_config1': {'OFFS': 0x11C,'DFLT':0x40000001,'RW':'RW','FIELDS':{
'reg_phy_dq_offset': {'r':(24,30),'d':0x40,'c':'Offset value of DQS to DQ during write leveling of data slice 1. Default is 0x40 for 90-degree shift'},
'reserved1': {'r':(15,23),'d':0,'c':'reserved'},
'reserved2': {'r':( 6,14),'d':0,'c':'reserved'},
'reserved3': {'r':( 5, 5),'d':0,'c':'reserved'},
'reserved4': {'r':( 4, 4),'d':0,'c':'reserved'},
'reg_phy_wrlvl_inc_mode': {'r':( 3, 3),'d':0,'c':'reserved'},
'reg_phy_gatelvl_inc_mode': {'r':( 2, 2),'d':0,'c':'reserved'},
'reg_phy_rdlvl_inc_mode': {'r':( 1, 1),'d':0,'c':'reserved'},
'reg_phy_data_slice_in_use': {'r':( 0, 0),'d':1,'c':'Data bus width for read FIFO generation. 0 - read data responses are ignored, 1 - data slice 1 is valid'}}},
'phy_config2': {'OFFS': 0x120,'DFLT':0x40000001,'RW':'RW','FIELDS':{
'reg_phy_dq_offset': {'r':(24,30),'d':0x40,'c':'Offset value of DQS to DQ during write leveling of data slice 2. Default is 0x40 for 90-degree shift'},
'reserved1': {'r':(15,23),'d':0,'c':'reserved'},
'reserved2': {'r':( 6,14),'d':0,'c':'reserved'},
'reserved3': {'r':( 5, 5),'d':0,'c':'reserved'},
'reserved4': {'r':( 4, 4),'d':0,'c':'reserved'},
'reg_phy_wrlvl_inc_mode': {'r':( 3, 3),'d':0,'c':'reserved'},
'reg_phy_gatelvl_inc_mode': {'r':( 2, 2),'d':0,'c':'reserved'},
'reg_phy_rdlvl_inc_mode': {'r':( 1, 1),'d':0,'c':'reserved'},
'reg_phy_data_slice_in_use': {'r':( 0, 0),'d':1,'c':'Data bus width for read FIFO generation. 0 - read data responses are ignored, 1 - data slice 2 is valid'}}},
'phy_config3': {'OFFS': 0x124,'DFLT':0x40000001,'RW':'RW','FIELDS':{
'reg_phy_dq_offset': {'r':(24,30),'d':0x40,'c':'Offset value of DQS to DQ during write leveling of data slice 3. Default is 0x40 for 90-degree shift'},
'reserved1': {'r':(15,23),'d':0,'c':'reserved'},
'reserved2': {'r':( 6,14),'d':0,'c':'reserved'},
'reserved3': {'r':( 5, 5),'d':0,'c':'reserved'},
'reserved4': {'r':( 4, 4),'d':0,'c':'reserved'},
'reg_phy_wrlvl_inc_mode': {'r':( 3, 3),'d':0,'c':'reserved'},
'reg_phy_gatelvl_inc_mode': {'r':( 2, 2),'d':0,'c':'reserved'},
'reg_phy_rdlvl_inc_mode': {'r':( 1, 1),'d':0,'c':'reserved'},
'reg_phy_data_slice_in_use': {'r':( 0, 0),'d':1,'c':'Data bus width for read FIFO generation. 0 - read data responses are ignored, 1 - data slice 3 is valid'}}},
# u32 reserved3[1]; /* 0x128*/,
'phy_init_ratio0': {'OFFS': 0x12C,'DFLT':0x00000000,'RW':'RW','FIELDS':{
'reg_phy_gatelvl_init_ratio': {'r':(10,19),'d':0,'c':'User-programmable init ratio used by Gate Leveling FSM, data slice 0'},
'reg_phy_wrlvl_init_ratio': {'r':( 0, 9),'d':0,'c':'User-programmable init ratio used by Write Leveling FSM, data slice 0'}}},
'phy_init_ratio1': {'OFFS': 0x130,'DFLT':0x00000000,'RW':'RW','FIELDS':{
'reg_phy_gatelvl_init_ratio': {'r':(10,19),'d':0,'c':'User-programmable init ratio used by Gate Leveling FSM, data slice 1'},
'reg_phy_wrlvl_init_ratio': {'r':( 0, 9),'d':0,'c':'User-programmable init ratio used by Write Leveling FSM, data slice 1'}}},
'phy_init_ratio2': {'OFFS': 0x134,'DFLT':0x00000000,'RW':'RW','FIELDS':{
'reg_phy_gatelvl_init_ratio': {'r':(10,19),'d':0,'c':'User-programmable init ratio used by Gate Leveling FSM, data slice 2'},
'reg_phy_wrlvl_init_ratio': {'r':( 0, 9),'d':0,'c':'User-programmable init ratio used by Write Leveling FSM, data slice 2'}}},
'phy_init_ratio3': {'OFFS': 0x138,'DFLT':0x00000000,'RW':'RW','FIELDS':{
'reg_phy_gatelvl_init_ratio': {'r':(10,19),'d':0,'c':'User-programmable init ratio used by Gate Leveling FSM, data slice 3'},
'reg_phy_wrlvl_init_ratio': {'r':( 0, 9),'d':0,'c':'User-programmable init ratio used by Write Leveling FSM, data slice 3'}}},
#
'phy_rd_dqs_cfg0': {'OFFS': 0x140,'DFLT':0x00000040,'RW':'RW','FIELDS':{
'reg_phy_rd_dqs_slave_delay': {'r':(11,19),'d':0,'c':'If reg_phy_rd_dqs_slave_force is 1, use this tap/delay value for read DQS slave DLL, data slice 0'},
'reg_phy_rd_dqs_slave_force': {'r':(10,10),'d':0,'c':'0 - use reg_phy_rd_dqs_slave_ratio for the read DQS slave DLL, 1 - use provided in reg_phy_rd_dqs_slave_delay, data slice 0'},
'reg_phy_rd_dqs_slave_ratio': {'r':( 0, 9),'d':0x40,'c':'Fraction of the clock cycle (256 = full period) for the read DQS slave DLL, data slice 0'}}},
'phy_rd_dqs_cfg1': {'OFFS': 0x144,'DFLT':0x00000040,'RW':'RW','FIELDS':{
'reg_phy_rd_dqs_slave_delay': {'r':(11,19),'d':0,'c':'If reg_phy_rd_dqs_slave_force is 1, use this tap/delay value for read DQS slave DLL, data slice 1'},
'reg_phy_rd_dqs_slave_force': {'r':(10,10),'d':0,'c':'0 - use reg_phy_rd_dqs_slave_ratio for the read DQS slave DLL, 1 - use provided in reg_phy_rd_dqs_slave_delay, data slice 1'},
'reg_phy_rd_dqs_slave_ratio': {'r':( 0, 9),'d':0x40,'c':'Fraction of the clock cycle (256 = full period) for the read DQS slave DLL, data slice 1'}}},
'phy_rd_dqs_cfg2': {'OFFS': 0x148,'DFLT':0x00000040,'RW':'RW','FIELDS':{
'reg_phy_rd_dqs_slave_delay': {'r':(11,19),'d':0,'c':'If reg_phy_rd_dqs_slave_force is 1, use this tap/delay value for read DQS slave DLL, data slice 2'},
'reg_phy_rd_dqs_slave_force': {'r':(10,10),'d':0,'c':'0 - use reg_phy_rd_dqs_slave_ratio for the read DQS slave DLL, 1 - use provided in reg_phy_rd_dqs_slave_delay, data slice 2'},
'reg_phy_rd_dqs_slave_ratio': {'r':( 0, 9),'d':0x40,'c':'Fraction of the clock cycle (256 = full period) for the read DQS slave DLL, data slice 2'}}},
'phy_rd_dqs_cfg3': {'OFFS': 0x14C,'DFLT':0x00000040,'RW':'RW','FIELDS':{
'reg_phy_rd_dqs_slave_delay': {'r':(11,19),'d':0,'c':'If reg_phy_rd_dqs_slave_force is 1, use this tap/delay value for read DQS slave DLL, data slice 3'},
'reg_phy_rd_dqs_slave_force': {'r':(10,10),'d':0,'c':'0 - use reg_phy_rd_dqs_slave_ratio for the read DQS slave DLL, 1 - use provided in reg_phy_rd_dqs_slave_delay, data slice 3'},
'reg_phy_rd_dqs_slave_ratio': {'r':( 0, 9),'d':0x40,'c':'Fraction of the clock cycle (256 = full period) for the read DQS slave DLL, data slice 3'}}},
# u32 reserved4[1]; /* 0x150 */
'phy_wr_dqs_cfg0': {'OFFS': 0x154,'DFLT':0x00000000,'RW':'RW','FIELDS':{
'reg_phy_wr_dqs_slave_delay': {'r':(11,19),'d':0,'c':'If reg_phy_wr_dqs_slave_force is 1, use this tap/delay value for write DQS slave DLL, data slice 0'},
'reg_phy_wr_dqs_slave_force': {'r':(10,10),'d':0,'c':'0 - use reg_phy_wr_dqs_slave_ratio for the write DQS slave DLL, 1 - use provided in reg_phy_wr_dqs_slave_delay, data slice 0'},
'reg_phy_wr_dqs_slave_ratio': {'r':( 0, 9),'d':0,'c':'Fraction of the clock cycle (256 = full period) for the write DQS slave DLL, data slice 0. Program manual training ratio'}}},
'phy_wr_dqs_cfg1': {'OFFS': 0x158,'DFLT':0x00000000,'RW':'RW','FIELDS':{
'reg_phy_wr_dqs_slave_delay': {'r':(11,19),'d':0,'c':'If reg_phy_wr_dqs_slave_force is 1, use this tap/delay value for write DQS slave DLL, data slice 1'},
'reg_phy_wr_dqs_slave_force': {'r':(10,10),'d':0,'c':'0 - use reg_phy_wr_dqs_slave_ratio for the write DQS slave DLL, 1 - use provided in reg_phy_wr_dqs_slave_delay, data slice 1'},
'reg_phy_wr_dqs_slave_ratio': {'r':( 0, 9),'d':0,'c':'Fraction of the clock cycle (256 = full period) for the write DQS slave DLL, data slice 1. Program manual training ratio'}}},
'phy_wr_dqs_cfg2': {'OFFS': 0x15C,'DFLT':0x00000000,'RW':'RW','FIELDS':{
'reg_phy_wr_dqs_slave_delay': {'r':(11,19),'d':0,'c':'If reg_phy_wr_dqs_slave_force is 1, use this tap/delay value for write DQS slave DLL, data slice 2'},
'reg_phy_wr_dqs_slave_force': {'r':(10,10),'d':0,'c':'0 - use reg_phy_wr_dqs_slave_ratio for the write DQS slave DLL, 1 - use provided in reg_phy_wr_dqs_slave_delay, data slice 2'},
'reg_phy_wr_dqs_slave_ratio': {'r':( 0, 9),'d':0,'c':'Fraction of the clock cycle (256 = full period) for the write DQS slave DLL, data slice 2. Program manual training ratio'}}},
'phy_wr_dqs_cfg3': {'OFFS': 0x160,'DFLT':0x00000000,'RW':'RW','FIELDS':{
'reg_phy_wr_dqs_slave_delay': {'r':(11,19),'d':0,'c':'If reg_phy_wr_dqs_slave_force is 1, use this tap/delay value for write DQS slave DLL, data slice 3'},
'reg_phy_wr_dqs_slave_force': {'r':(10,10),'d':0,'c':'0 - use reg_phy_wr_dqs_slave_ratio for the write DQS slave DLL, 1 - use provided in reg_phy_wr_dqs_slave_delay, data slice 3'},
'reg_phy_wr_dqs_slave_ratio': {'r':( 0, 9),'d':0,'c':'Fraction of the clock cycle (256 = full period) for the write DQS slave DLL, data slice 3. Program manual training ratio'}}},
# u32 reserved5[1]; /* 0x164 */
'phy_we_cfg0': {'OFFS': 0x168,'DFLT':0x00000040,'RW':'RW','FIELDS':{
'reg_phy_fifo_we_in_delay': {'r':(12,20),'d':0,'c':'If reg_phy_fifo_we_in_force is 1, use this tap/delay value for fifo_we_0 slave DLL, data slice 0'},
'reg_phy_fifo_we_in_force': {'r':(11,11),'d':0,'c':'0 - use reg_phy_fifo_we_slave_ratio for fifo_we_0 slave DLL, 1 - use provided in reg_phy_fifo_we_in_delay, data slice 0'},
'reg_phy_fifo_we_slave_ratio': {'r':( 0,10),'d':0x40,'c':'Fraction of the clock cycle (256 = full period) for fifo_we_0 slave DLL, data slice 0. Program manual training ratio'}}},
'phy_we_cfg1': {'OFFS': 0x16C,'DFLT':0x00000040,'RW':'RW','FIELDS':{
'reg_phy_fifo_we_in_delay': {'r':(12,20),'d':0,'c':'If reg_phy_fifo_we_in_force is 1, use this tap/delay value for fifo_we_1 slave DLL, data slice 1'},
'reg_phy_fifo_we_in_force': {'r':(11,11),'d':0,'c':'0 - use reg_phy_fifo_we_slave_ratio for fifo_we_1 slave DLL, 1 - use provided in reg_phy_fifo_we_in_delay, data slice 1'},
'reg_phy_fifo_we_slave_ratio': {'r':( 0,10),'d':0x40,'c':'Fraction of the clock cycle (256 = full period) for fifo_we_0 slave DLL, data slice 1. Program manual training ratio'}}},
'phy_we_cfg2': {'OFFS': 0x170,'DFLT':0x00000040,'RW':'RW','FIELDS':{
'reg_phy_fifo_we_in_delay': {'r':(12,20),'d':0,'c':'If reg_phy_fifo_we_in_force is 1, use this tap/delay value for fifo_we_2 slave DLL, data slice 2'},
'reg_phy_fifo_we_in_force': {'r':(11,11),'d':0,'c':'0 - use reg_phy_fifo_we_slave_ratio for fifo_we_2 slave DLL, 1 - use provided in reg_phy_fifo_we_in_delay, data slice 2'},
'reg_phy_fifo_we_slave_ratio': {'r':( 0,10),'d':0x40,'c':'Fraction of the clock cycle (256 = full period) for fifo_we_0 slave DLL, data slice 2. Program manual training ratio'}}},
'phy_we_cfg3': {'OFFS': 0x174,'DFLT':0x00000040,'RW':'RW','FIELDS':{
'reg_phy_fifo_we_in_delay': {'r':(12,20),'d':0,'c':'If reg_phy_fifo_we_in_force is 1, use this tap/delay value for fifo_we_3 slave DLL, data slice 3'},
'reg_phy_fifo_we_in_force': {'r':(11,11),'d':0,'c':'0 - use reg_phy_fifo_we_slave_ratio for fifo_we_3 slave DLL, 1 - use provided in reg_phy_fifo_we_in_delay, data slice 3'},
'reg_phy_fifo_we_slave_ratio': {'r':( 0,10),'d':0x40,'c':'Fraction of the clock cycle (256 = full period) for fifo_we_0 slave DLL, data slice 3. Program manual training ratio'}}},
# u32 reserved6[1]; /* 0x178 */
'wr_data_slv0': {'OFFS': 0x17C,'DFLT':0x00000080,'RW':'RW','FIELDS':{
'reg_phy_wr_data_slave_delay': {'r':(11,19),'d':0,'c':'If reg_phy_wr_dqs_slave_force is 1, use this tap/delay value for write data slave DLL, data slice 0'},
'reg_phy_wr_data_slave_force': {'r':(10,10),'d':0,'c':'0 - use reg_phy_wr_dqs_slave_ratio for the write data slave DLL, 1 - use provided in reg_phy_wr_dqs_slave_delay, data slice 0'},
'reg_phy_wr_data_slave_ratio': {'r':( 0, 9),'d':0,'c':'Fraction of the clock cycle (256 = full period) for the write data slave DLL, data slice 0. Program manual training ratio'}}},
'wr_data_slv1': {'OFFS': 0x180,'DFLT':0x00000080,'RW':'RW','FIELDS':{
'reg_phy_wr_data_slave_delay': {'r':(11,19),'d':0,'c':'If reg_phy_wr_dqs_slave_force is 1, use this tap/delay value for write data slave DLL, data slice 1'},
'reg_phy_wr_data_slave_force': {'r':(10,10),'d':0,'c':'0 - use reg_phy_wr_dqs_slave_ratio for the write data slave DLL, 1 - use provided in reg_phy_wr_dqs_slave_delay, data slice 1'},
'reg_phy_wr_data_slave_ratio': {'r':( 0, 9),'d':0,'c':'Fraction of the clock cycle (256 = full period) for the write data slave DLL, data slice 1. Program manual training ratio'}}},
'wr_data_slv2': {'OFFS': 0x184,'DFLT':0x00000080,'RW':'RW','FIELDS':{
'reg_phy_wr_data_slave_delay': {'r':(11,19),'d':0,'c':'If reg_phy_wr_dqs_slave_force is 1, use this tap/delay value for write data slave DLL, data slice 2'},
'reg_phy_wr_data_slave_force': {'r':(10,10),'d':0,'c':'0 - use reg_phy_wr_dqs_slave_ratio for the write data slave DLL, 1 - use provided in reg_phy_wr_dqs_slave_delay, data slice 2'},
'reg_phy_wr_data_slave_ratio': {'r':( 0, 9),'d':0,'c':'Fraction of the clock cycle (256 = full period) for the write data slave DLL, data slice 2. Program manual training ratio'}}},
'wr_data_slv3': {'OFFS': 0x188,'DFLT':0x00000080,'RW':'RW','FIELDS':{
'reg_phy_wr_data_slave_delay': {'r':(11,19),'d':0,'c':'If reg_phy_wr_dqs_slave_force is 1, use this tap/delay value for write data slave DLL, data slice 3'},
'reg_phy_wr_data_slave_force': {'r':(10,10),'d':0,'c':'0 - use reg_phy_wr_dqs_slave_ratio for the write data slave DLL, 1 - use provided in reg_phy_wr_dqs_slave_delay, data slice 3'},
'reg_phy_wr_data_slave_ratio': {'r':( 0, 9),'d':0,'c':'Fraction of the clock cycle (256 = full period) for the write data slave DLL, data slice 3. Program manual training ratio'}}},
# u32 reserved7[1]; /* 0x18C*/
'reg_64': {'OFFS': 0x190,'DFLT':0x10020000,'RW':'RW','COMMENTS':'Training control 2','FIELDS':{
'reserved1': {'r':(31,31),'d':0, 'c':'reserved'},
'reg_phy_cmd_latency': {'r':(30,30),'d':0, 'c':'1: Delay command to PHY by a FF'},
'reg_phy_lpddr': {'r':(29,29),'d':0, 'c':'0: DDR2/DDR3, 1 - LPDDR2'},
'reserved2': {'r':(28,28),'d':1,' c':'reserved'},
'reg_phy_ctrl_slave_delay': {'r':(21,27),'d':0,' c':'when reg_phy_rd_dqs_slave_force==1 this value (combined with bits 18:19 of reg_65) set address/command slave DLL'},
'reg_phy_ctrl_slave_force': {'r':(20,20),'d':0,' c':'0:use reg_phy_ctrl_slave_ratio for addr/cmd slave DLL, 1 - overwrite with reg_phy_ctrl_slave_delay'},
'reg_phy_ctrl_slave_ratio': {'r':(10,19),'d':0x80,'c':'address/command delay in clock/256'},
'reg_phy_sel_logic': {'r':( 9, 9),'d':0,'c':'Read leveling algorithm select - 0:algorithm 1, 1: algorithm 2'},
'reserved3': {'r':( 8, 8),'d':0,'c':'reserved'},
'reg_phy_invert_clkout': {'r':( 7, 7),'d':0,'c':'1 - invert clock polarity to DRAM'},
'reserved4': {'r':( 5, 6),'d':0,'c':'reserved'},
'reserved5': {'r':( 4, 4),'d':0,'c':'reserved'},
'reserved6': {'r':( 3, 3),'d':0,'c':'reserved'},
'reserved7': {'r':( 2, 2),'d':0,'c':'reserved'},
'reg_phy_bl2': {'r':( 1, 1),'d':0,'c':'reserved'},
'reserved8': {'r':( 0, 0),'d':0,'c':'reserved'}}},
'reg_65': {'OFFS': 0x194,'DFLT':0x00000000,'RW':'RW','COMMENTS':'Training control 3','FIELDS':{
'reg_phy_ctrl_slave_delay': {'r':(18,19),'d':0,'c':'when reg_phy_rd_dqs_slave_force==1 this value (combined with bits 21:27 of reg_64) set address/command slave DLL'},
'reg_phy_dis_calib_rst': {'r':(17,17),'d':0,'c':'disable dll_claib from resetting Read Capture FIFO'},
'reg_phy_use_rd_data_eye_level': {'r':(16,16),'d':0,'c':'Read Data Eye training control - 0 use fixed register data, 1 use data eye leveling data'},
'reg_phy_use_rd_dqs_gate_level': {'r':(15,15),'d':0,'c':'Read DQS Gate training control: 0 - used fixed data, 1 - use calculated data'},
'reg_phy_use_wr_level': {'r':(14,14),'d':0,'c':'Write leveling control: 0 - used programmed register data, 1 - use calculated data'},
'reg_phy_dll_lock_diff': {'r':(10,13),'d':0,'c':'Maximal number of DLL taps before DLL deasserts lock'},
'reg_phy_rd_rl_delay': {'r':( 5, 9),'d':0,'c':''},
'reg_phy_wr_rl_delay': {'r':( 0, 4),'d':0,'c':''}}},
# u32 reserved7[3]; /* 0x198 */
# The fifo_we_slave ratios for each slice(0 through 3) must be interpreted by software in the following way:
# Slice 0: fifo_we_ratio_slice_0[10:0] = {Reg_6A[9],Reg_69[18:9]}
# Slice1: fifo_we_ratio_slice_1[10:0] = {Reg_6B[10:9],Reg_6A[18:10]}
# Slice2: fifo_we_ratio_slice_2[10:0] = {Reg_6C[11:9],Reg_6B[18:11]}
# Slice3: fifo_we_ratio_slice_3[10:0] = {phy_reg_rdlvl_fifowein_ratio_slice3_msb,Reg_6C[18:12]}
'reg_69': {'OFFS': 0x1A4,'DFLT':0x000F0000,'RW':'R','COMMENTS':'Training results for data slice 0','FIELDS':{
'phy_reg_status_fifo_w e_slave_dll_value': {'r':(20,28),'d':0, 'm':'R','c':'Delay of FIFO WE slave DLL'},
'phy_reg_rdlvl_fifowein_ratio': {'r':( 9,19),'d':0x780,'m':'R','c':'Ratio by Read Gate training FSM'},
'reserved': {'r':( 0, 8),'d':0, 'm':'R','c':'reserved'}}},
'reg_6a': {'OFFS': 0x1A8,'DFLT':0x000F0000,'RW':'R','FIELDS':{
'phy_reg_status_fifo_w e_slave_dll_value': {'r':(20,28),'d':0, 'm':'R','c':'Delay of FIFO WE slave DLL'},
'phy_reg_rdlvl_fifowein_ratio': {'r':( 9,19),'d':0x780,'m':'R','c':'Ratio by Read Gate training FSM'},
'reserved': {'r':( 0, 8),'d':0, 'm':'R','c':'reserved'}}},
'reg_6b': {'OFFS': 0x1AC,'DFLT':0x000F0000,'RW':'R','FIELDS':{ #may be different bits/default values
'phy_reg_status_fifo_w e_slave_dll_value': {'r':(20,28),'d':0, 'm':'R','c':'Delay of FIFO WE slave DLL'},
'phy_reg_rdlvl_fifowein_ratio': {'r':( 9,19),'d':0x780,'m':'R','c':'Ratio by Read Gate training FSM'},
'reserved': {'r':( 0, 8),'d':0, 'm':'R','c':'reserved'}}},
# u32 reserved8[1]; /* 0x1AC */
'reg_6c': {'OFFS': 0x1B0,'DFLT':0x000F0000,'RW':'R','COMMENTS':'Training results for data slice 2','FIELDS':{
'phy_reg_status_fifo_we_slave_dll_value':{'r':(20,28),'d':0, 'm':'R','c':'Delay of FIFO WE slave DLL'},
'phy_reg_rdlvl_fifowein_ratio': {'r':( 9,19),'d':0x780,'m':'R','c':'Ratio by Read Gate training FSM'},
'phy_reg_bist_err': {'r':( 0, 8),'d':0, 'm':'R','c':'Mismatch error from BIST checker, 1 bit per data slice'}}},
'reg_6d': {'OFFS': 0x1B4,'DFLT':0x000F0000,'RW':'R','FIELDS':{
'phy_reg_status_fifo_we_slave_dll_value':{'r':(20,28),'d':0, 'm':'R','c':'Delay of FIFO WE slave DLL'},
'phy_reg_rdlvl_fifowein_ratio': {'r':( 9,19),'d':0x780,'m':'R','c':'Ratio by Read Gate training FSM'},
'phy_reg_bist_err': {'r':( 0, 8),'d':0, 'm':'R','c':'Mismatch error from BIST checker, 1 bit per data slice'}}},
'reg_6e': {'OFFS': 0x1B8,'RW':'R','COMMENTS':'Training results for data slice 0','FIELDS':{
'phy_reg_status_fifo_we_slave_dll_value':{'r':(20,29),'d':0, 'm':'R','c':'Ratio generated by Read Data Eye training'},
'phy_reg_rdlvl_fifowein_ratio': {'r':(10,19),'d':0, 'm':'R','c':'Ratio generated by Write Leveling for write data'},
'phy_reg_bist_err': {'r':( 0, 9),'d':0, 'm':'R','c':'Ratio generated by Write Leveling for write DQS'}}},
'reg_6f': {'OFFS': 0x1BC,'RW':'R','COMMENTS':'Training results for data slice 1','FIELDS':{
'phy_reg_status_fifo_we_slave_dll_value':{'r':(20,29),'d':0, 'm':'R','c':'Ratio generated by Read Data Eye training'},
'phy_reg_rdlvl_fifowein_ratio': {'r':(10,19),'d':0, 'm':'R','c':'Ratio generated by Write Leveling for write data'},
'phy_reg_bist_err': {'r':( 0, 9),'d':0, 'm':'R','c':'Ratio generated by Write Leveling for write DQS'}}},
'reg_70': {'OFFS': 0x1C0,'RW':'R','COMMENTS':'Training results for data slice 2','FIELDS':{
'phy_reg_status_fifo_we_slave_dll_value':{'r':(20,29),'d':0, 'm':'R','c':'Ratio generated by Read Data Eye training'},
'phy_reg_rdlvl_fifowein_ratio': {'r':(10,19),'d':0, 'm':'R','c':'Ratio generated by Write Leveling for write data'},
'phy_reg_bist_err': {'r':( 0, 9),'d':0, 'm':'R','c':'Ratio generated by Write Leveling for write DQS'}}},
'reg_71': {'OFFS': 0x1C4,'RW':'R','COMMENTS':'Training results for data slice 3','FIELDS':{
'phy_reg_status_fifo_we_slave_dll_value':{'r':(20,29),'d':0, 'm':'R','c':'Ratio generated by Read Data Eye training'},
'phy_reg_rdlvl_fifowein_ratio': {'r':(10,19),'d':0, 'm':'R','c':'Ratio generated by Write Leveling for write data'},
'phy_reg_bist_err': {'r':( 0, 9),'d':0, 'm':'R','c':'Ratio generated by Write Leveling for write DQS'}}},
# u32 reserved9[1]; /* 0x1C8 */
'phy_dll_sts0': {'OFFS': 0x1CC,'DFLT':0x00000000,'RW':'R','COMMENTS':'Slave DLL results for data slice 0','FIELDS':{
'phy_reg_status_wr_dqs_slave_dll_value': {'r':(18,26),'d':0, 'm':'R','c':'Delay for write DQS slave DLL'},
'phy_reg_status_wr_dat a_slave_dll_value':{'r':( 9,17),'d':0, 'm':'R','c':'Delay for write data slave DLL'},
'phy_reg_status_rd_dqs_slave_dll_value': {'r':( 0, 8),'d':0, 'm':'R','c':'Delay for read data slave DLL'}}},
'phy_dll_sts1': {'OFFS': 0x1D0,'DFLT':0x00000000,'RW':'R','COMMENTS':'Slave DLL results for data slice 1','FIELDS':{
'phy_reg_status_wr_dqs_slave_dll_value': {'r':(18,26),'d':0, 'm':'R','c':'Delay for write DQS slave DLL'},
'phy_reg_status_wr_dat a_slave_dll_value':{'r':( 9,17),'d':0, 'm':'R','c':'Delay for write data slave DLL'},
'phy_reg_status_rd_dqs_slave_dll_value': {'r':( 0, 8),'d':0, 'm':'R','c':'Delay for read data slave DLL'}}},
'phy_dll_sts2': {'OFFS': 0x1D4,'DFLT':0x00000000,'RW':'R','COMMENTS':'Slave DLL results for data slice 2','FIELDS':{
'phy_reg_status_wr_dqs_slave_dll_value': {'r':(18,26),'d':0, 'm':'R','c':'Delay for write DQS slave DLL'},
'phy_reg_status_wr_dat a_slave_dll_value':{'r':( 9,17),'d':0, 'm':'R','c':'Delay for write data slave DLL'},
'phy_reg_status_rd_dqs_slave_dll_value': {'r':( 0, 8),'d':0, 'm':'R','c':'Delay for read data slave DLL'}}},
'phy_dll_sts3': {'OFFS': 0x1D8,'DFLT':0x00000000,'RW':'R','COMMENTS':'Slave DLL results for data slice 3','FIELDS':{
'phy_reg_status_wr_dqs_slave_dll_value': {'r':(18,26),'d':0, 'm':'R','c':'Delay for write DQS slave DLL'},
'phy_reg_status_wr_dat a_slave_dll_value':{'r':( 9,17),'d':0, 'm':'R','c':'Delay for write data slave DLL'},
'phy_reg_status_rd_dqs_slave_dll_value': {'r':( 0, 8),'d':0, 'm':'R','c':'Delay for read data slave DLL'}}},
# u32 reserved10[1]; /* 0x1DC */
'dll_lock_sts': {'OFFS': 0x1E0,'DFLT':0x00000000,'RW':'R','COMMENTS':'DLL lock status','FIELDS':{
'phy_reg_rdlvl_fifowein_ratio_slice3_msb':{'r':(20,23),'d':0, 'm':'R','c':'4 msb-s of slice 3 ratio generated by Read Gate Training FSM'},
'phy_reg_status_dll_slave_value_1': {'r':(11,19),'d':0, 'm':'R','c':'8:2 - coarse, 1:0 - Fine for all slave DLLs (for master DLL 1)'},
'phy_reg_status_dll_slave_value_0': {'r':( 2,10),'d':0, 'm':'R','c':'8:2 - coarse, 1:0 - Fine for all slave DLLs (for master DLL 0)'},
'phy_reg_status_dll_lock_1': {'r':( 1, 1),'d':0, 'm':'R','c':'DLL 1 lock'},
'phy_reg_status_dll_lock_0': {'r':( 0, 0),'d':0, 'm':'R','c':'DLL 0 lock'}}},
'phy_ctrl_sts': {'OFFS': 0x1E4,'RW':'R','COMMENTS':'PHY control status','FIELDS':{
'phy_reg_status_phy_ctrl_of_in_lock_state':{'r':(28,29),'d':0, 'm':'R','c':'Master DLL Output Filter: bit29 - coarse delay line locked, 28 - fine delay line locked'},
'phy_reg_status_phy_ctrl_dll_slave_value': {'r':(20,27),'d':0, 'm':'R','c':'PHY_CTRL Slave DLL: 20:21 - fine, 22:27 - coarse'},
'phy_reg_status_phy_ctrl_dll_lock': {'r':(19,19),'d':0, 'm':'R','c':'PHY control Master DLL locked'},
'phy_reg_status_of_out_delay_value': {'r':(10,18), 'm':'R','c':'Master DLL output filter output: 10:11 - fine, 12:18 - coarse'},
'phy_reg_status_of_in_delay_value': {'r':( 0, 9), 'm':'R','c':'Master DLL output filter input: 10:11 - fine, 12:18 - coarse'}}},
'phy_ctrl_sts_reg2': {'OFFS': 0x1E8,'DFLT':0x00000000,'RW':'R','COMMENTS':'PHY control status 2','FIELDS':{
'phy_reg_status_phy_ctrl_slave_dll_value': {'r':(18,26),'d':0, 'm':'R','c':'Read DQS slave DLL input'},
'reserved': {'r':( 9,17),'d':0, 'm':'R','c':'reserved'},
'phy_reg_status_phy_ctrl_of_in_delay_value':{'r':( 0, 8),'d':0, 'm':'R','c':'Values applied to Master DLL Output filter: 0:1 - fine, 2:8 - coarse'}}},
# u32 reserved11[5]; /* 0x1EC */
'axi_id': {'OFFS': 0x200,'DFLT':0x00153042,'RW':'R','COMMENTS':'Id and Revision','FIELDS':{
'reg_arb_rev_num': {'r':(20,25),'d':0x01, 'm':'R','c':'Revision number'},
'reg_arb_prov_num': {'r':(12,19),'d':0x53, 'm':'R','c':'Provision number'},
'reg_arb_part_num': {'r':( 0,11),'d':0x42, 'm':'R','c':'Part number'}}},
'page_mask': {'OFFS': 0x204,'DFLT':0x00000000,'RW':'RW','COMMENTS':'Arbiter Page Mask','FIELDS':{
'reg_arb_page_addr_mask': {'r':( 0,31),'d':0x0,'c':'Arbiter page hit/miss: 0 - column address, 1 - row/bank address (applies to 64-bit address, not byte addr) '}}},
'axi_priority_wr_port0': {'OFFS': 0x208,'DFLT':0x000803FF,'RW':'M','COMMENTS':'AXI priority control for write port 0','FIELDS':{
'reserved1': {'r':(19,19),'d':0x1, 'c':'reserved'},
'reg_arb_dis_page_match_wr_portn': {'r':(18,18),'d':0, 'c':'Disable page match feature'},
'reg_arb_disable_urgent_wr_portn': {'r':(17,17),'d':0, 'c':'Disable urgent for this Write Port'},
'reg_arb_disable_aging_wr_portn': {'r':(16,16),'d':0, 'c':'Disable aging for this Write Port'},
'reserved2': {'r':(10,15),'d':0, 'm':'R','c':'reserved'},
'reg_arb_pri_wr_portn': {'r':( 0, 9),'d':0x3FF, 'c':'Priority for this write port, >=4, lower value - higher priority'}}},
'axi_priority_wr_port1': {'OFFS': 0x20C,'DFLT':0x000803FF,'RW':'M','COMMENTS':'AXI priority control for write port 1','FIELDS':{
'reserved1': {'r':(19,19),'d':0x1, 'c':'reserved'},
'reg_arb_dis_page_match_wr_portn': {'r':(18,18),'d':0, 'c':'Disable page match feature'},
'reg_arb_disable_urgent_wr_portn': {'r':(17,17),'d':0, 'c':'Disable urgent for this Write Port'},
'reg_arb_disable_aging_wr_portn': {'r':(16,16),'d':0, 'c':'Disable aging for this Write Port'},
'reserved2': {'r':(10,15),'d':0, 'm':'R','c':'reserved'},
'reg_arb_pri_wr_portn': {'r':( 0, 9),'d':0x3FF, 'c':'Priority for this write port, >=4, lower value - higher priority'}}},
'axi_priority_wr_port2': {'OFFS': 0x210,'DFLT':0x000803FF,'RW':'M','COMMENTS':'AXI priority control for write port 2','FIELDS':{
'reserved1': {'r':(19,19),'d':0x1, 'c':'reserved'},
'reg_arb_dis_page_match_wr_portn': {'r':(18,18),'d':0, 'c':'Disable page match feature'},
'reg_arb_disable_urgent_wr_portn': {'r':(17,17),'d':0, 'c':'Disable urgent for this Write Port'},
'reg_arb_disable_aging_wr_portn': {'r':(16,16),'d':0, 'c':'Disable aging for this Write Port'},
'reserved2': {'r':(10,15),'d':0, 'm':'R','c':'reserved'},
'reg_arb_pri_wr_portn': {'r':( 0, 9),'d':0x3FF, 'c':'Priority for this write port, >=4, lower value - higher priority'}}},
'axi_priority_wr_port3': {'OFFS': 0x214,'DFLT':0x000803FF,'RW':'M','COMMENTS':'AXI priority control for write port 3','FIELDS':{
'reserved1': {'r':(19,19),'d':0x1, 'c':'reserved'},
'reg_arb_dis_page_match_wr_portn': {'r':(18,18),'d':0, 'c':'Disable page match feature'},
'reg_arb_disable_urgent_wr_portn': {'r':(17,17),'d':0, 'c':'Disable urgent for this Write Port'},
'reg_arb_disable_aging_wr_portn': {'r':(16,16),'d':0, 'c':'Disable aging for this Write Port'},
'reserved2': {'r':(10,15),'d':0, 'm':'R','c':'reserved'},
'reg_arb_pri_wr_portn': {'r':( 0, 9),'d':0x3FF, 'c':'Priority for this write port, >=4, lower value - higher priority'}}},
'axi_priority_rd_port0': {'OFFS': 0x218,'DFLT':0x000003FF,'RW':'M','COMMENTS':'AXI priority control for read port 0','FIELDS':{
'reg_arb_set_hpr_rd_portn': {'r':(19,19),'d':0x1, 'c':'Enable reads to be HPR for this port'},
'reg_arb_dis_page_match_rd_portn': {'r':(18,18),'d':0, 'c':'Disable page match feature'},
'reg_arb_disable_urgent_rd_portn': {'r':(17,17),'d':0, 'c':'Disable urgent for this Read Port'},
'reg_arb_disable_aging_rd_portn': {'r':(16,16),'d':0, 'c':'Disable aging for this Read Port'},
'reserved1': {'r':(10,15),'d':0, 'm':'R','c':'reserved'},
'reg_arb_pri_rd_portn': {'r':( 0, 9),'d':0x3FF, 'c':'Priority for this Read port, lower value - higher priority'}}},
'axi_priority_rd_port1': {'OFFS': 0x21C,'DFLT':0x000003FF,'RW':'M','COMMENTS':'AXI priority control for read port 1','FIELDS':{
'reg_arb_set_hpr_rd_portn': {'r':(19,19),'d':0x1, 'c':'Enable reads to be HPR for this port'},
'reg_arb_dis_page_match_rd_portn': {'r':(18,18),'d':0, 'c':'Disable page match feature'},
'reg_arb_disable_urgent_rd_portn': {'r':(17,17),'d':0, 'c':'Disable urgent for this Read Port'},
'reg_arb_disable_aging_rd_portn': {'r':(16,16),'d':0, 'c':'Disable aging for this Read Port'},
'reserved1': {'r':(10,15),'d':0, 'm':'R','c':'reserved'},
'reg_arb_pri_rd_portn': {'r':( 0, 9),'d':0x3FF, 'c':'Priority for this Read port, lower value - higher priority'}}},
'axi_priority_rd_port2': {'OFFS': 0x220,'DFLT':0x000003FF,'RW':'M','COMMENTS':'AXI priority control for read port 2','FIELDS':{
'reg_arb_set_hpr_rd_portn': {'r':(19,19),'d':0x1, 'c':'Enable reads to be HPR for this port'},
'reg_arb_dis_page_match_rd_portn': {'r':(18,18),'d':0, 'c':'Disable page match feature'},
'reg_arb_disable_urgent_rd_portn': {'r':(17,17),'d':0, 'c':'Disable urgent for this Read Port'},
'reg_arb_disable_aging_rd_portn': {'r':(16,16),'d':0, 'c':'Disable aging for this Read Port'},
'reserved1': {'r':(10,15),'d':0, 'm':'R','c':'reserved'},
'reg_arb_pri_rd_portn': {'r':( 0, 9),'d':0x3FF, 'c':'Priority for this Read port, lower value - higher priority'}}},
'axi_priority_rd_port3': {'OFFS': 0x224,'DFLT':0x000003FF,'RW':'M','COMMENTS':'AXI priority control for read port 3','FIELDS':{
'reg_arb_set_hpr_rd_portn': {'r':(19,19),'d':0x1, 'c':'Enable reads to be HPR for this port'},
'reg_arb_dis_page_match_rd_portn': {'r':(18,18),'d':0, 'c':'Disable page match feature'},
'reg_arb_disable_urgent_rd_portn': {'r':(17,17),'d':0, 'c':'Disable urgent for this Read Port'},
'reg_arb_disable_aging_rd_portn': {'r':(16,16),'d':0, 'c':'Disable aging for this Read Port'},
'reserved1': {'r':(10,15),'d':0, 'm':'R','c':'reserved'},
'reg_arb_pri_rd_portn': {'r':( 0, 9),'d':0x3FF, 'c':'Priority for this Read port, lower value - higher priority'}}},
# u32 reserved12[0x1A]; /* 0x228 */
'trusted_mem_cfg': {'OFFS': 0x290,'DFLT':0x00000000,'RW':'RW','COMMENTS':'Trusted Memory Configuration (obsolete)','FIELDS':{
'reg_decprot': {'r':( 0,31),'d':0x0,'c':'Each bit for 64MB section, 1 - secure, 0 - non-secure. Not used anymore'}}},
'excl_access_cfg0': {'OFFS': 0x294,'DFLT':0x00000000,'RW':'RW','COMMENTS':'Exclusive access configuration for port 0','FIELDS':{
'reg_excl_acc_id1_port': {'r':( 9,17),'d':0, 'c':'reserved'},
'reg_excl_acc_id0_port': {'r':( 0, 8),'d':0, 'c':'reserved'}}},
'excl_access_cfg1': {'OFFS': 0x298,'DFLT':0x00000000,'RW':'RW','COMMENTS':'Exclusive access configuration for port 1','FIELDS':{
'reg_excl_acc_id1_port': {'r':( 9,17),'d':0, 'c':'reserved'},
'reg_excl_acc_id0_port': {'r':( 0, 8),'d':0, 'c':'reserved'}}},
'excl_access_cfg2': {'OFFS': 0x29C,'DFLT':0x00000000,'RW':'RW','COMMENTS':'Exclusive access configuration for port 2','FIELDS':{
'reg_excl_acc_id1_port': {'r':( 9,17),'d':0, 'c':'reserved'},
'reg_excl_acc_id0_port': {'r':( 0, 8),'d':0, 'c':'reserved'}}},
'excl_access_cfg3': {'OFFS': 0x2A0,'DFLT':0x00000000,'RW':'RW','COMMENTS':'Exclusive access configuration for port 3','FIELDS':{
'reg_excl_acc_id1_port': {'r':( 9,17),'d':0, 'c':'reserved'},
'reg_excl_acc_id0_port': {'r':( 0, 8),'d':0, 'c':'reserved'}}},
'mode_reg_read': {'OFFS': 0x2A4,'DFLT':0x00000000,'RW':'R','COMMENTS':'Mode register read data','FIELDS':{
'ddrc_reg_rd_mrr_data': {'r':( 0,31),'d':0x0, 'M':'R','c':'LPDDR2 only: Mode register read data, valid when ddrc_co_rd_mrr_data_valid is set'}}},
'lpddr_ctrl0': {'OFFS': 0x2A8,'DFLT':0x00000000,'RW':'RW','COMMENTS':'LPDDR2 control register 0','FIELDS':{
'reg_ddrc_mr4_margin': {'r':( 4,11),'d':0, 'c':'unused'},
'reserved1': {'r':( 3, 3),'d':0, 'c':'reserved'},
'reg_ddrc_derate_enable': {'r':( 2, 2),'d':0, 'c':'Timing parameter derating ENABLED using MR4 read data'},
'reserved2': {'r':( 1, 1),'d':0, 'c':'reserved'},
'reg_ddrc_lpddr2': {'r':( 0, 0),'d':0, 'c':'0 - DDR2/DDR3 in use, 1 - LPDDR2 in use'}}},
'lpddr_ctrl1': {'OFFS': 0x2AC,'DFLT':0x00000000,'RW':'RW','COMMENTS':'LPDDR2 control register 1','FIELDS':{
'reg_ddrc_mr4_read_int erval': {'r':(31, 0),'d':0, 'c':'Interval between two MR4 reads (for derating timing)'}}},
'lpddr_ctrl2': {'OFFS': 0x2B0,'DFLT':0x003C0015,'RW':'RW','COMMENTS':'LPDDR2 control register 2','FIELDS':{
'reg_ddrc_t_mrw': {'r':(12,21),'d':0x3C0,'c':'Wait for MR writes, typically required 5???'},
'reg_ddrc_idle_after_reset_x32': {'r':( 4,11),'d':0x1, 'c':'Idle time after reset command, tINIT4 (in clockx32)'},
'reg_ddrc_min_stable_clock_x1': {'r':( 0, 3),'d':0x5, 'c':'time to wait after first CKE high, tINIT2 in clock cycles. Typically required 5 (tCK)'}}},
'lpddr_ctrl3': {'OFFS': 0x2B4,'DFLT':0x00000601,'RW':'RW','COMMENTS':'LPDDR2 control register 3','FIELDS':{
'reg_ddrc_dev_zqinit_x32': {'r':( 8,17),'d':0x1, 'c':'tZQINIT - ZQ initial calibration (in clockx32). LPDDR@ typically require 1 microsecond'},
'reg_ddrc_max_auto_init_x1024': {'r':( 0, 7),'d':0x1, 'c':'tINIT5 - maximal duration of autoinitialization (in clockx1024). Typical 10 microseconds'}}}
}
#!/usr/bin/env python
# Copyright (C) 2013, Elphel.inc.
# Registers/bit fields manipulation
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
__author__ = "Andrey Filippov"
__copyright__ = "Copyright 2013, Elphel, Inc."
__license__ = "GPL"
__version__ = "3.0+"
__maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__status__ = "Development"
class EzynqRegisters:
ERRORS={
'ERR_REG': 'Register name is not defined',
'ERR_FIELD': 'Bit field is not defined',
'ERR_RO': 'Trying to overwrite read only register/ bit field',
'ERR_BITS': 'Data exceeds the available bits',
'ERR_NOTSET':'Register is not set',
}
def _mask(self,bits):
mask=0
for i in range (min(bits),max(bits)+1):
mask |= 1<<i
return mask
def _data(self,bits,data,warn=False):
mask=self._mask(bits)>>min(bits)
if (data & ~mask)!=0 :
msg ='Data '+hex(data)+' does not fit info the bit field '+bits
if warn:
print 'WARNING: '+msg
else:
raise Exception (self.ERRORS['ERR_BITS']+' '+msg)
return (data & mask) << min(bits)
def __init__(self,defines,channel=0,permit_undefined_bits=False):
self.defs=defines
self.base_addr=self.defs['BASE_ADDR'][channel]
self.registers={}
# calculate R/W masks
self.ro_masks={}
for reg_name in self.defs:
reg=self.defs[reg_name]
if ('RW' in reg) and permit_undefined_bits:
if 'W' in reg['RW']:
self.ro_masks[reg_name]=0 # all enabled
break;
elif 'R' in reg['RW']: # R, but no W - read only
self.ro_masks[reg_name]=0xFFFFFFFF # all read only
break;
else:
# some bits are writable, some - readonly
ro_mask=0
wr_mask=0
# print '==== reg_name=',reg_name
# print '==== reg=',reg
try:
fields=reg['FIELDS']
except:
continue
for field_name in fields:
field=fields[field_name]
# print field_name,field
m= self._mask(field['r'])
if ('m' in field) and (field['m']=='R'):
ro_mask |= m
else:
wr_mask |= m
self.ro_masks[reg_name]=((~wr_mask) & 0xFFFFFFFF, ro_mask)[permit_undefined_bits != 0]
# Combine bit field defaults into register default?
def set_word(self,register_name,data,force=False):
if not register_name in self.defs:
raise Exception (self.ERRORS['ERR_REG']+' '+register_name)
# addr=self.base_addr+self.defs[register_name]['OFFS']
try:
d=self.defs[register_name]['DFLT']
except:
d=0 # DFLT not defined
# d=int (d,0)
diff = (data ^ d) & self.ro_masks[register_name]
if diff:
msg= register_name+" readonly mask="+hex(self.ro_masks[register_name])+" default data="+hex(d)+" new data = "+data+" force="+force
if force:
print 'WARNING: '+msg
else:
raise Exception (self.ERRORS['ERR_RO'] + " " + msg)
self.registers[register_name]=data
def unset_word(self,register):
if not register in self.defs:
raise Exception (self.ERRORS['ERR_REG'])
try:
del self.registers[register]
except:
pass # OK if it did not exist
# force - force readonly/undefined, warn - if data does n ot fit into the bit field
def set_bitfield(self,register_name,field_name,data,force=False,warn=False):
if not register_name in self.defs:
raise Exception (self.ERRORS['ERR_REG']+' '+register_name)
# addr=self.base_addr+self.defs[register_name]['OFFS']
try:
old_data=self.registers[register_name] # already in the list of registers?
except:
try:
old_data=self.defs[register_name]['DFLT'] # default provided?
except:
old_data=0 # DFLT not defined, use 0
old_data=old_data
#new data and mask
try:
field=self.defs[register_name]['FIELDS'][field_name]
except:
raise Exception (self.ERRORS['ERR_FIELD']+': '+register_name+'.'+field_name)
mask= self._mask(field['r'])
new_data=self._data(field['r'],data,warn)
combined_data= ((new_data ^ old_data) & mask) ^ old_data # new data applied to old data
diff = (combined_data ^ old_data) & self.ro_masks[register_name]
if diff:
msg= register_name+" readonly mask="+hex(self.ro_masks[register_name])+" old data="+hex(old_data)+" new data = "+combined_data+" force="+force
if force:
print 'WARNING: '+msg
else:
raise Exception (self.ERRORS['ERR_RO'] + " " + msg)
self.registers[register_name]=combined_data
def unset_bitfield(self,register_name,field_name):
if not register_name in self.defs:
raise Exception (self.ERRORS['ERR_REG']+' '+register_name)
try:
old_data=self.registers[register_name] # already in the list of registers?
except:
return # register is not set
try:
dflt_data=self.defs[register_name]['DFLT'] # default provided?
except:
dflt_data=0 # DFLT not defined, use 0
#new data and mask
try:
field=self.defs[register_name]['FIELDS'][field_name]
except:
raise Exception (self.ERRORS['ERR_FIELD']+': '+register_name+'.'+field_name)
mask= self._mask(field['r'])
combined_data= ((dflt_data ^ old_data) & mask) ^ old_data # new data applied to old data
self.registers[register_name]=combined_data # no need to verify readonly - restoring defaults
def get_reg_names(self):
# name_offs=sorted([(name,self.registers[name]['OFFS']) for name in self.registers], key = lambda l: l[1])
# print '---self.registers=',self.registers
# unsorted_name_offs=[(name,self.defs[name]['OFFS']) for name in self.registers]
# print '---unsorted_name_offs=',unsorted_name_offs
# name_offs=sorted(unsorted_name_offs, key = lambda l: l[1])
# print '---name_offs=',name_offs
# return [n for n in name_offs]
# sort register names in the order of addresses
return [n for n in sorted([(name,self.defs[name]['OFFS']) for name in self.registers], key = lambda l: l[1])]
def _get_register_address_data_default(self,register_name,from_defines=False):
if not register_name in self.defs:
raise Exception (self.ERRORS['ERR_REG']+' '+register_name)
def_reg= self.defs[register_name]
address=self.base_addr+def_reg['OFFS']
try:
dflt_data=self.defs[register_name]['DFLT']
except:
dflt_data=0 #default is not defined for the register
data=dflt_data
if not from_defines:
try:
data=self.registers[register_name]
except:
raise Exception (self.ERRORS['ERR_NOTSET'] + " " + register_name)
return (address,data,dflt_data)
def get_address_data_pairs_list(self):
return[{'ADDRESS':self.base_addr+self.defs[name]['OFFS']} for name in self.get_reg_names()]
def get_register_details(self,register_name,from_defines=False):
# print '===register_name=',register_name
address, data, dflt_data = self._get_register_address_data_default(register_name,from_defines)
details={'NAME':register_name,'ADDRESS':address,'DATA':data}
def_reg= self.defs[register_name]
for key in def_reg:
if key=='FIELDS':
pass
else:
details[key]=def_reg[key]
# fill in needed fields if they were missing
if not 'DFLT' in details:
details['DFLT']=dflt_data
if not 'RW' in details:
details['RW']='RW'
if not 'COMMENTS' in details:
details['COMMENTS']=''
field_details=[]
for field_name in def_reg['FIELDS']:
# print '+++++ field_name=',field_name
# print ' details=',details
field_details.append(self.get_bitfield_details(register_name,field_name,from_defines))
# print '+++++ field_details=',field_details
details['FIELDS']=sorted(field_details, key = lambda rr: -rr['r'][0]) # from MSB to LSB
return details
def get_bitfield_details(self,register_name,field_name,from_defines=False):
_, data, dflt_data = self._get_register_address_data_default(register_name,from_defines)
if not field_name in self.defs[register_name]['FIELDS']:
raise Exception (self.ERRORS['ERR_FIELD']+' '+register_name+'.'+field_name)
bit_field=self.defs[register_name]['FIELDS'][field_name]
mask=self._mask(bit_field['r'])
field_data=(data & mask) >> min(bit_field['r'])
field_dflt=(dflt_data & mask) >> min(bit_field['r'])
field_details={'NAME':field_name,'DATA':field_data}
for key in bit_field:
field_details[key]=bit_field[key]
field_details['d']=field_dflt
try:
field_details['m'] = bit_field['m']
except:
field_details['m'] = 'RW'
if not 'c' in field_details:
field_details['c']=''
return field_details
def print_html_register(self, register_name, html_file, show_bit_fields=True, show_comments=True):
r=self.get_register_details(register_name,False)
html_file.write('<tr>\n')
if show_bit_fields:
html_file.write(' <th>'+hex(r['ADDRESS'])+'</th><th>'+r['NAME']+'</th><th>'+r['RW']+'</th><th>'+hex(r['DATA'])+'</th><th>'+hex(r['DFLT'])+'</th>')
if show_comments:
html_file.write('<th>'+(r['COMMENTS'])+'</th>')
html_file.write('\n</tr>\n')
for field in r['FIELDS']:
html_file.write(' <tr><td>'+str(field['r'][0])+":"+str(field['r'][1])+'</td><td>'+field['NAME']+'</td><td>'+field['m']+'</td>')
html_file.write('<td>'+hex(field['DATA'])+'</td><td>'+hex(field['d'])+'</td>')
if show_comments:
html_file.write('<td>'+(field['c'])+'</td>')
html_file.write('\n</tr>\n')
else:
html_file.write(' <th>'+hex(r['ADDRESS'])+'</th><td>'+r['NAME']+'</td><td>'+r['RW']+'</td><td><b>'+hex(r['DATA'])+'</b></td><td>'+hex(r['DFLT'])+'</td>')
if show_comments:
html_file.write('<td>'+r['COMMENTS']+'</td>')
html_file.write('\n</tr>\n')
def print_html_registers(self, html_file, show_bit_fields=True, show_comments=True):
html_file.write('<table border="1">\n')
if show_bit_fields:
html_file.write('<tr><th>Address/<br/>bit field</th><th>Register name/<br>Bit field name</th><th>R/W</th><th>Value</th><th>Default</th>\n')
if show_comments:
html_file.write('<th>Comments</th>')
html_file.write('</tr>')
else:
html_file.write('<tr><th>Address</th><th>Register name</th><th>R/W</th><th>Value</th><th>Default</th>\n')
if show_comments:
html_file.write('<th>Comments</th>')
html_file.write('</tr>')
for register in self.get_reg_names():
self.print_html_register(register[0], html_file, show_bit_fields, show_comments)
html_file.write('</table>\n')
#QULAIFIER_CHAR
#prefix like CONFIG_EZYNQ_DDR_SET_
#postfix like '_PRE','_POST' or ''
#qualifier_char '__'
#value may be hex/decimal or "FREE" (value convert to upper)
def parse_options_set(self,raw_configs,prefix,postfix,postfixes,qualifier_char,force=True,warn=True): #force - readonly/undefined fields, warn: data does not fit in the bit field
raw_regs={}
for line in raw_configs:
reg = line['KEY']
value = line['VALUE']
value=str(value).upper()
if (reg[:len(prefix) ]== prefix) and (reg[len(reg)-len(postfix):] == postfix):
#see if any other postfixes match
for other_postfix in postfixes:
if (other_postfix!=postfix) and (len(other_postfix)> len(postfix)) and (reg[len(reg)-len(other_postfix):] == other_postfix):
# print '== reg=',reg
# print '== postfix=',postfix
# print '== other_postfix=',other_postfix
break
else: #no other postfixes match
reg=reg[len(prefix):len(reg)-len(postfix)]
# print '++++ reg=',reg
if qualifier_char in reg:
reg,field=reg.split(qualifier_char,1)
else:
field=''
if not reg in self.defs:
raise Exception (self.ERRORS['ERR_REG']+' '+reg)
try:
value=int(value,0)
except:
value="FREE" # "Free" - anything but numeric/hex. Or do something else, parse more options?
if not reg in raw_regs:
raw_regs[reg] = {}
if len(field)>0:
if not field in self.defs[reg]['FIELDS']:
raise Exception (self.ERRORS['ERR_FIELD']+': '+reg+'.'+field)
try:
raw_regs[reg]['FIELDS'][field]=value
except:
raw_regs[reg]['FIELDS']={field:value}
else:
raw_regs[reg]['VALUE']=value
# apply raw_regs (should be done after normal parameters processed and some registers are populated
# if len(raw_regs) >0:
# print raw_regs
for reg_name in raw_regs:
reg=raw_regs[reg_name]
if 'VALUE' in reg:
if reg['VALUE'] == 'FREE':
self.unset_word(reg_name)
else:
self.set_word(reg_name,reg['VALUE'],force)
try:
fields=raw_regs[reg_name]['FIELDS']
except:
continue
for field_name in fields:
if fields[field_name] == 'FREE': #) or (reg_name in self.registers):
self.unset_bitfield(reg_name,field_name) # will do nothing if register is not there
else:
self.set_bitfield(reg_name,field_name,fields[field_name],force,warn)
\ No newline at end of file
...@@ -22,6 +22,8 @@ __maintainer__ = "Andrey Filippov" ...@@ -22,6 +22,8 @@ __maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com" __email__ = "andrey@elphel.com"
__status__ = "Development" __status__ = "Development"
import struct import struct
import ezynq_ddr
# http://docs.python.org/2/howto/argparse.html # http://docs.python.org/2/howto/argparse.html
import argparse import argparse
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
...@@ -36,32 +38,32 @@ args = parser.parse_args() ...@@ -36,32 +38,32 @@ args = parser.parse_args()
#print args #print args
#print args.configs #print args.configs
ERROR_DEFS={
ERR_WRONG_USAGE=1 'WRONG_USAGE':1,
ERR_MISSING_CONFIG = 2 'MISSING_CONFIG': 2,
ERR_INVALID = 3 'INVALID': 3,
ERR_NOSUCHPIN = 4 'NOSUCHPIN': 4,
ERR_NOSUCHSIGNAL = 5 'NOSUCHSIGNAL': 5,
ERR_MIOCONFLICT = 6 'MIOCONFLICT':6,
ERR_INOUT = 7 'INOUT': 7,
ERR_HEAD = 8 'HEAD': 8,
ERR_NONACCESSIBLE_REHGISTER = 9 'NONACCESSIBLE_REGISTER': 9,
ERR_NOT_IMPLEMENTED=10 'NOT_IMPLEMENTED':10}
COMMENT_CHAR = '#' COMMENT_CHAR = '#'
OPTION_CHAR = '=' OPTION_CHAR = '='
QULAIFIER_CHAR = '__' QUALIFIER_CHAR = '__'
if not args.configs: if not args.configs:
parser.print_help() parser.print_help()
exit (ERR_WRONG_USAGE) exit (ERROR_DEFS['WRONG_USAGE'])
WARN=args.warn WARN=args.warn
MIO_HTML=args.html MIO_HTML=args.html
try: try:
MIO_HTML_MASK=int(args.html_mask) MIO_HTML_MASK=int(args.html_mask,0)
except: except:
MIO_HTML_MASK=0 MIO_HTML_MASK=0
MIO_TEMPLATES = { MIO_TEMPLATES = {
'QUADSPI':( 'QUADSPI':(
...@@ -296,6 +298,8 @@ MIO_ATTR=[ ...@@ -296,6 +298,8 @@ MIO_ATTR=[
{'PREFIX':'CONFIG_EZYNQ_MIO_INOUT_', 'SPECIAL':'DIR'}, {'PREFIX':'CONFIG_EZYNQ_MIO_INOUT_', 'SPECIAL':'DIR'},
{'PREFIX':'CONFIG_EZYNQ_MIO_GPIO_OUT_', 'SPECIAL':'GPIO_OUT'}] {'PREFIX':'CONFIG_EZYNQ_MIO_GPIO_OUT_', 'SPECIAL':'GPIO_OUT'}]
GPIO_MASKDATA=[ GPIO_MASKDATA=[
{'NAME':'MASK_DATA_0_LSW','ADDRESS':0xE000A000,'DATA':0}, {'NAME':'MASK_DATA_0_LSW','ADDRESS':0xE000A000,'DATA':0},
{'NAME':'MASK_DATA_0_MSW','ADDRESS':0xE000A004,'DATA':0}, {'NAME':'MASK_DATA_0_MSW','ADDRESS':0xE000A004,'DATA':0},
...@@ -326,16 +330,13 @@ ACCESSIBLE_REGISTERS=((0xe0001000,0xe0001fff), # UART1 controller registers ...@@ -326,16 +330,13 @@ ACCESSIBLE_REGISTERS=((0xe0001000,0xe0001fff), # UART1 controller registers
(0xf8000a00,0xf8000a8c), # SLCR registers All shown "reserved" ??? (0xf8000a00,0xf8000a8c), # SLCR registers All shown "reserved" ???
(0xf8000ab0,0xf8000b74)) # SLCR registers iostd, voltages, - more DDR stuff (0xf8000ab0,0xf8000b74)) # SLCR registers iostd, voltages, - more DDR stuff
#TODO: list configurable interfaces (ordered list) and process it in the defined order
#Each interface may have channel and always has name (as in MIO_TEMPLATES)
if args.verbosity >= 2: if args.verbosity >= 2:
print MIO_TEMPLATES print MIO_TEMPLATES
def parse_config(filename): def read_config(filename):
attrib_suffix='ATTRIB' raw_configs = []
options = {}
f = open(filename) f = open(filename)
for line in f: for line in f:
# First, remove comments: # First, remove comments:
...@@ -349,33 +350,42 @@ def parse_config(filename): ...@@ -349,33 +350,42 @@ def parse_config(filename):
# strip spaces: # strip spaces:
option = option.strip() option = option.strip()
value = value.strip().upper() value = value.strip().upper()
# strip quotes:
value = value.strip('"') value = value.strip('"')
if QULAIFIER_CHAR in option: raw_configs.append({'KEY':option,'VALUE':value})
option,qualifier=option.split(QULAIFIER_CHAR,1)
if not option in options:
options[option]={}
if not isinstance(options[option],dict): # make a former value a value in a dictionary
options[option]={'INTERFACE_GROUP':options[option]}
if qualifier==attrib_suffix:
value=str(value).upper()
try:
options[option]['ATTRIBS'].add(value)
except:
options[option]['ATTRIBS']=set([value])
if not 'INTERFACE_GROUP' in options[option]:
options[option]['INTERFACE_GROUP']='Y' # 'any' if not overwritten, so just setting attribute initializes interface
else:
options[option][qualifier]=value
else:
# store in dictionary:
if option in options:
try:
options[option]['INTERFACE_GROUP'] = value #qualified pins already defined
except:
options[option] = value # not a dictionary - just overwrite
else:
options[option] = value
f.close() f.close()
return raw_configs
def parse_config_mio(raw_configs):
attrib_suffix='ATTRIB'
options = {}
for line in raw_configs:
option = line['KEY']
value = line['VALUE']
if QUALIFIER_CHAR in option:
option,qualifier=option.split(QUALIFIER_CHAR,1)
if not option in options:
options[option]={}
if not isinstance(options[option],dict): # make a former value a value in a dictionary
options[option]={'INTERFACE_GROUP':options[option]}
if qualifier==attrib_suffix:
value=str(value).upper()
try:
options[option]['ATTRIBS'].add(value)
except:
options[option]['ATTRIBS']=set([value])
if not 'INTERFACE_GROUP' in options[option]:
options[option]['INTERFACE_GROUP']='Y' # 'any' if not overwritten, so just setting attribute initializes interface
else:
options[option][qualifier]=value
else:
# store in the dictionary:
if option in options:
try:
options[option]['INTERFACE_GROUP'] = value #qualified pins already defined
except:
options[option] = value # not a dictionary - just overwrite
else:
options[option] = value
return options return options
def mio_set_defaults(mio_dflts, mio, options): def mio_set_defaults(mio_dflts, mio, options):
...@@ -385,20 +395,20 @@ def mio_set_defaults(mio_dflts, mio, options): ...@@ -385,20 +395,20 @@ def mio_set_defaults(mio_dflts, mio, options):
mio_dflts['MIO_0_VOLT'] = float(options['CONFIG_EZYNQ_MIO_0_VOLT']) mio_dflts['MIO_0_VOLT'] = float(options['CONFIG_EZYNQ_MIO_0_VOLT'])
except (KeyError): except (KeyError):
print "required CONFIG_EZYNQ_MIO_0_VOLT is not defined. It should be 1.8, 2.5 or 3.3" print "required CONFIG_EZYNQ_MIO_0_VOLT is not defined. It should be 1.8, 2.5 or 3.3"
exit (ERR_MISSING_CONFIG) exit (ERROR_DEFS['MISSING_CONFIG'])
if not mio_dflts['MIO_0_VOLT'] in VALID_VOLTAGES: if not mio_dflts['MIO_0_VOLT'] in VALID_VOLTAGES:
print 'Invalid voltage specified for MIO bank 0: CONFIG_EZYNQ_MIO_0_VOLT = ' + options['CONFIG_EZYNQ_MIO_0_VOLT'] print 'Invalid voltage specified for MIO bank 0: CONFIG_EZYNQ_MIO_0_VOLT = ' + options['CONFIG_EZYNQ_MIO_0_VOLT']
print 'Valid values are : ' + str(VALID_VOLTAGES) print 'Valid values are : ' + str(VALID_VOLTAGES)
exit (ERR_INVALID) exit (ERROR_DEFS['INVALID'])
try: try:
mio_dflts['MIO_1_VOLT'] = float(options['CONFIG_EZYNQ_MIO_1_VOLT']) mio_dflts['MIO_1_VOLT'] = float(options['CONFIG_EZYNQ_MIO_1_VOLT'])
except (KeyError): except (KeyError):
print "required CONFIG_EZYNQ_MIO_1_VOLT is not defined. It should be 1.8, 2.5 or 3.3" print "required CONFIG_EZYNQ_MIO_1_VOLT is not defined. It should be 1.8, 2.5 or 3.3"
exit (ERR_MISSING_CONFIG) exit (ERROR_DEFS['MISSING_CONFIG'])
if not mio_dflts['MIO_1_VOLT'] in VALID_VOLTAGES: if not mio_dflts['MIO_1_VOLT'] in VALID_VOLTAGES:
print 'Invalid voltage specified for MIO bank 1: CONFIG_EZYNQ_MIO_1_VOLT = ' + options['CONFIG_EZYNQ_MIO_1_VOLT'] print 'Invalid voltage specified for MIO bank 1: CONFIG_EZYNQ_MIO_1_VOLT = ' + options['CONFIG_EZYNQ_MIO_1_VOLT']
print 'Valid values are : ' + str(VALID_VOLTAGES) print 'Valid values are : ' + str(VALID_VOLTAGES)
exit (ERR_INVALID) exit (ERROR_DEFS['INVALID'])
iostd0 = IOSTD[VALID_VOLTAGES.index(mio_dflts['MIO_0_VOLT'])] iostd0 = IOSTD[VALID_VOLTAGES.index(mio_dflts['MIO_0_VOLT'])]
pullup0 = False pullup0 = False
if 'CONFIG_EZYNQ_MIO_0_PULLUP' in options: if 'CONFIG_EZYNQ_MIO_0_PULLUP' in options:
...@@ -452,7 +462,7 @@ def set_mio_interfaces(mio_interfaces, options): ...@@ -452,7 +462,7 @@ def set_mio_interfaces(mio_interfaces, options):
for pin in func_pin['PINS'][channel]: for pin in func_pin['PINS'][channel]:
allowed_pins.append(pin) allowed_pins.append(pin)
print 'Allowed MIO pins are:',allowed_pins print 'Allowed MIO pins are:',allowed_pins
exit (ERR_NOSUCHPIN) exit (ERROR_DEFS['NOSUCHPIN'])
for tmpl_pin in iface_template: for tmpl_pin in iface_template:
iface_pin={} iface_pin={}
for key in tmpl_pin.keys(): for key in tmpl_pin.keys():
...@@ -488,8 +498,8 @@ def set_mio_interfaces(mio_interfaces, options): ...@@ -488,8 +498,8 @@ def set_mio_interfaces(mio_interfaces, options):
break; break;
else: else:
print 'Signal name '+individual_pin_name+' is not defined for interface '+iface_name+' in' print 'Signal name '+individual_pin_name+' is not defined for interface '+iface_name+' in'
print conf_iface['CONFIG_NAME']+QULAIFIER_CHAR+individual_pin_name+" = "+option[individual_pin_name] print conf_iface['CONFIG_NAME']+QUALIFIER_CHAR+individual_pin_name+" = "+option[individual_pin_name]
exit (ERR_NOSUCHSIGNAL) exit (ERROR_DEFS['NOSUCHSIGNAL'])
if (value<0): if (value<0):
try: try:
del iface[individual_pin_name] del iface[individual_pin_name]
...@@ -501,9 +511,9 @@ def set_mio_interfaces(mio_interfaces, options): ...@@ -501,9 +511,9 @@ def set_mio_interfaces(mio_interfaces, options):
value=tmpl_pin['PINS'][channel][0] # first variant value=tmpl_pin['PINS'][channel][0] # first variant
if not value in tmpl_pin['PINS'][channel]: if not value in tmpl_pin['PINS'][channel]:
print 'Invalid MIO pin number '+str(value)+' for interface '+iface_name+print_channel+', set in ' print 'Invalid MIO pin number '+str(value)+' for interface '+iface_name+print_channel+', set in '
print conf_iface['CONFIG_NAME']+QULAIFIER_CHAR+individual_pin_name+" = "+option[individual_pin_name] print conf_iface['CONFIG_NAME']+QUALIFIER_CHAR+individual_pin_name+" = "+option[individual_pin_name]
print 'Allowed MIO pins are:',tmpl_pin['PINS'][channel] print 'Allowed MIO pins are:',tmpl_pin['PINS'][channel]
exit (ERR_NOSUCHPIN) exit (ERROR_DEFS['NOSUCHPIN'])
#set new pin data #set new pin data
iface_pin={} iface_pin={}
for key in tmpl_pin.keys(): for key in tmpl_pin.keys():
...@@ -526,7 +536,7 @@ def config_name (iface, channel, signal): ...@@ -526,7 +536,7 @@ def config_name (iface, channel, signal):
for mi in MIO_INTERFACES: for mi in MIO_INTERFACES:
if (mi['IFACE']==iface) and (mi['CHANNEL']==channel) : if (mi['IFACE']==iface) and (mi['CHANNEL']==channel) :
if signal: if signal:
return mi['CONFIG_NAME']+QULAIFIER_CHAR+signal return mi['CONFIG_NAME']+QUALIFIER_CHAR+signal
else: else:
return mi['CONFIG_NAME'] return mi['CONFIG_NAME']
...@@ -551,7 +561,7 @@ def apply_mio_interfaces(mio, mio_interfaces,warn): ...@@ -551,7 +561,7 @@ def apply_mio_interfaces(mio, mio_interfaces,warn):
print config_name (name, channel, signal)+'=free' print config_name (name, channel, signal)+'=free'
print 'to the board configuration file\n' print 'to the board configuration file\n'
if not warn: if not warn:
exit (ERR_MIOCONFLICT) exit (ERROR_DEFS['MIOCONFLICT'])
#add current pin usage information #add current pin usage information
mio[pin['PIN']]['USED_IN'].append({'NAME':name, 'CHANNEL':channel,'SIGNAL':signal,'PRINT_CHANNEL':print_channel}) mio[pin['PIN']]['USED_IN'].append({'NAME':name, 'CHANNEL':channel,'SIGNAL':signal,'PRINT_CHANNEL':print_channel})
#modify mio pin attributes #modify mio pin attributes
...@@ -627,7 +637,7 @@ def set_mio_attribs(mio,options): ...@@ -627,7 +637,7 @@ def set_mio_attribs(mio,options):
key=int(option[len(prefix):]) key=int(option[len(prefix):])
except: except:
print 'Invalid pin number ',option[len(prefix):],' in',option print 'Invalid pin number ',option[len(prefix):],' in',option
exit (ERR_NOSUCHPIN) exit (ERROR_DEFS['NOSUCHPIN)'])
attribs[prefix][key]=options[option] attribs[prefix][key]=options[option]
break break
# print '------- attribs -----' # print '------- attribs -----'
...@@ -642,7 +652,7 @@ def set_mio_attribs(mio,options): ...@@ -642,7 +652,7 @@ def set_mio_attribs(mio,options):
# print '***',attr['PROPERTY'],pin,attr['VALUE'] # print '***',attr['PROPERTY'],pin,attr['VALUE']
else: else:
print attr['PREFIX']+str(pin)+': pin number',pin,' out of range 0...53' print attr['PREFIX']+str(pin)+': pin number',pin,' out of range 0...53'
exit (ERR_NOSUCHPIN) exit (ERROR_DEFS['NOSUCHPIN'])
#set IN, OUT, BIDIR (INOUT) parameters #set IN, OUT, BIDIR (INOUT) parameters
elif ('SPECIAL' in attr) and (attr['SPECIAL']=='DIR') and (attr['PREFIX'] in attribs): elif ('SPECIAL' in attr) and (attr['SPECIAL']=='DIR') and (attr['PREFIX'] in attribs):
for pin in attribs[attr['PREFIX']]: for pin in attribs[attr['PREFIX']]:
...@@ -657,11 +667,11 @@ def set_mio_attribs(mio,options): ...@@ -657,11 +667,11 @@ def set_mio_attribs(mio,options):
else: else:
print 'Invalid MIO pin polarity in',attr['PREFIX']+str(pin),'=',value print 'Invalid MIO pin polarity in',attr['PREFIX']+str(pin),'=',value
print 'Polarity can only be IN, OUT or BIDIR' print 'Polarity can only be IN, OUT or BIDIR'
exit (ERR_INOUT) exit (ERROR_DEFS['INOUT'])
if (pin==7) or (pin==8) and (value!='OUT'): if (pin==7) or (pin==8) and (value!='OUT'):
print 'Invalid MIO pin polarity in',attr['PREFIX']+str(pin),'=',value print 'Invalid MIO pin polarity in',attr['PREFIX']+str(pin),'=',value
print 'Polarity for MIO pins 7 and 8 can only be OUT' print 'Polarity for MIO pins 7 and 8 can only be OUT'
exit (ERR_INOUT) exit (ERROR_DEFS['INOUT'])
mio[pin]['INOUT']=value #Where is it used? mio[pin]['INOUT']=value #Where is it used?
if value=='IN': if value=='IN':
mio[pin]['TRISTATE']=True mio[pin]['TRISTATE']=True
...@@ -782,7 +792,7 @@ def output_slcr_lock(registers,f,lock,MIO_HTML_MASK): ...@@ -782,7 +792,7 @@ def output_slcr_lock(registers,f,lock,MIO_HTML_MASK):
# for i,word in enumerate (GPIO_MASKDATA): # for i,word in enumerate (GPIO_MASKDATA):
word=SLCR_LOCK[lock!=0] word=SLCR_LOCK[lock!=0]
# print word # print word
registers.append({'ADDRESS':word['ADDRESS'],'DATA':word['DATA']}) registers.append({'ADDRESS':word['ADDRESS'],'DATA':word['DATA']})
if f: if f:
f.write(' <tr><td>'+word['NAME']+'</td><td>'+hex(word['ADDRESS'])+'</td><td>'+hex(word['DATA'])+'</td></tr>\n') f.write(' <tr><td>'+word['NAME']+'</td><td>'+hex(word['ADDRESS'])+'</td><td>'+hex(word['DATA'])+'</td></tr>\n')
...@@ -825,7 +835,7 @@ def image_generator (image, registers, user_def,ocm_offset,ocm_len,start_exec): ...@@ -825,7 +835,7 @@ def image_generator (image, registers, user_def,ocm_offset,ocm_len,start_exec):
reserved0044=0; reserved0044=0;
if 'CONFIG_EZYNQ_RESERVED44' in options: reserved0044= int(options['CONFIG_EZYNQ_RESERVED44'],0) if 'CONFIG_EZYNQ_RESERVED44' in options: reserved0044= int(options['CONFIG_EZYNQ_RESERVED44'],0)
rfi_word=0xeafffffe #froma actual image rfi_word=0xeafffffe #from actual image
waddr=0 waddr=0
for _ in range (0x20/4): for _ in range (0x20/4):
image[waddr]=rfi_word # fill reserved for interrupts fields image[waddr]=rfi_word # fill reserved for interrupts fields
...@@ -849,17 +859,17 @@ def image_generator (image, registers, user_def,ocm_offset,ocm_len,start_exec): ...@@ -849,17 +859,17 @@ def image_generator (image, registers, user_def,ocm_offset,ocm_len,start_exec):
#ocm_offset #ocm_offset
if ocm_offset<0x8c0: if ocm_offset<0x8c0:
print 'Start offset should be >= 0x8c0, specified', hex(ocm_offset) print 'Start offset should be >= 0x8c0, specified', hex(ocm_offset)
exit (ERR_HEAD) exit (ERROR_DEFS['HEAD'])
elif (ocm_offset & 0x3f) != 0: elif (ocm_offset & 0x3f) != 0:
print 'Start offset should be 64-bytes aligned, specified', hex(ocm_offset) print 'Start offset should be 64-bytes aligned, specified', hex(ocm_offset)
exit (ERR_HEAD) exit (ERROR_DEFS['HEAD'])
image[waddr]=ocm_offset # offset 0x30 image[waddr]=ocm_offset # offset 0x30
waddr+=1 waddr+=1
#ocm_len #ocm_len
if ocm_len>0x30000: if ocm_len>0x30000:
print 'Loaded to the OCM image should fit into 3 mapped pages of OCM - 192K (0x30000), specified ',hex(ocm_len) print 'Loaded to the OCM image should fit into 3 mapped pages of OCM - 192K (0x30000), specified ',hex(ocm_len)
exit (ERR_HEAD) exit (ERROR_DEFS['HEAD'])
image[waddr]=ocm_len # offset 0x34 image[waddr]=ocm_len # offset 0x34
waddr+=1 waddr+=1
...@@ -870,7 +880,7 @@ def image_generator (image, registers, user_def,ocm_offset,ocm_len,start_exec): ...@@ -870,7 +880,7 @@ def image_generator (image, registers, user_def,ocm_offset,ocm_len,start_exec):
#start_exec #start_exec
if (start_exec>0x30000) or (start_exec<0): if (start_exec>0x30000) or (start_exec<0):
print 'Start address is relative to OCM and should fit there - in 192K (0x30000), specified ',hex(start_exec) print 'Start address is relative to OCM and should fit there - in 192K (0x30000), specified ',hex(start_exec)
exit (ERR_HEAD) exit (ERROR_DEFS['HEAD'])
image[waddr]=start_exec # offset 0x3c image[waddr]=start_exec # offset 0x3c
waddr+=1 waddr+=1
...@@ -899,7 +909,7 @@ def image_generator (image, registers, user_def,ocm_offset,ocm_len,start_exec): ...@@ -899,7 +909,7 @@ def image_generator (image, registers, user_def,ocm_offset,ocm_len,start_exec):
for register in registers: for register in registers:
if not verify_register_accessible (register['ADDRESS']): if not verify_register_accessible (register['ADDRESS']):
print 'Tried to set non-accessible register', hex(register['ADDRESS']),' with data ', hex(register['DATA']) print 'Tried to set non-accessible register', hex(register['ADDRESS']),' with data ', hex(register['DATA'])
exit (ERR_NONACCESSIBLE_REHGISTER) exit (ERROR_DEFS['NONACCESSIBLE_REGISTER'])
image[waddr]=register['ADDRESS'] image[waddr]=register['ADDRESS']
waddr+=1 waddr+=1
image[waddr]=register['DATA'] image[waddr]=register['DATA']
...@@ -927,8 +937,25 @@ def write_image(image,name): ...@@ -927,8 +937,25 @@ def write_image(image,name):
bf.write(data) bf.write(data)
bf.close() bf.close()
#========================= #=========================
options = parse_config(args.configs) raw_configs=read_config(args.configs)
permit_undefined_bits=False
force=True #False
warn_notfit=True # False
ddr=ezynq_ddr.EzynqDDR(permit_undefined_bits, force, warn_notfit)
ddr.parse_raw_register_set(raw_configs,QUALIFIER_CHAR,force,warn_notfit)
#ddr.print_html_registers(html_file, show_bit_fields=True, show_comments=True)
#class EzynqDDR:
# def __init__(self,permit_undefined_bits=False,force=False,warn=False):
# def parse_raw_register_set(self,raw_configs,qualifier_char,force=True,warn=True):
# def print_html_registers(self, html_file, show_bit_fields=True, show_comments=True):
options = parse_config_mio(raw_configs)
if args.verbosity >= 3: if args.verbosity >= 3:
print options print options
if args.verbosity >= 1: if args.verbosity >= 1:
...@@ -945,7 +972,7 @@ set_mio_interfaces(mio_interfaces, options) ...@@ -945,7 +972,7 @@ set_mio_interfaces(mio_interfaces, options)
apply_mio_interfaces(mio, mio_interfaces,WARN) apply_mio_interfaces(mio, mio_interfaces,WARN)
set_mio_attribs(mio,options) set_mio_attribs(mio,options)
parse_mio(mio) parse_mio(mio)
#sett MIO pin options and initial value for GPIO output #set MIO pin options and initial value for GPIO output
if args.verbosity >= 1: if args.verbosity >= 1:
print '\n===== mio_interfaces === ' print '\n===== mio_interfaces === '
...@@ -971,6 +998,10 @@ else: ...@@ -971,6 +998,10 @@ else:
f=False f=False
#output_slcr_lock(registers,f,False,MIO_HTML_MASK) #prohibited by RBL #output_slcr_lock(registers,f,False,MIO_HTML_MASK) #prohibited by RBL
output_mio(registers,f,mio,MIO_HTML_MASK) output_mio(registers,f,mio,MIO_HTML_MASK)
ddr.print_html_registers(f, MIO_HTML_MASK & 0x100, MIO_HTML_MASK & 0x200)
#output_gpio_out(registers,f,MIO_HTML_MASK) #prohibited by RBL #output_gpio_out(registers,f,MIO_HTML_MASK) #prohibited by RBL
#output_slcr_lock(registers,f,True,MIO_HTML_MASK) #prohibited by RBL #output_slcr_lock(registers,f,True,MIO_HTML_MASK) #prohibited by RBL
if 'CONFIG_EZYNQ_UART_LOOPBACK_0' in options: uart_remote_loopback(registers,f, 0,MIO_HTML_MASK) if 'CONFIG_EZYNQ_UART_LOOPBACK_0' in options: uart_remote_loopback(registers,f, 0,MIO_HTML_MASK)
......
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