1 #ifndef __DRAM_INTERNAL_H__
2 #define __DRAM_INTERNAL_H__
3 /***********************license start***********************************
4 * Copyright (c) 2003-2017 Cavium Inc. ([email protected]). All rights
5 * reserved.
6 *
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 *
20 * * Neither the name of Cavium Inc. nor the names of
21 * its contributors may be used to endorse or promote products
22 * derived from this software without specific prior written
23 * permission.
24 *
25 * This Software, including technical data, may be subject to U.S. export
26 * control laws, including the U.S. Export Administration Act and its
27 * associated regulations, and may be subject to export or import
28 * regulations in other countries.
29 *
30 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
31 * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
32 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT
33 * TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
34 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
35 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
36 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
37 * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT,
38 * QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK
39 * ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
40 ***********************license end**************************************/
41
42 /**
43 * This header defines all internal API for libdram. None
44 * of these functions should be called by users of the library.
45 * This is the only header that DRAM files should include
46 * from the libdram directory
47 */
48
49 /* FIXME(dhendrix): include path */
50 //#include "libdram.h"
51 #include <libdram/libdram.h>
52 #include "lib_octeon_shared.h"
53 #include "dram-print.h"
54 #include "dram-util.h"
55 #include "dram-csr.h"
56 #include "dram-env.h"
57 #include "dram-gpio.h"
58 #include "dram-spd.h"
59 #include "dram-l2c.h"
60 #include "dram-init-ddr3.h"
61
62 #undef DRAM_CSR_WRITE_INLINE
63
64 // define how many HW WL samples to take for majority voting
65 // MUST BE odd!!
66 // assume there should only be 2 possible values that will show up,
67 // so treat ties as a problem!!!
68 #define WLEVEL_LOOPS_DEFAULT 5 // NOTE: do not change this without checking the code!!!
69
70 // define how many HW RL samples per rank to take
71 // multiple samples will allow either:
72 // 1. looking for the best sample score
73 // 2. averaging the samples into a composite score
74 // symbol PICK_BEST_RANK_SCORE_NOT_AVG is used to choose
75 // (see dram-init-ddr3.c:
76 #define RLEVEL_AVG_LOOPS_DEFAULT 3
77 #define PICK_BEST_RANK_SCORE_NOT_AVG 1
78
79 typedef struct {
80 int delay;
81 int loop_total;
82 int loop_count;
83 int best;
84 uint64_t bm;
85 int bmerrs;
86 int sqerrs;
87 int bestsq;
88 } rlevel_byte_data_t;
89
90 typedef struct {
91 uint64_t bm;
92 uint8_t mstart;
93 uint8_t width;
94 int errs;
95 } rlevel_bitmask_t;
96
97 #define SET_DDR_DLL_CTL3(field, expr) \
98 do { \
99 ddr_dll_ctl3.cn81xx.field = (expr); \
100 } while (0)
101
102 #define ENCODE_DLL90_BYTE_SEL(byte_sel) ((byte_sel)+1)
103
104 #define GET_DDR_DLL_CTL3(field) \
105 (ddr_dll_ctl3.cn81xx.field)
106
107
108 #define RLEVEL_NONSEQUENTIAL_DELAY_ERROR 50
109 #define RLEVEL_ADJACENT_DELAY_ERROR 30
110
111 #define TWO_LMC_MASK 0x03
112 #define FOUR_LMC_MASK 0x0f
113 #define ONE_DIMM_MASK 0x01
114 #define TWO_DIMM_MASK 0x03
115
116 extern int initialize_ddr_clock(bdk_node_t node,
117 const ddr_configuration_t *ddr_configuration, uint32_t cpu_hertz,
118 uint32_t ddr_hertz, uint32_t ddr_ref_hertz, int ddr_interface_num,
119 uint32_t ddr_interface_mask);
120
121 extern int test_dram_byte(bdk_node_t node, int ddr_interface_num, uint64_t p,
122 uint64_t bitmask, uint64_t *xor_data);
123 extern int dram_tuning_mem_xor(bdk_node_t node, int ddr_interface_num, uint64_t p,
124 uint64_t bitmask, uint64_t *xor_data);
125
126 // "mode" arg
127 #define DBTRAIN_TEST 0
128 #define DBTRAIN_DBI 1
129 #define DBTRAIN_LFSR 2
130 extern int test_dram_byte_hw(bdk_node_t node, int ddr_interface_num,
131 uint64_t p, int mode, uint64_t *xor_data);
132 extern int run_best_hw_patterns(bdk_node_t node, int ddr_interface_num,
133 uint64_t p, int mode, uint64_t *xor_data);
134
135 extern int get_dimm_part_number(char *buffer, bdk_node_t node,
136 const dimm_config_t *dimm_config,
137 int ddr_type);
138 extern uint32_t get_dimm_serial_number(bdk_node_t node,
139 const dimm_config_t *dimm_config,
140 int ddr_type);
141
142 extern int octeon_ddr_initialize(bdk_node_t node, uint32_t cpu_hertz,
143 uint32_t ddr_hertz, uint32_t ddr_ref_hertz, uint32_t ddr_interface_mask,
144 const ddr_configuration_t *ddr_configuration, uint32_t *measured_ddr_hertz,
145 int board_type, int board_rev_maj, int board_rev_min);
146
147 extern uint64_t divide_nint(uint64_t dividend, uint64_t divisor);
148
149 typedef enum {
150 DDR3_DRAM = 3,
151 DDR4_DRAM = 4,
152 } ddr_type_t;
153
get_ddr_type(bdk_node_t node,const dimm_config_t * dimm_config)154 static inline int get_ddr_type(bdk_node_t node, const dimm_config_t *dimm_config)
155 {
156 int spd_ddr_type;
157
158 #define DEVICE_TYPE DDR4_SPD_KEY_BYTE_DEVICE_TYPE // same for DDR3 and DDR4
159 spd_ddr_type = read_spd(node, dimm_config, DEVICE_TYPE);
160
161 debug_print("%s:%d spd_ddr_type=0x%02x\n", __func__, __LINE__, spd_ddr_type);
162
163 /* we return only DDR4 or DDR3 */
164 return (spd_ddr_type == 0x0C) ? DDR4_DRAM : DDR3_DRAM;
165 }
166
get_dimm_ecc(bdk_node_t node,const dimm_config_t * dimm_config,int ddr_type)167 static inline int get_dimm_ecc(bdk_node_t node, const dimm_config_t *dimm_config, int ddr_type)
168 {
169 #define BUS_WIDTH(t) (((t) == DDR4_DRAM) ? DDR4_SPD_MODULE_MEMORY_BUS_WIDTH : DDR3_SPD_MEMORY_BUS_WIDTH)
170
171 return !!(read_spd(node, dimm_config, BUS_WIDTH(ddr_type)) & 8);
172 }
173
get_dimm_module_type(bdk_node_t node,const dimm_config_t * dimm_config,int ddr_type)174 static inline int get_dimm_module_type(bdk_node_t node, const dimm_config_t *dimm_config, int ddr_type)
175 {
176 #define MODULE_TYPE DDR4_SPD_KEY_BYTE_MODULE_TYPE // same for DDR3 and DDR4
177
178 return (read_spd(node, dimm_config, MODULE_TYPE) & 0x0F);
179 }
180
181 extern int common_ddr4_fixups(dram_config_t *cfg, uint32_t default_udimm_speed);
182
183 #define DEFAULT_BEST_RANK_SCORE 9999999
184 #define MAX_RANK_SCORE_LIMIT 99 // is this OK?
185
186 unsigned short load_dll_offset(bdk_node_t node, int ddr_interface_num,
187 int dll_offset_mode, int byte_offset, int byte);
188 void change_dll_offset_enable(bdk_node_t node, int ddr_interface_num, int change);
189
190 extern int perform_dll_offset_tuning(bdk_node_t node, int dll_offset_mode, int do_tune);
191 extern int perform_HW_dll_offset_tuning(bdk_node_t node, int dll_offset_mode, int bytelane);
192
193 extern int perform_margin_write_voltage(bdk_node_t node);
194 extern int perform_margin_read_voltage(bdk_node_t node);
195
196 #define LMC_DDR3_RESET_ASSERT 0
197 #define LMC_DDR3_RESET_DEASSERT 1
198 extern void cn88xx_lmc_ddr3_reset(bdk_node_t node, int ddr_interface_num, int reset);
199 extern void perform_lmc_reset(bdk_node_t node, int ddr_interface_num);
200 extern void ddr4_mrw(bdk_node_t node, int ddr_interface_num, int rank,
201 int mr_wr_addr, int mr_wr_sel, int mr_wr_bg1);
202 #endif /* __DRAM_INTERNAL_H__ */
203
204