File indexing completed on 2025-05-11 08:22:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <bsp.h>
0038 #include <bsp/ecc_priv.h>
0039 #include <bsp/irq.h>
0040 #include <bsp/utility.h>
0041 #include <rtems/rtems/intr.h>
0042
0043 static uintptr_t ddrc_base = 0xFD070000;
0044
0045
0046
0047
0048
0049 #define DDRC_ADDRMAP_4BIT_SPECIAL 15
0050 #define DDRC_ADDRMAP_5BIT_SPECIAL 31
0051
0052 #define DDRC_MSTR_OFFSET 0x0
0053 #define DDRC_MSTR_BURST_RDWR(val) BSP_FLD32(val, 16, 19)
0054 #define DDRC_MSTR_BURST_RDWR_GET(reg) BSP_FLD32GET(reg, 16, 19)
0055 #define DDRC_MSTR_BURST_RDWR_SET(reg, val) BSP_FLD32SET(reg, val, 16, 19)
0056 #define DDRC_MSTR_BURST_RDWR_4 0x2
0057 #define DDRC_MSTR_BURST_RDWR_8 0x4
0058 #define DDRC_MSTR_BURST_RDWR_16 0x8
0059 #define DDRC_MSTR_DATA_BUS_WIDTH(val) BSP_FLD32(val, 12, 13)
0060 #define DDRC_MSTR_DATA_BUS_WIDTH_GET(reg) BSP_FLD32GET(reg, 12, 13)
0061 #define DDRC_MSTR_DATA_BUS_WIDTH_SET(reg, val) BSP_FLD32SET(reg, val, 12, 13)
0062 #define DDRC_MSTR_DATA_BUS_WIDTH_FULL 0x0
0063 #define DDRC_MSTR_DATA_BUS_WIDTH_HALF 0x1
0064 #define DDRC_MSTR_DATA_BUS_WIDTH_QUARTER 0x2
0065 #define DDRC_MSTR_LPDDR4 BSP_BIT32(5)
0066 #define DDRC_MSTR_DDR4 BSP_BIT32(4)
0067 #define DDRC_MSTR_LPDDR3 BSP_BIT32(3)
0068 #define DDRC_MSTR_DDR3 BSP_BIT32(0)
0069
0070
0071 #define DDRC_ADDRMAP0_OFFSET 0x200
0072 #define DDRC_ADDRMAP0_RANK_B0_BASE 6
0073 #define DDRC_ADDRMAP0_RANK_B0_TARGET_BIT(bw, lp3) 0
0074 #define DDRC_ADDRMAP0_RANK_B0_TARGET rank
0075 #define DDRC_ADDRMAP0_RANK_B0_SPECIAL DDRC_ADDRMAP_5BIT_SPECIAL
0076 #define DDRC_ADDRMAP0_RANK_B0(val) BSP_FLD32(val, 0, 4)
0077 #define DDRC_ADDRMAP0_RANK_B0_GET(reg) BSP_FLD32GET(reg, 0, 4)
0078 #define DDRC_ADDRMAP0_RANK_B0_SET(reg, val) BSP_FLD32SET(reg, val, 0, 4)
0079
0080 #define DDRC_ADDRMAP1_OFFSET 0x204
0081 #define DDRC_ADDRMAP1_BANK_B2_BASE 4
0082 #define DDRC_ADDRMAP1_BANK_B2_TARGET_BIT(bw, lp3) 2
0083 #define DDRC_ADDRMAP1_BANK_B2_TARGET bank
0084 #define DDRC_ADDRMAP1_BANK_B2_SPECIAL DDRC_ADDRMAP_5BIT_SPECIAL
0085 #define DDRC_ADDRMAP1_BANK_B2(val) BSP_FLD32(val, 16, 20)
0086 #define DDRC_ADDRMAP1_BANK_B2_GET(reg) BSP_FLD32GET(reg, 16, 20)
0087 #define DDRC_ADDRMAP1_BANK_B2_SET(reg, val) BSP_FLD32SET(reg, val, 16, 20)
0088 #define DDRC_ADDRMAP1_BANK_B1_BASE 3
0089 #define DDRC_ADDRMAP1_BANK_B1_TARGET_BIT(bw, lp3) 1
0090 #define DDRC_ADDRMAP1_BANK_B1_TARGET bank
0091 #define DDRC_ADDRMAP1_BANK_B1_SPECIAL DDRC_ADDRMAP_5BIT_SPECIAL
0092 #define DDRC_ADDRMAP1_BANK_B1(val) BSP_FLD32(val, 8, 12)
0093 #define DDRC_ADDRMAP1_BANK_B1_GET(reg) BSP_FLD32GET(reg, 8, 12)
0094 #define DDRC_ADDRMAP1_BANK_B1_SET(reg, val) BSP_FLD32SET(reg, val, 8, 12)
0095 #define DDRC_ADDRMAP1_BANK_B0_BASE 2
0096 #define DDRC_ADDRMAP1_BANK_B0_TARGET_BIT(bw, lp3) 0
0097 #define DDRC_ADDRMAP1_BANK_B0_TARGET bank
0098 #define DDRC_ADDRMAP1_BANK_B0_SPECIAL DDRC_ADDRMAP_5BIT_SPECIAL
0099 #define DDRC_ADDRMAP1_BANK_B0(val) BSP_FLD32(val, 0, 4)
0100 #define DDRC_ADDRMAP1_BANK_B0_GET(reg) BSP_FLD32GET(reg, 0, 4)
0101 #define DDRC_ADDRMAP1_BANK_B0_SET(reg, val) BSP_FLD32SET(reg, val, 0, 4)
0102
0103 #define DDRC_ADDRMAP2_OFFSET 0x208
0104 #define DDRC_ADDRMAP2_COL_B5_BASE 5
0105 #define DDRC_ADDRMAP2_COL_B5_TARGET_BIT(bw, lp3) \
0106 ((bw == DDRC_MSTR_DATA_BUS_WIDTH_FULL) ? \
0107 5 : ((bw == DDRC_MSTR_DATA_BUS_WIDTH_HALF) ? 6 : 7))
0108 #define DDRC_ADDRMAP2_COL_B5_TARGET column
0109 #define DDRC_ADDRMAP2_COL_B5_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0110 #define DDRC_ADDRMAP2_COL_B5(val) BSP_FLD32(val, 24, 27)
0111 #define DDRC_ADDRMAP2_COL_B5_GET(reg) BSP_FLD32GET(reg, 24, 27)
0112 #define DDRC_ADDRMAP2_COL_B5_SET(reg, val) BSP_FLD32SET(reg, val, 24, 27)
0113 #define DDRC_ADDRMAP2_COL_B4_BASE 4
0114 #define DDRC_ADDRMAP2_COL_B4_TARGET_BIT(bw, lp3) \
0115 ((bw == DDRC_MSTR_DATA_BUS_WIDTH_FULL) ? \
0116 4 : ((bw == DDRC_MSTR_DATA_BUS_WIDTH_HALF) ? 5 : 6))
0117 #define DDRC_ADDRMAP2_COL_B4_TARGET column
0118 #define DDRC_ADDRMAP2_COL_B4_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0119 #define DDRC_ADDRMAP2_COL_B4(val) BSP_FLD32(val, 16, 19)
0120 #define DDRC_ADDRMAP2_COL_B4_GET(reg) BSP_FLD32GET(reg, 16, 19)
0121 #define DDRC_ADDRMAP2_COL_B4_SET(reg, val) BSP_FLD32SET(reg, val, 16, 19)
0122 #define DDRC_ADDRMAP2_COL_B3_BASE 3
0123 #define DDRC_ADDRMAP2_COL_B3_TARGET_BIT(bw, lp3) \
0124 ((bw == DDRC_MSTR_DATA_BUS_WIDTH_FULL) ? \
0125 3 : ((bw == DDRC_MSTR_DATA_BUS_WIDTH_HALF) ? 4 : 5 ))
0126 #define DDRC_ADDRMAP2_COL_B3_TARGET column
0127 #define DDRC_ADDRMAP2_COL_B3_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0128 #define DDRC_ADDRMAP2_COL_B3(val) BSP_FLD32(val, 8, 11)
0129 #define DDRC_ADDRMAP2_COL_B3_GET(reg) BSP_FLD32GET(reg, 8, 11)
0130 #define DDRC_ADDRMAP2_COL_B3_SET(reg, val) BSP_FLD32SET(reg, val, 8, 11)
0131 #define DDRC_ADDRMAP2_COL_B2_BASE 2
0132 #define DDRC_ADDRMAP2_COL_B2_TARGET_BIT(bw, lp3) \
0133 ((bw == DDRC_MSTR_DATA_BUS_WIDTH_FULL) ? \
0134 2 : ((bw == DDRC_MSTR_DATA_BUS_WIDTH_HALF) ? 3 : 4))
0135 #define DDRC_ADDRMAP2_COL_B2_TARGET column
0136 #define DDRC_ADDRMAP2_COL_B2_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0137 #define DDRC_ADDRMAP2_COL_B2(val) BSP_FLD32(val, 0, 3)
0138 #define DDRC_ADDRMAP2_COL_B2_GET(reg) BSP_FLD32GET(reg, 0, 3)
0139 #define DDRC_ADDRMAP2_COL_B2_SET(reg, val) BSP_FLD32SET(reg, val, 0, 3)
0140
0141 #define DDRC_ADDRMAP3_OFFSET 0x20c
0142 #define DDRC_ADDRMAP3_COL_B9_BASE 9
0143 static uint32_t map3_col_b9_target_bit(uint32_t bw, bool lp3)
0144 {
0145 if (bw == DDRC_MSTR_DATA_BUS_WIDTH_FULL) {
0146 return 9;
0147 }
0148
0149 if (bw == DDRC_MSTR_DATA_BUS_WIDTH_QUARTER) {
0150 return 13;
0151 }
0152
0153 if (lp3) {
0154 return 10;
0155 }
0156
0157 return 11;
0158 }
0159 #define DDRC_ADDRMAP3_COL_B9_TARGET_BIT(bw, lp3) \
0160 map3_col_b9_target_bit(bw, lp3)
0161 #define DDRC_ADDRMAP3_COL_B9_TARGET column
0162 #define DDRC_ADDRMAP3_COL_B9_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0163 #define DDRC_ADDRMAP3_COL_B9(val) BSP_FLD32(val, 24, 27)
0164 #define DDRC_ADDRMAP3_COL_B9_GET(reg) BSP_FLD32GET(reg, 24, 27)
0165 #define DDRC_ADDRMAP3_COL_B9_SET(reg, val) BSP_FLD32SET(reg, val, 24, 27)
0166 #define DDRC_ADDRMAP3_COL_B8_BASE 8
0167 #define DDRC_ADDRMAP3_COL_B8_TARGET_BIT(bw, lp3) \
0168 ((bw == DDRC_MSTR_DATA_BUS_WIDTH_FULL) ? \
0169 8 : ((bw == DDRC_MSTR_DATA_BUS_WIDTH_HALF) ? 9 : 11))
0170 #define DDRC_ADDRMAP3_COL_B8_TARGET column
0171 #define DDRC_ADDRMAP3_COL_B8_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0172 #define DDRC_ADDRMAP3_COL_B8(val) BSP_FLD32(val, 16, 19)
0173 #define DDRC_ADDRMAP3_COL_B8_GET(reg) BSP_FLD32GET(reg, 16, 19)
0174 #define DDRC_ADDRMAP3_COL_B8_SET(reg, val) BSP_FLD32SET(reg, val, 16, 19)
0175 #define DDRC_ADDRMAP3_COL_B7_BASE 7
0176 #define DDRC_ADDRMAP3_COL_B7_TARGET_BIT(bw, lp3) \
0177 ((bw == DDRC_MSTR_DATA_BUS_WIDTH_FULL) ? \
0178 7 : ((bw == DDRC_MSTR_DATA_BUS_WIDTH_HALF) ? 8 : 9))
0179 #define DDRC_ADDRMAP3_COL_B7_TARGET column
0180 #define DDRC_ADDRMAP3_COL_B7_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0181 #define DDRC_ADDRMAP3_COL_B7(val) BSP_FLD32(val, 8, 11)
0182 #define DDRC_ADDRMAP3_COL_B7_GET(reg) BSP_FLD32GET(reg, 8, 11)
0183 #define DDRC_ADDRMAP3_COL_B7_SET(reg, val) BSP_FLD32SET(reg, val, 8, 11)
0184 #define DDRC_ADDRMAP3_COL_B6_BASE 6
0185 #define DDRC_ADDRMAP3_COL_B6_TARGET_BIT(bw, lp3) \
0186 ((bw == DDRC_MSTR_DATA_BUS_WIDTH_FULL) ? \
0187 6 : ((bw == DDRC_MSTR_DATA_BUS_WIDTH_HALF) ? 7 : 8))
0188 #define DDRC_ADDRMAP3_COL_B6_TARGET column
0189 #define DDRC_ADDRMAP3_COL_B6_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0190 #define DDRC_ADDRMAP3_COL_B6(val) BSP_FLD32(val, 0, 3)
0191 #define DDRC_ADDRMAP3_COL_B6_GET(reg) BSP_FLD32GET(reg, 0, 3)
0192 #define DDRC_ADDRMAP3_COL_B6_SET(reg, val) BSP_FLD32SET(reg, val, 0, 3)
0193
0194 #define DDRC_ADDRMAP4_OFFSET 0x210
0195 #define DDRC_ADDRMAP4_COL_B11_BASE 11
0196 #define DDRC_ADDRMAP4_COL_B11_TARGET_BIT(bw, lp3) \
0197 (lp3?11:13)
0198 #define DDRC_ADDRMAP4_COL_B11_TARGET column
0199 #define DDRC_ADDRMAP4_COL_B11_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0200 #define DDRC_ADDRMAP4_COL_B11(val) BSP_FLD32(val, 8, 11)
0201 #define DDRC_ADDRMAP4_COL_B11_GET(reg) BSP_FLD32GET(reg, 8, 11)
0202 #define DDRC_ADDRMAP4_COL_B11_SET(reg, val) BSP_FLD32SET(reg, val, 8, 11)
0203 #define DDRC_ADDRMAP4_COL_B10_BASE 10
0204 static uint32_t map4_col_b10_target_bit(uint32_t bw, bool lp3)
0205 {
0206 if (bw == DDRC_MSTR_DATA_BUS_WIDTH_FULL) {
0207 if (lp3) {
0208 return 10;
0209 }
0210 return 11;
0211 }
0212
0213
0214 if (lp3) {
0215 return 11;
0216 }
0217
0218 return 13;
0219 }
0220 #define DDRC_ADDRMAP4_COL_B10_TARGET_BIT(bw, lp3) \
0221 map4_col_b10_target_bit(bw, lp3)
0222 #define DDRC_ADDRMAP4_COL_B10_TARGET column
0223 #define DDRC_ADDRMAP4_COL_B10_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0224 #define DDRC_ADDRMAP4_COL_B10(val) BSP_FLD32(val, 0, 3)
0225 #define DDRC_ADDRMAP4_COL_B10_GET(reg) BSP_FLD32GET(reg, 0, 3)
0226 #define DDRC_ADDRMAP4_COL_B10_SET(reg, val) BSP_FLD32SET(reg, val, 0, 3)
0227
0228 #define DDRC_ADDRMAP5_OFFSET 0x214
0229 #define DDRC_ADDRMAP5_ROW_B11_BASE 17
0230 #define DDRC_ADDRMAP5_ROW_B11_TARGET_BIT(bw, lp3) 11
0231 #define DDRC_ADDRMAP5_ROW_B11_TARGET row
0232 #define DDRC_ADDRMAP5_ROW_B11_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0233 #define DDRC_ADDRMAP5_ROW_B11(val) BSP_FLD32(val, 24, 27)
0234 #define DDRC_ADDRMAP5_ROW_B11_GET(reg) BSP_FLD32GET(reg, 24, 27)
0235 #define DDRC_ADDRMAP5_ROW_B11_SET(reg, val) BSP_FLD32SET(reg, val, 24, 27)
0236
0237 #define DDRC_ADDRMAP5_ROW_B2_10(val) BSP_FLD32(val, 16, 19)
0238 #define DDRC_ADDRMAP5_ROW_B2_10_GET(reg) BSP_FLD32GET(reg, 16, 19)
0239 #define DDRC_ADDRMAP5_ROW_B2_10_SET(reg, val) BSP_FLD32SET(reg, val, 16, 19)
0240 #define DDRC_ADDRMAP5_ROW_B1_BASE 7
0241 #define DDRC_ADDRMAP5_ROW_B1_TARGET_BIT(bw, lp3) 1
0242 #define DDRC_ADDRMAP5_ROW_B1_TARGET row
0243 #define DDRC_ADDRMAP5_ROW_B1_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0244 #define DDRC_ADDRMAP5_ROW_B1(val) BSP_FLD32(val, 8, 11)
0245 #define DDRC_ADDRMAP5_ROW_B1_GET(reg) BSP_FLD32GET(reg, 8, 11)
0246 #define DDRC_ADDRMAP5_ROW_B1_SET(reg, val) BSP_FLD32SET(reg, val, 8, 11)
0247 #define DDRC_ADDRMAP5_ROW_B0_BASE 6
0248 #define DDRC_ADDRMAP5_ROW_B0_TARGET_BIT(bw, lp3) 0
0249 #define DDRC_ADDRMAP5_ROW_B0_TARGET row
0250 #define DDRC_ADDRMAP5_ROW_B0_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0251 #define DDRC_ADDRMAP5_ROW_B0(val) BSP_FLD32(val, 0, 3)
0252 #define DDRC_ADDRMAP5_ROW_B0_GET(reg) BSP_FLD32GET(reg, 0, 3)
0253 #define DDRC_ADDRMAP5_ROW_B0_SET(reg, val) BSP_FLD32SET(reg, val, 0, 3)
0254
0255 #define DDRC_ADDRMAP6_OFFSET 0x218
0256 #define DDRC_ADDRMAP6_LPDDR3_6_12 BSP_BIT(bw, lp3)32(31)
0257 #define DDRC_ADDRMAP6_ROW_B15_BASE 21
0258 #define DDRC_ADDRMAP6_ROW_B15_TARGET_BIT(bw, lp3) 15
0259 #define DDRC_ADDRMAP6_ROW_B15_TARGET row
0260 #define DDRC_ADDRMAP6_ROW_B15_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0261 #define DDRC_ADDRMAP6_ROW_B15(val) BSP_FLD32(val, 24, 27)
0262 #define DDRC_ADDRMAP6_ROW_B15_GET(reg) BSP_FLD32GET(reg, 24, 27)
0263 #define DDRC_ADDRMAP6_ROW_B15_SET(reg, val) BSP_FLD32SET(reg, val, 24, 27)
0264 #define DDRC_ADDRMAP6_ROW_B14_BASE 20
0265 #define DDRC_ADDRMAP6_ROW_B14_TARGET_BIT(bw, lp3) 14
0266 #define DDRC_ADDRMAP6_ROW_B14_TARGET row
0267 #define DDRC_ADDRMAP6_ROW_B14_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0268 #define DDRC_ADDRMAP6_ROW_B14(val) BSP_FLD32(val, 16, 19)
0269 #define DDRC_ADDRMAP6_ROW_B14_GET(reg) BSP_FLD32GET(reg, 16, 19)
0270 #define DDRC_ADDRMAP6_ROW_B14_SET(reg, val) BSP_FLD32SET(reg, val, 16, 19)
0271 #define DDRC_ADDRMAP6_ROW_B13_BASE 19
0272 #define DDRC_ADDRMAP6_ROW_B13_TARGET_BIT(bw, lp3) 13
0273 #define DDRC_ADDRMAP6_ROW_B13_TARGET row
0274 #define DDRC_ADDRMAP6_ROW_B13_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0275 #define DDRC_ADDRMAP6_ROW_B13(val) BSP_FLD32(val, 8, 11)
0276 #define DDRC_ADDRMAP6_ROW_B13_GET(reg) BSP_FLD32GET(reg, 8, 11)
0277 #define DDRC_ADDRMAP6_ROW_B13_SET(reg, val) BSP_FLD32SET(reg, val, 8, 11)
0278 #define DDRC_ADDRMAP6_ROW_B12_BASE 18
0279 #define DDRC_ADDRMAP6_ROW_B12_TARGET_BIT(bw, lp3) 12
0280 #define DDRC_ADDRMAP6_ROW_B12_TARGET row
0281 #define DDRC_ADDRMAP6_ROW_B12_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0282 #define DDRC_ADDRMAP6_ROW_B12(val) BSP_FLD32(val, 0, 3)
0283 #define DDRC_ADDRMAP6_ROW_B12_GET(reg) BSP_FLD32GET(reg, 0, 3)
0284 #define DDRC_ADDRMAP6_ROW_B12_SET(reg, val) BSP_FLD32SET(reg, val, 0, 3)
0285
0286 #define DDRC_ADDRMAP7_OFFSET 0x21c
0287 #define DDRC_ADDRMAP7_ROW_B17_BASE 23
0288 #define DDRC_ADDRMAP7_ROW_B17_TARGET_BIT(bw, lp3) 17
0289 #define DDRC_ADDRMAP7_ROW_B17_TARGET row
0290 #define DDRC_ADDRMAP7_ROW_B17_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0291 #define DDRC_ADDRMAP7_ROW_B17(val) BSP_FLD32(val, 8, 11)
0292 #define DDRC_ADDRMAP7_ROW_B17_GET(reg) BSP_FLD32GET(reg, 8, 11)
0293 #define DDRC_ADDRMAP7_ROW_B17_SET(reg, val) BSP_FLD32SET(reg, val, 8, 11)
0294 #define DDRC_ADDRMAP7_ROW_B16_BASE 22
0295 #define DDRC_ADDRMAP7_ROW_B16_TARGET_BIT(bw, lp3) 16
0296 #define DDRC_ADDRMAP7_ROW_B16_TARGET row
0297 #define DDRC_ADDRMAP7_ROW_B16_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0298 #define DDRC_ADDRMAP7_ROW_B16(val) BSP_FLD32(val, 0, 3)
0299 #define DDRC_ADDRMAP7_ROW_B16_GET(reg) BSP_FLD32GET(reg, 0, 3)
0300 #define DDRC_ADDRMAP7_ROW_B16_SET(reg, val) BSP_FLD32SET(reg, val, 0, 3)
0301
0302 #define DDRC_ADDRMAP8_OFFSET 0x220
0303 #define DDRC_ADDRMAP8_BG_B1_BASE 3
0304 #define DDRC_ADDRMAP8_BG_B1_TARGET_BIT(bw, lp3) 1
0305 #define DDRC_ADDRMAP8_BG_B1_TARGET bank_group
0306 #define DDRC_ADDRMAP8_BG_B1_SPECIAL DDRC_ADDRMAP_5BIT_SPECIAL
0307 #define DDRC_ADDRMAP8_BG_B1(val) BSP_FLD32(val, 8, 12)
0308 #define DDRC_ADDRMAP8_BG_B1_GET(reg) BSP_FLD32GET(reg, 8, 12)
0309 #define DDRC_ADDRMAP8_BG_B1_SET(reg, val) BSP_FLD32SET(reg, val, 8, 12)
0310 #define DDRC_ADDRMAP8_BG_B0_BASE 2
0311 #define DDRC_ADDRMAP8_BG_B0_TARGET_BIT(bw, lp3) 0
0312 #define DDRC_ADDRMAP8_BG_B0_TARGET bank_group
0313 #define DDRC_ADDRMAP8_BG_B0_SPECIAL DDRC_ADDRMAP_5BIT_SPECIAL
0314 #define DDRC_ADDRMAP8_BG_B0(val) BSP_FLD32(val, 0, 4)
0315 #define DDRC_ADDRMAP8_BG_B0_GET(reg) BSP_FLD32GET(reg, 0, 4)
0316 #define DDRC_ADDRMAP8_BG_B0_SET(reg, val) BSP_FLD32SET(reg, val, 0, 4)
0317
0318 #define DDRC_ADDRMAP9_OFFSET 0x224
0319 #define DDRC_ADDRMAP9_ROW_B5_BASE 11
0320 #define DDRC_ADDRMAP9_ROW_B5_TARGET_BIT(bw, lp3) 5
0321 #define DDRC_ADDRMAP9_ROW_B5_TARGET row
0322 #define DDRC_ADDRMAP9_ROW_B5_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0323 #define DDRC_ADDRMAP9_ROW_B5(val) BSP_FLD32(val, 24, 27)
0324 #define DDRC_ADDRMAP9_ROW_B5_GET(reg) BSP_FLD32GET(reg, 24, 27)
0325 #define DDRC_ADDRMAP9_ROW_B5_SET(reg, val) BSP_FLD32SET(reg, val, 24, 27)
0326 #define DDRC_ADDRMAP9_ROW_B4_BASE 10
0327 #define DDRC_ADDRMAP9_ROW_B4_TARGET_BIT(bw, lp3) 4
0328 #define DDRC_ADDRMAP9_ROW_B4_TARGET row
0329 #define DDRC_ADDRMAP9_ROW_B4_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0330 #define DDRC_ADDRMAP9_ROW_B4(val) BSP_FLD32(val, 16, 19)
0331 #define DDRC_ADDRMAP9_ROW_B4_GET(reg) BSP_FLD32GET(reg, 16, 19)
0332 #define DDRC_ADDRMAP9_ROW_B4_SET(reg, val) BSP_FLD32SET(reg, val, 16, 19)
0333 #define DDRC_ADDRMAP9_ROW_B3_BASE 9
0334 #define DDRC_ADDRMAP9_ROW_B3_TARGET_BIT(bw, lp3) 3
0335 #define DDRC_ADDRMAP9_ROW_B3_TARGET row
0336 #define DDRC_ADDRMAP9_ROW_B3_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0337 #define DDRC_ADDRMAP9_ROW_B3(val) BSP_FLD32(val, 8, 11)
0338 #define DDRC_ADDRMAP9_ROW_B3_GET(reg) BSP_FLD32GET(reg, 8, 11)
0339 #define DDRC_ADDRMAP9_ROW_B3_SET(reg, val) BSP_FLD32SET(reg, val, 8, 11)
0340 #define DDRC_ADDRMAP9_ROW_B2_BASE 8
0341 #define DDRC_ADDRMAP9_ROW_B2_TARGET_BIT(bw, lp3) 2
0342 #define DDRC_ADDRMAP9_ROW_B2_TARGET row
0343 #define DDRC_ADDRMAP9_ROW_B2_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0344 #define DDRC_ADDRMAP9_ROW_B2(val) BSP_FLD32(val, 0, 3)
0345 #define DDRC_ADDRMAP9_ROW_B2_GET(reg) BSP_FLD32GET(reg, 0, 3)
0346 #define DDRC_ADDRMAP9_ROW_B2_SET(reg, val) BSP_FLD32SET(reg, val, 0, 3)
0347
0348 #define DDRC_ADDRMAP10_OFFSET 0x228
0349 #define DDRC_ADDRMAP10_ROW_B9_BASE 15
0350 #define DDRC_ADDRMAP10_ROW_B9_TARGET_BIT(bw, lp3) 9
0351 #define DDRC_ADDRMAP10_ROW_B9_TARGET row
0352 #define DDRC_ADDRMAP10_ROW_B9_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0353 #define DDRC_ADDRMAP10_ROW_B9(val) BSP_FLD32(val, 24, 27)
0354 #define DDRC_ADDRMAP10_ROW_B9_GET(reg) BSP_FLD32GET(reg, 24, 27)
0355 #define DDRC_ADDRMAP10_ROW_B9_SET(reg, val) BSP_FLD32SET(reg, val, 24, 27)
0356 #define DDRC_ADDRMAP10_ROW_B8_BASE 14
0357 #define DDRC_ADDRMAP10_ROW_B8_TARGET_BIT(bw, lp3) 8
0358 #define DDRC_ADDRMAP10_ROW_B8_TARGET row
0359 #define DDRC_ADDRMAP10_ROW_B8_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0360 #define DDRC_ADDRMAP10_ROW_B8(val) BSP_FLD32(val, 16, 19)
0361 #define DDRC_ADDRMAP10_ROW_B8_GET(reg) BSP_FLD32GET(reg, 16, 19)
0362 #define DDRC_ADDRMAP10_ROW_B8_SET(reg, val) BSP_FLD32SET(reg, val, 16, 19)
0363 #define DDRC_ADDRMAP10_ROW_B7_BASE 13
0364 #define DDRC_ADDRMAP10_ROW_B7_TARGET_BIT(bw, lp3) 7
0365 #define DDRC_ADDRMAP10_ROW_B7_TARGET row
0366 #define DDRC_ADDRMAP10_ROW_B7_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0367 #define DDRC_ADDRMAP10_ROW_B7(val) BSP_FLD32(val, 8, 11)
0368 #define DDRC_ADDRMAP10_ROW_B7_GET(reg) BSP_FLD32GET(reg, 8, 11)
0369 #define DDRC_ADDRMAP10_ROW_B7_SET(reg, val) BSP_FLD32SET(reg, val, 8, 11)
0370 #define DDRC_ADDRMAP10_ROW_B6_BASE 12
0371 #define DDRC_ADDRMAP10_ROW_B6_TARGET_BIT(bw, lp3) 6
0372 #define DDRC_ADDRMAP10_ROW_B6_TARGET row
0373 #define DDRC_ADDRMAP10_ROW_B6_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0374 #define DDRC_ADDRMAP10_ROW_B6(val) BSP_FLD32(val, 0, 3)
0375 #define DDRC_ADDRMAP10_ROW_B6_GET(reg) BSP_FLD32GET(reg, 0, 3)
0376 #define DDRC_ADDRMAP10_ROW_B6_SET(reg, val) BSP_FLD32SET(reg, val, 0, 3)
0377
0378 #define DDRC_ADDRMAP11_OFFSET 0x22c
0379 #define DDRC_ADDRMAP11_ROW_B10_BASE 16
0380 #define DDRC_ADDRMAP11_ROW_B10_TARGET_BIT(bw, lp3) 10
0381 #define DDRC_ADDRMAP11_ROW_B10_TARGET row
0382 #define DDRC_ADDRMAP11_ROW_B10_SPECIAL DDRC_ADDRMAP_4BIT_SPECIAL
0383 #define DDRC_ADDRMAP11_ROW_B10(val) BSP_FLD32(val, 0, 3)
0384 #define DDRC_ADDRMAP11_ROW_B10_GET(reg) BSP_FLD32GET(reg, 0, 3)
0385 #define DDRC_ADDRMAP11_ROW_B10_SET(reg, val) BSP_FLD32SET(reg, val, 0, 3)
0386
0387 #define DDRC_ECCPOISONADDR0_OFFSET 0xB8
0388 #define DDRC_ECCPOISONADDR0_RANK BSP_BIT32(24)
0389 #define DDRC_ECCPOISONADDR0_COL(val) BSP_FLD32(val, 0, 11)
0390 #define DDRC_ECCPOISONADDR0_COL_GET(reg) BSP_FLD32GET(reg, 0, 11)
0391 #define DDRC_ECCPOISONADDR0_COL_SET(reg, val) BSP_FLD32SET(reg, val, 0, 11)
0392
0393 #define DDRC_ECCPOISONADDR1_OFFSET 0xBC
0394 #define DDRC_ECCPOISONADDR1_BG(val) BSP_FLD32(val, 28, 29)
0395 #define DDRC_ECCPOISONADDR1_BG_GET(reg) BSP_FLD32GET(reg, 28, 29)
0396 #define DDRC_ECCPOISONADDR1_BG_SET(reg, val) BSP_FLD32SET(reg, val, 28, 29)
0397 #define DDRC_ECCPOISONADDR1_BANK(val) BSP_FLD32(val, 24, 26)
0398 #define DDRC_ECCPOISONADDR1_BANK_GET(reg) BSP_FLD32GET(reg, 24, 26)
0399 #define DDRC_ECCPOISONADDR1_BANK_SET(reg, val) BSP_FLD32SET(reg, val, 24, 26)
0400 #define DDRC_ECCPOISONADDR1_ROW(val) BSP_FLD32(val, 0, 17)
0401 #define DDRC_ECCPOISONADDR1_ROW_GET(reg) BSP_FLD32GET(reg, 0, 17)
0402 #define DDRC_ECCPOISONADDR1_ROW_SET(reg, val) BSP_FLD32SET(reg, val, 0, 17)
0403
0404 static void homogenize_row(
0405 uint32_t *addrmap5,
0406 uint32_t *addrmap9,
0407 uint32_t *addrmap10,
0408 uint32_t *addrmap11
0409 )
0410 {
0411 uint32_t b2_10 = DDRC_ADDRMAP5_ROW_B2_10_GET(*addrmap5);
0412 if (b2_10 == DDRC_ADDRMAP_4BIT_SPECIAL) {
0413
0414 return;
0415 }
0416
0417
0418 *addrmap9 = DDRC_ADDRMAP9_ROW_B5_SET(*addrmap9, b2_10);
0419 *addrmap9 = DDRC_ADDRMAP9_ROW_B4_SET(*addrmap9, b2_10);
0420 *addrmap9 = DDRC_ADDRMAP9_ROW_B3_SET(*addrmap9, b2_10);
0421 *addrmap9 = DDRC_ADDRMAP9_ROW_B2_SET(*addrmap9, b2_10);
0422
0423 *addrmap10 = DDRC_ADDRMAP10_ROW_B9_SET(*addrmap10, b2_10);
0424 *addrmap10 = DDRC_ADDRMAP10_ROW_B8_SET(*addrmap10, b2_10);
0425 *addrmap10 = DDRC_ADDRMAP10_ROW_B7_SET(*addrmap10, b2_10);
0426 *addrmap10 = DDRC_ADDRMAP10_ROW_B6_SET(*addrmap10, b2_10);
0427
0428 *addrmap11 = DDRC_ADDRMAP11_ROW_B10_SET(*addrmap11, b2_10);
0429 }
0430
0431 #define DDRC_READ(offset) (*(uint32_t *)(ddrc_base + offset))
0432
0433 #define DDRC_MAP_BIT(value, source, target) ((value >> source) & 0x1) << target
0434
0435 #define DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, BIT_ID, info, addrmap) \
0436 ({ \
0437 uint32_t mapbit = DDRC_ ## BIT_ID ## _GET(addrmap); \
0438 uint32_t target_bit = DDRC_ ## BIT_ID ## _TARGET_BIT(bus_width, lpddr3); \
0439 if (mapbit != DDRC_ ## BIT_ID ## _SPECIAL) { \
0440 mapbit += DDRC_ ## BIT_ID ## _BASE; \
0441 \
0442 mapbit += 3; \
0443 info->address |= \
0444 DDRC_MAP_BIT(info-> DDRC_ ## BIT_ID ## _TARGET, target_bit, mapbit); \
0445 } \
0446 })
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459 static int compose_address(DDR_Error_Info *info)
0460 {
0461 uint32_t addrmap0 = DDRC_READ(DDRC_ADDRMAP0_OFFSET);
0462 uint32_t addrmap1 = DDRC_READ(DDRC_ADDRMAP1_OFFSET);
0463 uint32_t addrmap2 = DDRC_READ(DDRC_ADDRMAP2_OFFSET);
0464 uint32_t addrmap3 = DDRC_READ(DDRC_ADDRMAP3_OFFSET);
0465 uint32_t addrmap4 = DDRC_READ(DDRC_ADDRMAP4_OFFSET);
0466 uint32_t addrmap5 = DDRC_READ(DDRC_ADDRMAP5_OFFSET);
0467 uint32_t addrmap6 = DDRC_READ(DDRC_ADDRMAP6_OFFSET);
0468 uint32_t addrmap7 = DDRC_READ(DDRC_ADDRMAP7_OFFSET);
0469 uint32_t addrmap8 = DDRC_READ(DDRC_ADDRMAP8_OFFSET);
0470 uint32_t addrmap9 = DDRC_READ(DDRC_ADDRMAP9_OFFSET);
0471 uint32_t addrmap10 = DDRC_READ(DDRC_ADDRMAP10_OFFSET);
0472 uint32_t addrmap11 = DDRC_READ(DDRC_ADDRMAP11_OFFSET);
0473 uint32_t mstr = DDRC_READ(DDRC_MSTR_OFFSET);
0474 uint32_t bus_width = DDRC_MSTR_DATA_BUS_WIDTH_GET(mstr);
0475 bool lpddr3 = mstr & DDRC_MSTR_LPDDR3;
0476
0477 homogenize_row(&addrmap5, &addrmap9, &addrmap10, &addrmap11);
0478
0479
0480 info->address = 0;
0481
0482 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP0_RANK_B0, info, addrmap0);
0483 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP1_BANK_B2, info, addrmap1);
0484 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP1_BANK_B1, info, addrmap1);
0485 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP1_BANK_B0, info, addrmap1);
0486 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP2_COL_B5, info, addrmap2);
0487 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP2_COL_B4, info, addrmap2);
0488 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP2_COL_B3, info, addrmap2);
0489 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP2_COL_B2, info, addrmap2);
0490 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP3_COL_B9, info, addrmap3);
0491 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP3_COL_B8, info, addrmap3);
0492 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP3_COL_B7, info, addrmap3);
0493 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP3_COL_B6, info, addrmap3);
0494 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP4_COL_B11, info, addrmap4);
0495 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP4_COL_B10, info, addrmap4);
0496 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP5_ROW_B11, info, addrmap5);
0497 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP5_ROW_B1, info, addrmap5);
0498 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP5_ROW_B0, info, addrmap5);
0499 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP6_ROW_B15, info, addrmap6);
0500 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP6_ROW_B14, info, addrmap6);
0501 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP6_ROW_B13, info, addrmap6);
0502 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP6_ROW_B12, info, addrmap6);
0503 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP7_ROW_B17, info, addrmap7);
0504 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP7_ROW_B16, info, addrmap7);
0505 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP8_BG_B1, info, addrmap8);
0506 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP8_BG_B0, info, addrmap8);
0507 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP9_ROW_B5, info, addrmap9);
0508 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP9_ROW_B4, info, addrmap9);
0509 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP9_ROW_B3, info, addrmap9);
0510 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP9_ROW_B2, info, addrmap9);
0511 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP10_ROW_B9, info, addrmap10);
0512 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP10_ROW_B8, info, addrmap10);
0513 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP10_ROW_B7, info, addrmap10);
0514 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP10_ROW_B6, info, addrmap10);
0515 DDRC_CHECK_AND_UNMAP(bus_width, lpddr3, ADDRMAP11_ROW_B10, info, addrmap11);
0516
0517
0518 info->address |= (info->column & 0x3) << 3;
0519 return 0;
0520 }
0521
0522 static uintptr_t ddr_qos_ctrl_base = 0xFD090000;
0523
0524 #define DDR_QIS_OFFSET 0x200
0525 #define DDR_QIE_OFFSET 0x208
0526 #define DDR_QID_OFFSET 0x20c
0527 #define DDR_QI_UNCRERR BSP_BIT32(2)
0528 #define DDR_QI_CORERR BSP_BIT32(1)
0529
0530 #define DDRC_ECCSTAT_OFFSET 0x78
0531 #define DDRC_ECCSTAT_UNCR_ERR(val) BSP_FLD32(val, 16, 19)
0532 #define DDRC_ECCSTAT_UNCR_ERR_GET(reg) BSP_FLD32GET(reg, 16, 19)
0533 #define DDRC_ECCSTAT_UNCR_ERR_SET(reg, val) BSP_FLD32SET(reg, val, 16, 19)
0534 #define DDRC_ECCSTAT_CORR_ERR(val) BSP_FLD32(val, 8, 11)
0535 #define DDRC_ECCSTAT_CORR_ERR_GET(reg) BSP_FLD32GET(reg, 8, 11)
0536 #define DDRC_ECCSTAT_CORR_ERR_SET(reg, val) BSP_FLD32SET(reg, val, 8, 11)
0537 #define DDRC_ECCSTAT_CORR_BIT(val) BSP_FLD32(val, 0, 6)
0538 #define DDRC_ECCSTAT_CORR_BIT_GET(reg) BSP_FLD32GET(reg, 0, 6)
0539 #define DDRC_ECCSTAT_CORR_BIT_SET(reg, val) BSP_FLD32SET(reg, val, 0, 6)
0540
0541
0542 #define DDRC_ECCCADDR0_OFFSET 0x84
0543 #define DDRC_ECCUADDR0_OFFSET 0xA4
0544 #define DDRC_ECCXADDR0_RANK BSP_BIT32(24)
0545 #define DDRC_ECCXADDR0_ROW(val) BSP_FLD32(val, 0, 17)
0546 #define DDRC_ECCXADDR0_ROW_GET(reg) BSP_FLD32GET(reg, 0, 17)
0547 #define DDRC_ECCXADDR0_ROW_SET(reg, val) BSP_FLD32SET(reg, val, 0, 17)
0548
0549 #define DDRC_ECCCADDR1_OFFSET 0x88
0550 #define DDRC_ECCUADDR1_OFFSET 0xA8
0551 #define DDRC_ECCXADDR1_BG(val) BSP_FLD32(val, 24, 25)
0552 #define DDRC_ECCXADDR1_BG_GET(reg) BSP_FLD32GET(reg, 24, 25)
0553 #define DDRC_ECCXADDR1_BG_SET(reg, val) BSP_FLD32SET(reg, val, 24, 25)
0554 #define DDRC_ECCXADDR1_BANK(val) BSP_FLD32(val, 16, 18)
0555 #define DDRC_ECCXADDR1_BANK_GET(reg) BSP_FLD32GET(reg, 16, 18)
0556 #define DDRC_ECCXADDR1_BANK_SET(reg, val) BSP_FLD32SET(reg, val, 16, 18)
0557 #define DDRC_ECCXADDR1_COL(val) BSP_FLD32(val, 0, 11)
0558 #define DDRC_ECCXADDR1_COL_GET(reg) BSP_FLD32GET(reg, 0, 11)
0559 #define DDRC_ECCXADDR1_COL_SET(reg, val) BSP_FLD32SET(reg, val, 0, 11)
0560
0561 static void extract_ddr_info(
0562 DDR_Error_Info *info,
0563 uint32_t addr0_val,
0564 uint32_t addr1_val
0565 )
0566 {
0567 info->rank = (addr0_val & DDRC_ECCXADDR0_RANK) >> 24;
0568 info->bank_group = DDRC_ECCXADDR1_BG_GET(addr1_val);
0569 info->bank = DDRC_ECCXADDR1_BANK_GET(addr1_val);
0570 info->row = DDRC_ECCXADDR0_ROW_GET(addr0_val);
0571 info->column = DDRC_ECCXADDR1_COL_GET(addr1_val);
0572 compose_address(info);
0573 }
0574
0575
0576 static void ddr_handler(void *arg)
0577 {
0578 (void) arg;
0579
0580 volatile uint32_t *qis = (uint32_t *)(ddr_qos_ctrl_base + DDR_QIS_OFFSET);
0581 uint32_t qis_value = *qis;
0582 DDR_Error_Info info;
0583 volatile uint32_t *addr0 = (uint32_t *)(ddrc_base + DDRC_ECCCADDR0_OFFSET);
0584 volatile uint32_t *addr1 = (uint32_t *)(ddrc_base + DDRC_ECCCADDR1_OFFSET);
0585
0586
0587 if ((qis_value & DDR_QI_CORERR) != 0) {
0588
0589 *qis = DDR_QI_CORERR;
0590
0591 info.type = DDR_CORRECTABLE;
0592 extract_ddr_info(&info, *addr0, *addr1);
0593 zynqmp_invoke_ecc_handler(DDR_RAM, &info);
0594 }
0595 if ((qis_value & DDR_QI_UNCRERR) != 0) {
0596
0597 *qis = DDR_QI_UNCRERR;
0598
0599 info.type = DDR_UNCORRECTABLE;
0600 extract_ddr_info(&info, *addr0, *addr1);
0601 zynqmp_invoke_ecc_handler(DDR_RAM, &info);
0602 }
0603 }
0604
0605 static rtems_interrupt_entry zynqmp_ddr_ecc_entry;
0606
0607 rtems_status_code zynqmp_configure_ddr_ecc( void )
0608 {
0609 volatile uint32_t *qie = (uint32_t *)(ddr_qos_ctrl_base + DDR_QIE_OFFSET);
0610 rtems_status_code sc;
0611
0612 rtems_interrupt_entry_initialize(
0613 &zynqmp_ddr_ecc_entry,
0614 ddr_handler,
0615 NULL,
0616 "DDR RAM ECC"
0617 );
0618
0619 sc = rtems_interrupt_entry_install(
0620 ZYNQMP_IRQ_DDR,
0621 RTEMS_INTERRUPT_SHARED,
0622 &zynqmp_ddr_ecc_entry
0623 );
0624
0625 if (sc != RTEMS_SUCCESSFUL) {
0626 return sc;
0627 }
0628
0629
0630 *qie |= DDR_QI_UNCRERR | DDR_QI_CORERR;
0631 return RTEMS_SUCCESSFUL;
0632 }
0633
0634 #if RUNNING_FROM_OCM_IS_NOT_CURRENTLY_POSSIBLE
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644 #define DDRC_PRINT_MAP(BIT_ID, addrmap) \
0645 ({ \
0646 uint32_t mapbit = DDRC_ ## BIT_ID ## _GET(addrmap); \
0647 if (mapbit != DDRC_ ## BIT_ID ## _SPECIAL) { \
0648 mapbit += DDRC_ ## BIT_ID ## _BASE; \
0649 } \
0650 })
0651
0652 static void print_addr_maps( void )
0653 {
0654 uint32_t addrmap0 = DDRC_READ(DDRC_ADDRMAP0_OFFSET);
0655 uint32_t addrmap1 = DDRC_READ(DDRC_ADDRMAP1_OFFSET);
0656 uint32_t addrmap2 = DDRC_READ(DDRC_ADDRMAP2_OFFSET);
0657 uint32_t addrmap3 = DDRC_READ(DDRC_ADDRMAP3_OFFSET);
0658 uint32_t addrmap4 = DDRC_READ(DDRC_ADDRMAP4_OFFSET);
0659 uint32_t addrmap5 = DDRC_READ(DDRC_ADDRMAP5_OFFSET);
0660 uint32_t addrmap6 = DDRC_READ(DDRC_ADDRMAP6_OFFSET);
0661 uint32_t addrmap7 = DDRC_READ(DDRC_ADDRMAP7_OFFSET);
0662 uint32_t addrmap8 = DDRC_READ(DDRC_ADDRMAP8_OFFSET);
0663 uint32_t addrmap9 = DDRC_READ(DDRC_ADDRMAP9_OFFSET);
0664 uint32_t addrmap10 = DDRC_READ(DDRC_ADDRMAP10_OFFSET);
0665 uint32_t addrmap11 = DDRC_READ(DDRC_ADDRMAP11_OFFSET);
0666
0667 homogenize_row(&addrmap5, &addrmap9, &addrmap10, &addrmap11);
0668
0669 DDRC_PRINT_MAP(ADDRMAP0_RANK_B0, addrmap0);
0670 DDRC_PRINT_MAP(ADDRMAP1_BANK_B2, addrmap1);
0671 DDRC_PRINT_MAP(ADDRMAP1_BANK_B1, addrmap1);
0672 DDRC_PRINT_MAP(ADDRMAP1_BANK_B0, addrmap1);
0673 DDRC_PRINT_MAP(ADDRMAP2_COL_B5, addrmap2);
0674 DDRC_PRINT_MAP(ADDRMAP2_COL_B4, addrmap2);
0675 DDRC_PRINT_MAP(ADDRMAP2_COL_B3, addrmap2);
0676 DDRC_PRINT_MAP(ADDRMAP2_COL_B2, addrmap2);
0677 DDRC_PRINT_MAP(ADDRMAP3_COL_B9, addrmap3);
0678 DDRC_PRINT_MAP(ADDRMAP3_COL_B8, addrmap3);
0679 DDRC_PRINT_MAP(ADDRMAP3_COL_B7, addrmap3);
0680 DDRC_PRINT_MAP(ADDRMAP3_COL_B6, addrmap3);
0681 DDRC_PRINT_MAP(ADDRMAP4_COL_B11, addrmap4);
0682 DDRC_PRINT_MAP(ADDRMAP4_COL_B10, addrmap4);
0683 DDRC_PRINT_MAP(ADDRMAP5_ROW_B11, addrmap5);
0684 DDRC_PRINT_MAP(ADDRMAP5_ROW_B1, addrmap5);
0685 DDRC_PRINT_MAP(ADDRMAP5_ROW_B0, addrmap5);
0686 DDRC_PRINT_MAP(ADDRMAP6_ROW_B15, addrmap6);
0687 DDRC_PRINT_MAP(ADDRMAP6_ROW_B14, addrmap6);
0688 DDRC_PRINT_MAP(ADDRMAP6_ROW_B13, addrmap6);
0689 DDRC_PRINT_MAP(ADDRMAP6_ROW_B12, addrmap6);
0690 DDRC_PRINT_MAP(ADDRMAP7_ROW_B17, addrmap7);
0691 DDRC_PRINT_MAP(ADDRMAP7_ROW_B16, addrmap7);
0692 DDRC_PRINT_MAP(ADDRMAP8_BG_B1, addrmap8);
0693 DDRC_PRINT_MAP(ADDRMAP8_BG_B0, addrmap8);
0694 DDRC_PRINT_MAP(ADDRMAP9_ROW_B5, addrmap9);
0695 DDRC_PRINT_MAP(ADDRMAP9_ROW_B4, addrmap9);
0696 DDRC_PRINT_MAP(ADDRMAP9_ROW_B3, addrmap9);
0697 DDRC_PRINT_MAP(ADDRMAP9_ROW_B2, addrmap9);
0698 DDRC_PRINT_MAP(ADDRMAP10_ROW_B9, addrmap10);
0699 DDRC_PRINT_MAP(ADDRMAP10_ROW_B8, addrmap10);
0700 DDRC_PRINT_MAP(ADDRMAP10_ROW_B7, addrmap10);
0701 DDRC_PRINT_MAP(ADDRMAP10_ROW_B6, addrmap10);
0702 DDRC_PRINT_MAP(ADDRMAP11_ROW_B10, addrmap11);
0703 }
0704
0705
0706 #define DDRC_CHECK_AND_MAP(bus_width, lpddr3, BIT_ID, info, addrmap) \
0707 ({ \
0708 uint32_t mapbit = DDRC_ ## BIT_ID ## _GET(addrmap); \
0709 uint32_t target_bit = DDRC_ ## BIT_ID ## _TARGET_BIT(bus_width, lpddr3); \
0710 if (mapbit != DDRC_ ## BIT_ID ## _SPECIAL) { \
0711 mapbit += DDRC_ ## BIT_ID ## _BASE; \
0712 \
0713 mapbit += 3; \
0714 info-> DDRC_ ## BIT_ID ## _TARGET |= \
0715 DDRC_MAP_BIT(info->address, mapbit, target_bit); \
0716 } \
0717 })
0718
0719 static int decompose_address(DDR_Error_Info *info)
0720 {
0721 uint32_t addrmap0 = DDRC_READ(DDRC_ADDRMAP0_OFFSET);
0722 uint32_t addrmap1 = DDRC_READ(DDRC_ADDRMAP1_OFFSET);
0723 uint32_t addrmap2 = DDRC_READ(DDRC_ADDRMAP2_OFFSET);
0724 uint32_t addrmap3 = DDRC_READ(DDRC_ADDRMAP3_OFFSET);
0725 uint32_t addrmap4 = DDRC_READ(DDRC_ADDRMAP4_OFFSET);
0726 uint32_t addrmap5 = DDRC_READ(DDRC_ADDRMAP5_OFFSET);
0727 uint32_t addrmap6 = DDRC_READ(DDRC_ADDRMAP6_OFFSET);
0728 uint32_t addrmap7 = DDRC_READ(DDRC_ADDRMAP7_OFFSET);
0729 uint32_t addrmap8 = DDRC_READ(DDRC_ADDRMAP8_OFFSET);
0730 uint32_t addrmap9 = DDRC_READ(DDRC_ADDRMAP9_OFFSET);
0731 uint32_t addrmap10 = DDRC_READ(DDRC_ADDRMAP10_OFFSET);
0732 uint32_t addrmap11 = DDRC_READ(DDRC_ADDRMAP11_OFFSET);
0733 uint32_t mstr = DDRC_READ(DDRC_MSTR_OFFSET);
0734 uint32_t bus_width = DDRC_MSTR_DATA_BUS_WIDTH_GET(mstr);
0735 bool lpddr3 = mstr & DDRC_MSTR_LPDDR3;
0736
0737 homogenize_row(&addrmap5, &addrmap9, &addrmap10, &addrmap11);
0738
0739
0740 info->rank = 0;
0741 info->bank_group = 0;
0742 info->bank = 0;
0743 info->row = 0;
0744 info->column = 0;
0745
0746 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP0_RANK_B0, info, addrmap0);
0747 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP1_BANK_B2, info, addrmap1);
0748 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP1_BANK_B1, info, addrmap1);
0749 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP1_BANK_B0, info, addrmap1);
0750 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP2_COL_B5, info, addrmap2);
0751 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP2_COL_B4, info, addrmap2);
0752 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP2_COL_B3, info, addrmap2);
0753 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP2_COL_B2, info, addrmap2);
0754 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP3_COL_B9, info, addrmap3);
0755 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP3_COL_B8, info, addrmap3);
0756 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP3_COL_B7, info, addrmap3);
0757 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP3_COL_B6, info, addrmap3);
0758 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP4_COL_B11, info, addrmap4);
0759 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP4_COL_B10, info, addrmap4);
0760 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP5_ROW_B11, info, addrmap5);
0761 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP5_ROW_B1, info, addrmap5);
0762 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP5_ROW_B0, info, addrmap5);
0763 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP6_ROW_B15, info, addrmap6);
0764 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP6_ROW_B14, info, addrmap6);
0765 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP6_ROW_B13, info, addrmap6);
0766 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP6_ROW_B12, info, addrmap6);
0767 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP7_ROW_B17, info, addrmap7);
0768 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP7_ROW_B16, info, addrmap7);
0769 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP8_BG_B1, info, addrmap8);
0770 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP8_BG_B0, info, addrmap8);
0771 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP9_ROW_B5, info, addrmap9);
0772 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP9_ROW_B4, info, addrmap9);
0773 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP9_ROW_B3, info, addrmap9);
0774 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP9_ROW_B2, info, addrmap9);
0775 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP10_ROW_B9, info, addrmap10);
0776 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP10_ROW_B8, info, addrmap10);
0777 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP10_ROW_B7, info, addrmap10);
0778 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP10_ROW_B6, info, addrmap10);
0779 DDRC_CHECK_AND_MAP(bus_width, lpddr3, ADDRMAP11_ROW_B10, info, addrmap11);
0780
0781
0782 info->column |= (info->address >> 3) & 0x3;
0783
0784
0785 uint32_t paddr0_val = DDRC_ECCPOISONADDR0_COL_SET(0, info->column);
0786 if (info->rank) {
0787 paddr0_val |= DDRC_ECCPOISONADDR0_RANK;
0788 }
0789
0790 uint32_t paddr1_val = DDRC_ECCPOISONADDR1_BG_SET(0, info->bank_group);
0791 paddr1_val = DDRC_ECCPOISONADDR1_BANK_SET(paddr1_val, info->bank);
0792 paddr1_val = DDRC_ECCPOISONADDR1_ROW_SET(paddr1_val, info->row);
0793 return 0;
0794 }
0795
0796
0797 #define DDRC_ECCCFG1_OFFSET 0x74
0798 #define DDRC_ECCCFG1_POISON_SINGLE BSP_BIT32(1)
0799 #define DDRC_ECCCFG1_POISON_EN BSP_BIT32(0)
0800
0801 #define DDRC_SWCTL_OFFSET 0x74
0802 #define DDRC_SWSTAT_OFFSET 0x324
0803
0804 #define DDRC_DBGCAM_OFFSET 0x308
0805 #define DDRC_DBGCAM_WR_DATA_PIPELINE_EMPTY BSP_BIT32(28)
0806 #define DDRC_DBGCAM_RD_DATA_PIPELINE_EMPTY BSP_BIT32(27)
0807 #define DDRC_DBGCAM_DBG_WR_Q_EMPTY BSP_BIT32(26)
0808 #define DDRC_DBGCAM_DBG_RD_Q_EMPTY BSP_BIT32(25)
0809
0810 #define DDRC_DBG1_OFFSET 0x304
0811 #define DDRC_DBG1_DIS_DQ BSP_BIT32(0)
0812
0813 static void set_ecccfg1(volatile uint32_t *ecccfg1, uint32_t ecccfg1_val)
0814 {
0815 uint32_t dbgcam_mask = DDRC_DBGCAM_WR_DATA_PIPELINE_EMPTY |
0816 DDRC_DBGCAM_RD_DATA_PIPELINE_EMPTY | DDRC_DBGCAM_DBG_WR_Q_EMPTY |
0817 DDRC_DBGCAM_DBG_RD_Q_EMPTY;
0818 volatile uint32_t *dbgcam = (uint32_t *)(ddrc_base + DDRC_DBGCAM_OFFSET);
0819 volatile uint32_t *dbg1 = (uint32_t *)(ddrc_base + DDRC_DBG1_OFFSET);
0820
0821
0822 *dbg1 |= DDRC_DBG1_DIS_DQ;
0823
0824 while((*dbgcam & dbgcam_mask) != dbgcam_mask);
0825 *ecccfg1 = ecccfg1_val;
0826
0827 *dbg1 &= ~DDRC_DBG1_DIS_DQ;
0828 }
0829
0830 void zynqmp_ddr_inject_fault( bool correctable )
0831 {
0832 uint64_t poison_var;
0833 uint64_t read_var;
0834 volatile uint64_t *poison_addr = &poison_var;
0835 volatile uint32_t *ecccfg1 = (uint32_t *)(ddrc_base + DDRC_ECCCFG1_OFFSET);
0836 uint32_t ecccfg1_val = 0;
0837 volatile uint32_t *swctl = (uint32_t *)(ddrc_base + DDRC_SWCTL_OFFSET);
0838 volatile uint32_t *swstat = (uint32_t *)(ddrc_base + DDRC_SWSTAT_OFFSET);
0839 volatile uint32_t *poisonaddr0;
0840 uint32_t paddr0_val;
0841 volatile uint32_t *poisonaddr1;
0842 uint32_t paddr1_val;
0843 DDR_Error_Info info;
0844 poisonaddr0 = (uint32_t *)(ddrc_base + DDRC_ECCPOISONADDR0_OFFSET);
0845 poisonaddr1 = (uint32_t *)(ddrc_base + DDRC_ECCPOISONADDR1_OFFSET);
0846
0847 info.address = (uint64_t)(uintptr_t)poison_addr;
0848
0849 decompose_address(&info);
0850
0851
0852 ecccfg1_val &= ~DDRC_ECCCFG1_POISON_SINGLE;
0853 if (correctable) {
0854 ecccfg1_val |= DDRC_ECCCFG1_POISON_SINGLE;
0855 }
0856
0857
0858 ecccfg1_val |= DDRC_ECCCFG1_POISON_EN;
0859
0860 uint32_t isr_cookie;
0861 rtems_interrupt_local_disable(isr_cookie);
0862
0863 *swctl = 0;
0864 set_ecccfg1(ecccfg1, ecccfg1_val);
0865 *swctl = 1;
0866 rtems_interrupt_local_enable(isr_cookie);
0867
0868
0869 while ((*swstat & 0x1) == 0);
0870
0871
0872 paddr0_val = DDRC_ECCPOISONADDR0_COL_SET(0, info.column);
0873 if (info.rank) {
0874 paddr0_val |= DDRC_ECCPOISONADDR0_RANK;
0875 }
0876 *poisonaddr0 = paddr0_val;
0877
0878 paddr1_val = DDRC_ECCPOISONADDR1_BG_SET(0, info.bank_group);
0879 paddr1_val = DDRC_ECCPOISONADDR1_BANK_SET(paddr1_val, info.bank);
0880 paddr1_val = DDRC_ECCPOISONADDR1_ROW_SET(paddr1_val, info.row);
0881 *poisonaddr1 = paddr1_val;
0882
0883
0884 *poison_addr = 0x5555555555555555UL;
0885
0886
0887 rtems_cache_flush_multiple_data_lines(poison_addr, sizeof(*poison_addr));
0888
0889
0890 rtems_cache_invalidate_multiple_data_lines(poison_addr, sizeof(*poison_addr));
0891
0892
0893 _AARCH64_Data_synchronization_barrier();
0894
0895
0896 read_var = *poison_addr;
0897 read_var++;
0898
0899 volatile uint32_t *qis = (uint32_t *)(ddr_qos_ctrl_base + DDR_QIS_OFFSET);
0900
0901
0902 *swctl = 0;
0903 *ecccfg1 = 0;
0904 *swctl = 1;
0905 }
0906 #endif