blob: 1b70faff7f763d8486ecb3d0318ab4bbae74159b [file] [log] [blame]
Marek Vasut1f7ba642024-12-12 14:34:30 +01001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2024 Renesas Electronics Corp.
4 */
5
6#include <asm/io.h>
7#include <dm.h>
8#include <errno.h>
9#include <hang.h>
10#include <ram.h>
11#include <linux/iopoll.h>
12#include <linux/sizes.h>
13#include "dbsc5.h"
14
15/* The number of channels V4H has */
16#define DRAM_CH_CNT 4
17/* The number of slices V4H has */
18#define SLICE_CNT 2
19/* The number of chip select V4H has */
20#define CS_CNT 2
21
22/* Number of array elements in Data Slice */
23#define DDR_PHY_SLICE_REGSET_SIZE_V4H 0x100
24/* Number of array elements in Data Slice */
25#define DDR_PHY_SLICE_REGSET_NUM_V4H 153
26/* Number of array elements in Address Slice */
27#define DDR_PHY_ADR_V_REGSET_NUM_V4H 61
28/* Number of array elements in Address Control Slice */
29#define DDR_PHY_ADR_G_REGSET_NUM_V4H 97
30/* Number of array elements in PI Register */
31#define DDR_PI_REGSET_NUM_V4H 1381
32
33/* Minimum value table for JS1 configuration table that can be taken */
34#define JS1_USABLEC_SPEC_LO 5
35/* Maximum value table for JS1 configuration table that can be taken */
36#define JS1_USABLEC_SPEC_HI 11
37/* The number of JS1 setting table */
38#define JS1_FREQ_TBL_NUM 12
39/* Macro to set the value of MR1 */
40#define JS1_MR1(f) (((f) << 4) | 0x00) /* CK mode = 0B */
41/* Macro to set the value of MR2 */
42#define JS1_MR2(f) (((f) << 4) | (f))
43
44#define JS2_tSR 0 /* Element for self refresh */
45#define JS2_tXP 1 /* Exit power-down mode to first valid command */
46#define JS2_tRCD 2 /* Active to read or write delay */
47#define JS2_tRPpb 3 /* Minimum Row Precharge Delay Time */
48#define JS2_tRPab 4 /* Minimum Row Precharge Delay Time */
49#define JS2_tRAS 5 /* ACTIVE-to-PRECHARGE command */
50#define JS2_tWTR_S 6 /* Internal WRITE-to-READ command delay */
51#define JS2_tWTR_L 7 /* Internal WRITE-to-READ command delay */
52#define JS2_tRRD 8 /* Active bank a to active bank b command */
53#define JS2_tPPD 9 /* Precharge Power Down */
54#define JS2_tFAW 10 /* Four bank ACT window */
55#define JS2_tMRR 11 /* Mode Register Read */
56#define JS2_tMRW 12 /* Mode Register Write */
57#define JS2_tMRD 13 /* LOAD MODE REGISTER command cycle time */
58#define JS2_tZQCALns 14 /* ZQ Calibration */
59#define JS2_tZQLAT 15 /* ZQ Latency */
60#define JS2_tODTon_min 16 /* Minimum time on die termination */
61#define JS2_tPDN_DSM 17 /* Recommended minimum time for Deep Sleep Mode duration */
62#define JS2_tXSR_DSM 18 /* Required time to be fully re-powered up from Deep Sleep Mode */
63#define JS2_tXDSM_XP 19 /* Delay from Deep Sleep Mode Exit to Power-Down Exit */
64#define JS2_tWCK2DQI_HF 20 /* Setting value of DQ to WCK input offset */
65#define JS2_tWCK2DQO_HF 21 /* Setting value of WCK to DQ output offset */
66#define JS2_tWCK2DQI_LF 22 /* Setting value of DQ to WCK input offset */
67#define JS2_tWCK2DQO_LF 23 /* Setting value of WCK to DQ output offset */
68#define JS2_tOSCODQI 24 /* Delay time from Stop WCK2DQI Interval Oscillator command to Mode Register Readout */
69#define JS2_tDQ72DQns 25 /* Reception time to change the value fof REF(CA) for Command Bus Training Mode2 */
70#define JS2_tCAENTns 26 /* Reception time to change the value fof REF(CA) for Command Bus Training Mode1 */
71#define JS2_tCSCAL 27 /* Minimum CA Low Duration time */
72#define JS2_TBLCNT 28 /* The number of table */
73
74#define JS2_tRCpb JS2_TBLCNT /* ACTIVATE-to-ACTIVATE command period with per bank precharge */
75#define JS2_tRCab (JS2_TBLCNT + 1) /* ACTIVATE-to-ACTIVATE command period with all bank precharge */
76#define JS2_tRFCab (JS2_TBLCNT + 2) /* Refresh Cycle Time with All Banks */
77#define JS2_tRBTP (JS2_TBLCNT + 3) /* READ Burst end to PRECHARGE command delay */
78#define JS2_tXSR (JS2_TBLCNT + 4) /* Exit Self Refresh to Valid commands */
79#define JS2_tPDN (JS2_TBLCNT + 5)
80#define JS2_tWLWCKOFF (JS2_TBLCNT + 6)
81#define JS2_CNT (JS2_TBLCNT + 7)
82
83struct jedec_spec1 {
84 u32 fx3; /* Frequency */
85 u8 RLset1; /* setting value of Read Latency */
86 u8 RLset2; /* setting value of Read Latency */
87 u8 WLsetA; /* setting value of Write Latency */
88 u8 WLsetB; /* setting value of Write Latency */
89 u32 nWR; /* Write-Recovery for Auto-Precharge commands */
90 u32 nRBTP; /* the minimum interval from a READ command to a PRE command */
91 u32 ODTLon; /* On Die Termination */
92 u8 MR1; /* Mode Register 1 */
93 u8 MR2; /* Mode Register 2 */
94 u32 WCKENLR; /* The setting time from CAS command to the Start-up of WCK in READ operation */
95 u32 WCKENLW; /* The setting time from CAS command to the Start-up of WCK in WRITE operation */
96 u32 WCKENLF; /* The setting time from CAS command to the Start-up of WCK in FAST-sync operation */
97 u32 WCKPRESTA; /* The setting time from the Start-up of WCK to WCK Clocling Start */
98 u32 WCKPRETGLR; /* The setting time from WCK Clocling Start to Reflecting frequency of WCK */
99};
100
101static const struct jedec_spec1 js1[JS1_FREQ_TBL_NUM] = {
102 /* fx3, RL1, RL2, WLA.WLB.nWR.nRBTP, ODTLon */
103 { 800, 3, 3, 2, 2, 3, 0, 1, JS1_MR1(0), JS1_MR2(0), 0, 0, 0, 1, 3 }, /* 533.333Mbps*/
104 { 1600, 4, 4, 2, 3, 5, 0, 1, JS1_MR1(1), JS1_MR2(1), 0, 0, 0, 1, 4 }, /* 1066.666Mbps*/
105 { 2400, 5, 6, 3, 4, 7, 0, 2, JS1_MR1(2), JS1_MR2(2), 1, 1, 1, 1, 4 }, /* 1600.000Mbps*/
106 { 3200, 7, 7, 4, 5, 10, 0, 2, JS1_MR1(3), JS1_MR2(3), 2, 1, 1, 2, 4 }, /* 2133.333Mbps*/
107 { 4000, 8, 9, 4, 7, 12, 1, 2, JS1_MR1(4), JS1_MR2(4), 2, 1, 1, 2, 5 }, /* 2666.666Mbps*/
108 { 4800, 10, 10, 5, 8, 14, 1, 3, JS1_MR1(5), JS1_MR2(5), 4, 2, 1, 2, 5 }, /* 3200.000Mbps*/
109 { 5600, 11, 12, 6, 9, 16, 2, 4, JS1_MR1(6), JS1_MR2(6), 4, 2, 1, 3, 5 }, /* 3733.333Mbps*/
110 { 6400, 13, 14, 6, 11, 19, 2, 3, JS1_MR1(7), JS1_MR2(7), 5, 2, 1, 3, 6 }, /* 4266.666Mbps*/
111 { 7200, 14, 15, 7, 12, 21, 3, 4, JS1_MR1(8), JS1_MR2(8), 6, 3, 2, 3, 6 }, /* 4800.000Mbps*/
112 { 8250, 16, 17, 8, 14, 24, 4, 5, JS1_MR1(9), JS1_MR2(9), 7, 3, 2, 4, 6 }, /* 5500.000Mbps*/
113 { 9000, 17, 19, 9, 15, 26, 4, 6, JS1_MR1(10), JS1_MR2(10), 7, 4, 2, 4, 7 }, /* 6000.000Mbps*/
114 { 9600, 18, 20, 9, 16, 28, 4, 6, JS1_MR1(11), JS1_MR2(11), 8, 4, 2, 4, 7 } /* 6400.000Mbps*/
115};
116
117struct jedec_spec2 {
118 u16 ps; /* Value in pico seconds */
119 u16 cyc; /* Value in cycle count */
120};
121
122static const struct jedec_spec2 jedec_spec2[2][JS2_TBLCNT] = {
123 {
124 { 15000, 2 }, /* tSR */
125 { 7000, 3 }, /* tXP */
126 { 18000, 2 }, /* tRCD */
127 { 18000, 2 }, /* tRPpb */
128 { 21000, 2 }, /* tRPab */
129 { 42000, 3 }, /* tRAS */
130 { 6250, 4 }, /* tWTR_S */
131 { 12000, 4 }, /* tWTR_L */
132 { 5000, 2 }, /* tRRD */
133 { 0, 2 }, /* tPPD */
134 { 20000, 0 }, /* tFAW */
135 { 0, 4 }, /* tMRR */
136 { 10000, 5 }, /* tMRW */
137 { 14000, 5 }, /* tMRD */
138 { 1500, 0 }, /* tZQCALns */
139 { 30000, 4 }, /* tZQLAT */
140 { 1500, 0 }, /* tODTon_min */
141 { 4000, 0 }, /* tPDN_DSMus */
142 { 200, 0 }, /* tXSR_DSMus */
143 { 190, 0 }, /* tXDSM_XPus */
144 { 700, 0 }, /* tWCK2DQI_HF */
145 { 1600, 0 }, /* tWCK2DQO_HF */
146 { 900, 0 }, /* tWCK2DQI_LF */
147 { 1900, 0 }, /* tWCK2DQO_LF */
148 { 40000, 8 }, /* tOSCODQI */
149 { 125, 0 }, /* tDQ72DQns */
150 { 250, 0 }, /* tCAENTns */
151 { 1750, 0 } /* tCSCAL */
152 }, {
153 { 15000, 2 }, /* tSR */
154 { 7000, 3 }, /* tXP */
155 { 19875, 2 }, /* tRCD */
156 { 19875, 2 }, /* tRPpb */
157 { 22875, 2 }, /* tRPab */
158 { 43875, 3 }, /* tRAS */
159 { 6250, 4 }, /* tWTR_S */
160 { 12000, 4 }, /* tWTR_L */
161 { 5000, 2 }, /* tRRD */
162 { 0, 2 }, /* tPPD */
163 { 20000, 0 }, /* tFAW */
164 { 0, 4 }, /* tMRR */
165 { 10000, 5 }, /* tMRW */
166 { 14000, 5 }, /* tMRD */
167 { 1500, 0 }, /* tZQCALns */
168 { 30000, 4 }, /* tZQLAT */
169 { 1500, 0 }, /* tODTon_min */
170 { 4000, 0 }, /* tPDN_DSMus */
171 { 200, 0 }, /* tXSR_DSMus */
172 { 190, 0 }, /* tXDSM_XPus */
173 { 715, 0 }, /* tWCK2DQI_HF */
174 { 1635, 0 }, /* tWCK2DQO_HF */
175 { 920, 0 }, /* tWCK2DQI_LF */
176 { 1940, 0 }, /* tWCK2DQO_LF */
177 { 40000, 8 }, /* tOSCODQI */
178 { 125, 0 }, /* tDQ72DQns */
179 { 250, 0 }, /* tCAENTns */
180 { 1750, 0 } /* tCSCAL */
181 }
182};
183
184static const u16 jedec_spec2_tRFC_ab[] = {
185 /* 2Gb, 3Gb, 4Gb, 6Gb, 8Gb, 12Gb, 16Gb, 24Gb, 32Gb */
186 130, 180, 180, 210, 210, 280, 280, 380, 380
187};
188
189/* The address offsets of PI Register */
190#define DDR_PI_REGSET_OFS_V4H 0x0800
191/* The address offsets of Data Slice */
192#define DDR_PHY_SLICE_REGSET_OFS_V4H 0x1000
193/* The address offsets of Address Slice */
194#define DDR_PHY_ADR_V_REGSET_OFS_V4H 0x1200
195/* The address offsets of Address Control Slice */
196#define DDR_PHY_ADR_G_REGSET_OFS_V4H 0x1300
197
198#define DDR_REGDEF_ADR(regdef) ((regdef) & 0xFFFF)
199#define DDR_REGDEF_LEN(regdef) (((regdef) >> 16) & 0xFF)
200#define DDR_REGDEF_LSB(regdef) (((regdef) >> 24) & 0xFF)
201
202#define DDR_REGDEF(lsb, len, adr) \
203 (((lsb) << 24) | ((len) << 16) | (adr))
204
205#define PHY_LP4_BOOT_RX_PCLK_CLK_SEL DDR_REGDEF(0x10, 0x03, 0x1000)
206#define PHY_PER_CS_TRAINING_MULTICAST_EN DDR_REGDEF(0x10, 0x01, 0x1006)
207#define PHY_PER_CS_TRAINING_INDEX DDR_REGDEF(0x18, 0x01, 0x1006)
208#define PHY_VREF_INITIAL_STEPSIZE DDR_REGDEF(0x18, 0x08, 0x100D)
209#define PHY_RDLVL_BEST_THRSHLD DDR_REGDEF(0x00, 0x04, 0x100E)
210#define PHY_RDLVL_VREF_OUTLIER DDR_REGDEF(0x10, 0x03, 0x100E)
211#define SC_PHY_WCK_CALC DDR_REGDEF(0x18, 0x01, 0x101A)
212#define PHY_RDLVL_RDDQS_DQ_OBS_SELECT DDR_REGDEF(0x10, 0x05, 0x102C)
213#define PHY_CALVL_VREF_DRIVING_SLICE DDR_REGDEF(0x18, 0x01, 0x1030)
214#define PHY_WRLVL_HARD0_DELAY_OBS DDR_REGDEF(0x00, 0x0A, 0x1038)
215#define PHY_WRLVL_HARD1_DELAY_OBS DDR_REGDEF(0x10, 0x0A, 0x1038)
216#define PHY_WRLVL_STATUS_OBS DDR_REGDEF(0x00, 0x1C, 0x1039)
217#define PHY_WRLVL_ERROR_OBS DDR_REGDEF(0x00, 0x10, 0x103B)
218#define PHY_GTLVL_STATUS_OBS DDR_REGDEF(0x00, 0x12, 0x103D)
219#define PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS DDR_REGDEF(0x10, 0x09, 0x103E)
220#define PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS DDR_REGDEF(0x00, 0x09, 0x103F)
221#define PHY_WDQLVL_STATUS_OBS DDR_REGDEF(0x00, 0x20, 0x1043)
222#define PHY_DATA_DC_CAL_START DDR_REGDEF(0x18, 0x01, 0x104D)
Marek Vasut021b08e2025-03-16 14:51:42 +0100223#define PHY_SLV_DLY_CTRL_GATE_DISABLE DDR_REGDEF(0x10, 0x01, 0x104E)
Marek Vasut1f7ba642024-12-12 14:34:30 +0100224#define PHY_REGULATOR_EN_CNT DDR_REGDEF(0x18, 0x06, 0x1050)
225#define PHY_VREF_INITIAL_START_POINT DDR_REGDEF(0x00, 0x09, 0x1055)
226#define PHY_VREF_INITIAL_STOP_POINT DDR_REGDEF(0x10, 0x09, 0x1055)
227#define PHY_VREF_TRAINING_CTRL DDR_REGDEF(0x00, 0x02, 0x1056)
228#define PHY_RDDQ0_SLAVE_DELAY DDR_REGDEF(0x00, 0x09, 0x105D)
229#define PHY_RDDQ1_SLAVE_DELAY DDR_REGDEF(0x10, 0x09, 0x105D)
230#define PHY_RDDQ2_SLAVE_DELAY DDR_REGDEF(0x00, 0x09, 0x105E)
231#define PHY_RDDQ3_SLAVE_DELAY DDR_REGDEF(0x10, 0x09, 0x105E)
232#define PHY_RDDQ4_SLAVE_DELAY DDR_REGDEF(0x00, 0x09, 0x105F)
233#define PHY_RDDQ5_SLAVE_DELAY DDR_REGDEF(0x10, 0x09, 0x105F)
234#define PHY_RDDQ6_SLAVE_DELAY DDR_REGDEF(0x00, 0x09, 0x1060)
235#define PHY_RDDQ7_SLAVE_DELAY DDR_REGDEF(0x10, 0x09, 0x1060)
236#define PHY_RDDM_SLAVE_DELAY DDR_REGDEF(0x00, 0x09, 0x1061)
237#define PHY_RX_CAL_ALL_DLY DDR_REGDEF(0x18, 0x06, 0x1061)
238#define PHY_RX_PCLK_CLK_SEL DDR_REGDEF(0x00, 0x03, 0x1062)
239#define PHY_DATA_DC_CAL_CLK_SEL DDR_REGDEF(0x18, 0x03, 0x1063)
240#define PHY_PAD_VREF_CTRL_DQ DDR_REGDEF(0x00, 0x0E, 0x1067)
241#define PHY_PER_CS_TRAINING_EN DDR_REGDEF(0x00, 0x01, 0x1068)
242#define PHY_RDDATA_EN_TSEL_DLY DDR_REGDEF(0x18, 0x05, 0x1069)
243#define PHY_RDDATA_EN_OE_DLY DDR_REGDEF(0x00, 0x05, 0x106A)
244#define PHY_RPTR_UPDATE DDR_REGDEF(0x10, 0x04, 0x106C)
245#define PHY_WRLVL_RESP_WAIT_CNT DDR_REGDEF(0x08, 0x06, 0x106D)
246#define PHY_RDLVL_DLY_STEP DDR_REGDEF(0x08, 0x04, 0x1070)
247#define PHY_RDLVL_MAX_EDGE DDR_REGDEF(0x00, 0x09, 0x1071)
248#define PHY_DATA_DC_WDQLVL_ENABLE DDR_REGDEF(0x08, 0x02, 0x1075)
249#define PHY_RDDATA_EN_DLY DDR_REGDEF(0x10, 0x05, 0x1076)
250#define PHY_MEAS_DLY_STEP_ENABLE DDR_REGDEF(0x08, 0x06, 0x1076)
251#define PHY_DQ_DM_SWIZZLE0 DDR_REGDEF(0x00, 0x20, 0x1077)
252#define PHY_DQ_DM_SWIZZLE1 DDR_REGDEF(0x00, 0x04, 0x1078)
253#define PHY_CLK_WRDQS_SLAVE_DELAY DDR_REGDEF(0x00, 0x09, 0x107E)
254#define PHY_WRITE_PATH_LAT_DEC DDR_REGDEF(0x10, 0x01, 0x107E)
255#define PHY_RDDQS_GATE_SLAVE_DELAY DDR_REGDEF(0x00, 0x09, 0x1088)
256#define PHY_RDDQS_LATENCY_ADJUST DDR_REGDEF(0x10, 0x05, 0x1088)
257#define PHY_WRITE_PATH_LAT_ADD DDR_REGDEF(0x18, 0x03, 0x1088)
258#define PHY_WRITE_PATH_LAT_FRAC DDR_REGDEF(0x00, 0x08, 0x1089)
259#define PHY_GTLVL_LAT_ADJ_START DDR_REGDEF(0x00, 0x05, 0x108A)
260#define PHY_DATA_DC_DQS_CLK_ADJUST DDR_REGDEF(0x00, 0x08, 0x108C)
261#define PHY_ADR_CALVL_SWIZZLE0 DDR_REGDEF(0x00, 0x20, 0x1202)
262#define PHY_ADR_MEAS_DLY_STEP_ENABLE DDR_REGDEF(0x10, 0x01, 0x1203)
263#define PHY_ADR_CALVL_RANK_CTRL DDR_REGDEF(0x18, 0x02, 0x1205)
264#define PHY_ADR_CALVL_OBS1 DDR_REGDEF(0x00, 0x20, 0x120A)
265#define PHY_ADR_CALVL_OBS2 DDR_REGDEF(0x00, 0x20, 0x120B)
266#define PHY_ADR_CALVL_DLY_STEP DDR_REGDEF(0x00, 0x04, 0x1210)
267#define PHY_CS_ACS_ALLOCATION_BIT2_2 DDR_REGDEF(0x08, 0x02, 0x1215)
268#define PHY_CS_ACS_ALLOCATION_BIT3_2 DDR_REGDEF(0x10, 0x02, 0x1215)
269#define PHY_CSLVL_OBS1 DDR_REGDEF(0x00, 0x20, 0x1221)
270#define PHY_CLK_DC_CAL_CLK_SEL DDR_REGDEF(0x08, 0x03, 0x123A)
271#define PHY_FREQ_SEL_MULTICAST_EN DDR_REGDEF(0x08, 0x01, 0x1301)
272#define PHY_FREQ_SEL_INDEX DDR_REGDEF(0x10, 0x02, 0x1301)
273#define SC_PHY_MANUAL_UPDATE DDR_REGDEF(0x18, 0x01, 0x1304)
274#define PHY_SET_DFI_INPUT_RST_PAD DDR_REGDEF(0x18, 0x01, 0x1311)
275#define PHY_CAL_MODE_0 DDR_REGDEF(0x00, 0x0D, 0x132C)
276#define PHY_CAL_INTERVAL_COUNT_0 DDR_REGDEF(0x00, 0x20, 0x132D)
277#define PHY_DATA_BYTE_ORDER_SEL DDR_REGDEF(0x00, 0x20, 0x133E)
278#define PHY_PAD_ACS_RX_PCLK_CLK_SEL DDR_REGDEF(0x10, 0x03, 0x1348)
279#define PHY_PLL_CTRL DDR_REGDEF(0x00, 0x0E, 0x134B)
280#define PHY_PLL_CTRL_8X DDR_REGDEF(0x10, 0x0E, 0x134B)
281#define PHY_CAL_CLK_SELECT_0 DDR_REGDEF(0x00, 0x03, 0x1360)
282
283#define PI_START DDR_REGDEF(0x00, 0x01, 0x0800)
284#define PI_TRAIN_ALL_FREQ_REQ DDR_REGDEF(0x18, 0x01, 0x0802)
285#define PI_CS_MAP DDR_REGDEF(0x08, 0x02, 0x0813)
286#define PI_WRLVL_REQ DDR_REGDEF(0x10, 0x01, 0x081C)
287#define PI_WRLVL_CS_SW DDR_REGDEF(0x18, 0x02, 0x081C)
288#define PI_RDLVL_REQ DDR_REGDEF(0x18, 0x01, 0x0824)
289#define PI_RDLVL_GATE_REQ DDR_REGDEF(0x00, 0x01, 0x0825)
290#define PI_RDLVL_CS_SW DDR_REGDEF(0x08, 0x02, 0x0825)
291#define PI_RDLVL_PERIODIC DDR_REGDEF(0x08, 0x01, 0x082E)
292#define PI_RDLVL_INTERVAL DDR_REGDEF(0x08, 0x10, 0x0835)
293#define PI_DRAMDCA_FLIP_MASK DDR_REGDEF(0x08, 0x02, 0x083B)
294#define PI_DRAMDCA_LVL_REQ DDR_REGDEF(0x10, 0x01, 0x083D)
295#define PI_DCMLVL_CS_SW DDR_REGDEF(0x18, 0x02, 0x083D)
296#define PI_WRDCM_LVL_EN_F1 DDR_REGDEF(0x00, 0x02, 0x083F)
297#define PI_DRAMDCA_LVL_EN_F1 DDR_REGDEF(0x08, 0x02, 0x083F)
298#define PI_WRDCM_LVL_EN_F2 DDR_REGDEF(0x18, 0x02, 0x083F)
299#define PI_DRAMDCA_LVL_EN_F2 DDR_REGDEF(0x00, 0x02, 0x0840)
300#define PI_DRAMDCA_LVL_ACTIVE_SEQ_2 DDR_REGDEF(0x00, 0x1B, 0x0868)
301#define PI_DRAMDCA_LVL_ACTIVE_SEQ_3 DDR_REGDEF(0x00, 0x1B, 0x0869)
302#define PI_DRAMDCA_LVL_ACTIVE_SEQ_4 DDR_REGDEF(0x00, 0x1B, 0x086A)
303#define PI_TCKCKEL_F2 DDR_REGDEF(0x18, 0x04, 0x089D)
304#define PI_WDQLVL_VREF_EN DDR_REGDEF(0x08, 0x04, 0x089E)
305#define PI_WDQLVL_PERIODIC DDR_REGDEF(0x00, 0x01, 0x08A0)
306#define PI_WDQLVL_INTERVAL DDR_REGDEF(0x00, 0x10, 0x08A4)
307#define PI_INT_STATUS DDR_REGDEF(0x00, 0x20, 0x0900)
308#define PI_INT_ACK_0 DDR_REGDEF(0x00, 0x20, 0x0902)
309#define PI_INT_ACK_1 DDR_REGDEF(0x00, 0x03, 0x0903)
310#define PI_LONG_COUNT_MASK DDR_REGDEF(0x10, 0x05, 0x090F)
311#define PI_ADDR_MUX_0 DDR_REGDEF(0x00, 0x03, 0x0910)
312#define PI_ADDR_MUX_1 DDR_REGDEF(0x08, 0x03, 0x0910)
313#define PI_ADDR_MUX_2 DDR_REGDEF(0x10, 0x03, 0x0910)
314#define PI_ADDR_MUX_3 DDR_REGDEF(0x18, 0x03, 0x0910)
315#define PI_ADDR_MUX_4 DDR_REGDEF(0x00, 0x03, 0x0911)
316#define PI_ADDR_MUX_5 DDR_REGDEF(0x08, 0x03, 0x0911)
317#define PI_ADDR_MUX_6 DDR_REGDEF(0x10, 0x03, 0x0911)
318#define PI_DATA_BYTE_SWAP_EN DDR_REGDEF(0x18, 0x01, 0x0911)
319#define PI_DATA_BYTE_SWAP_SLICE0 DDR_REGDEF(0x00, 0x01, 0x0912)
320#define PI_DATA_BYTE_SWAP_SLICE1 DDR_REGDEF(0x08, 0x01, 0x0912)
321#define PI_PWRUP_SREFRESH_EXIT DDR_REGDEF(0x18, 0x01, 0x093D)
322#define PI_PWRUP_SREFRESH_EXIT DDR_REGDEF(0x18, 0x01, 0x093D)
323#define PI_DLL_RST DDR_REGDEF(0x00, 0x01, 0x0941)
324#define PI_TDELAY_RDWR_2_BUS_IDLE_F2 DDR_REGDEF(0x00, 0x08, 0x0964)
325#define PI_WRLAT_F2 DDR_REGDEF(0x10, 0x07, 0x096A)
326#define PI_TWCKENL_WR_ADJ_F2 DDR_REGDEF(0x18, 0x06, 0x096A)
327#define PI_TWCKENL_RD_ADJ_F2 DDR_REGDEF(0x00, 0x06, 0x096B)
328#define PI_TWCKPRE_STATIC_F2 DDR_REGDEF(0x08, 0x06, 0x096B)
329#define PI_TWCKPRE_TOGGLE_RD_F2 DDR_REGDEF(0x18, 0x06, 0x096B)
330#define PI_TWCKENL_FS_ADJ_F2 DDR_REGDEF(0x00, 0x06, 0x096C)
331#define PI_CASLAT_F2 DDR_REGDEF(0x08, 0x07, 0x096C)
332#define PI_TRFC_F2 DDR_REGDEF(0x00, 0x0A, 0x0971)
333#define PI_TREF_F2 DDR_REGDEF(0x00, 0x14, 0x0972)
334#define PI_TDFI_WRLVL_WW_F0 DDR_REGDEF(0x00, 0x0A, 0x0974)
335#define PI_TDFI_WRLVL_WW_F1 DDR_REGDEF(0x00, 0x0A, 0x0975)
336#define PI_WRLVL_EN_F2 DDR_REGDEF(0x18, 0x02, 0x0975)
337#define PI_TDFI_WRLVL_WW_F2 DDR_REGDEF(0x00, 0x0A, 0x0976)
338#define PI_WRLVL_WCKOFF_F2 DDR_REGDEF(0x10, 0x08, 0x0976)
339#define PI_RDLVL_EN_F2 DDR_REGDEF(0x18, 0x02, 0x097A)
340#define PI_RDLVL_GATE_EN_F2 DDR_REGDEF(0x00, 0x02, 0x097B)
341#define PI_RDLVL_VREF_EN_F0 DDR_REGDEF(0x10, 0x04, 0x097B)
342#define PI_RDLVL_VREF_EN_F1 DDR_REGDEF(0x00, 0x04, 0x097D)
343#define PI_RDLVL_VREF_EN_F2 DDR_REGDEF(0x10, 0x04, 0x097E)
344#define PI_RDLAT_ADJ_F2 DDR_REGDEF(0x00, 0x09, 0x0981)
345#define PI_WRLAT_ADJ_F2 DDR_REGDEF(0x00, 0x07, 0x0982)
346#define PI_TDFI_CALVL_CC_F2 DDR_REGDEF(0x00, 0x0A, 0x0985)
347#define PI_TDFI_CALVL_CAPTURE_F2 DDR_REGDEF(0x10, 0x0A, 0x0985)
348#define PI_CALVL_EN_F2 DDR_REGDEF(0x10, 0x02, 0x0986)
349#define PI_TCAENT_F2 DDR_REGDEF(0x00, 0x0E, 0x0989)
350#define PI_TVREF_SHORT_F2 DDR_REGDEF(0x00, 0x0A, 0x098F)
351#define PI_TVREF_LONG_F2 DDR_REGDEF(0x10, 0x0A, 0x098F)
352#define PI_TVRCG_ENABLE_F2 DDR_REGDEF(0x00, 0x0A, 0x0990)
353#define PI_TVRCG_DISABLE_F2 DDR_REGDEF(0x10, 0x0A, 0x0990)
354#define PI_CALVL_VREF_INITIAL_START_POINT_F0 DDR_REGDEF(0x00, 0x07, 0x0991)
355#define PI_CALVL_VREF_INITIAL_STOP_POINT_F0 DDR_REGDEF(0x08, 0x07, 0x0991)
356#define PI_CALVL_VREF_INITIAL_START_POINT_F1 DDR_REGDEF(0x18, 0x07, 0x0991)
357#define PI_CALVL_VREF_INITIAL_STOP_POINT_F1 DDR_REGDEF(0x00, 0x07, 0x0992)
358#define PI_CALVL_VREF_INITIAL_START_POINT_F2 DDR_REGDEF(0x10, 0x07, 0x0992)
359#define PI_CALVL_VREF_INITIAL_STOP_POINT_F2 DDR_REGDEF(0x18, 0x07, 0x0992)
360#define PI_TDFI_CALVL_STROBE_F2 DDR_REGDEF(0x08, 0x04, 0x0995)
361#define PI_TXP_F2 DDR_REGDEF(0x10, 0x05, 0x0995)
362#define PI_TMRWCKEL_F2 DDR_REGDEF(0x18, 0x08, 0x0995)
363#define PI_TCKEHDQS_F2 DDR_REGDEF(0x10, 0x06, 0x099D)
364#define PI_TFC_F2 DDR_REGDEF(0x00, 0x0A, 0x099E)
365#define PI_WDQLVL_VREF_INITIAL_START_POINT_F0 DDR_REGDEF(0x10, 0x07, 0x09A0)
366#define PI_WDQLVL_VREF_INITIAL_STOP_POINT_F0 DDR_REGDEF(0x18, 0x07, 0x09A0)
367#define PI_WDQLVL_VREF_INITIAL_START_POINT_F1 DDR_REGDEF(0x00, 0x07, 0x09A4)
368#define PI_WDQLVL_VREF_INITIAL_STOP_POINT_F1 DDR_REGDEF(0x08, 0x07, 0x09A4)
369#define PI_TDFI_WDQLVL_WR_F2 DDR_REGDEF(0x00, 0x0A, 0x09A6)
370#define PI_TDFI_WDQLVL_RW_F2 DDR_REGDEF(0x10, 0x0A, 0x09A6)
371#define PI_WDQLVL_VREF_INITIAL_START_POINT_F2 DDR_REGDEF(0x00, 0x07, 0x09A7)
372#define PI_WDQLVL_VREF_INITIAL_STOP_POINT_F2 DDR_REGDEF(0x08, 0x07, 0x09A7)
373#define PI_WDQLVL_EN_F2 DDR_REGDEF(0x18, 0x02, 0x09A7)
374#define PI_MBIST_RDLAT_ADJ_F2 DDR_REGDEF(0x08, 0x09, 0x09A8)
375#define PI_MBIST_TWCKENL_RD_ADJ_F2 DDR_REGDEF(0x18, 0x06, 0x09A8)
376#define PI_TRTP_F2 DDR_REGDEF(0x18, 0x08, 0x09B3)
377#define PI_TRP_F2 DDR_REGDEF(0x00, 0x08, 0x09B4)
378#define PI_TRCD_F2 DDR_REGDEF(0x08, 0x08, 0x09B4)
379#define PI_TWTR_S_F2 DDR_REGDEF(0x18, 0x06, 0x09B4)
380#define PI_TWTR_L_F2 DDR_REGDEF(0x00, 0x06, 0x09B5)
381#define PI_TWTR_F2 DDR_REGDEF(0x10, 0x06, 0x09B5)
382#define PI_TWR_F2 DDR_REGDEF(0x18, 0x08, 0x09B5)
383#define PI_TRAS_MIN_F2 DDR_REGDEF(0x10, 0x09, 0x09B6)
384#define PI_TDQSCK_MAX_F2 DDR_REGDEF(0x00, 0x04, 0x09B7)
385#define PI_TSR_F2 DDR_REGDEF(0x10, 0x08, 0x09B7)
386#define PI_TMRD_F2 DDR_REGDEF(0x18, 0x08, 0x09B7)
387#define PI_TDFI_CTRLUPD_MAX_F2 DDR_REGDEF(0x00, 0x15, 0x09BC)
388#define PI_TDFI_CTRLUPD_INTERVAL_F2 DDR_REGDEF(0x00, 0x20, 0x09BD)
389#define PI_TINIT_F2 DDR_REGDEF(0x00, 0x18, 0x09CC)
390#define PI_TINIT1_F2 DDR_REGDEF(0x00, 0x18, 0x09CD)
391#define PI_TINIT3_F2 DDR_REGDEF(0x00, 0x18, 0x09CE)
392#define PI_TINIT4_F2 DDR_REGDEF(0x00, 0x18, 0x09CF)
393#define PI_TINIT5_F2 DDR_REGDEF(0x00, 0x18, 0x09D0)
394#define PI_TXSNR_F2 DDR_REGDEF(0x00, 0x10, 0x09D1)
395#define PI_TZQCAL_F2 DDR_REGDEF(0x10, 0x0C, 0x09D6)
396#define PI_TZQLAT_F2 DDR_REGDEF(0x00, 0x07, 0x09D7)
397#define PI_ZQRESET_F2 DDR_REGDEF(0x10, 0x0C, 0x09D8)
398#define PI_TDQ72DQ_F2 DDR_REGDEF(0x10, 0x0A, 0x09DD)
399#define PI_TCBTRTW_F2 DDR_REGDEF(0x00, 0x06, 0x09DE)
400#define PI_MC_TRFC_F2 DDR_REGDEF(0x00, 0x0A, 0x09E1)
401#define PI_CKE_MUX_0 DDR_REGDEF(0x00, 0x03, 0x09E6)
402#define PI_CKE_MUX_1 DDR_REGDEF(0x08, 0x03, 0x09E6)
403#define PI_SEQ_DEC_SW_CS DDR_REGDEF(0x00, 0x02, 0x0A4E)
404#define PI_SW_SEQ_START DDR_REGDEF(0x10, 0x01, 0x0A4E)
405#define PI_SW_SEQ_0 DDR_REGDEF(0x00, 0x1B, 0x0BF1)
406#define PI_SW_SEQ_1 DDR_REGDEF(0x00, 0x1B, 0x0BF2)
407#define PI_DFS_ENTRY_SEQ_0 DDR_REGDEF(0x00, 0x1D, 0x0BFB)
408#define PI_DFS_INITIALIZATION_SEQ_1 DDR_REGDEF(0x00, 0x1D, 0x0C24)
409#define PI_DFS_INITIALIZATION_SEQ_9 DDR_REGDEF(0x00, 0x1D, 0x0C2C)
410#define PI_DFS_INITIALIZATION_SEQ_10 DDR_REGDEF(0x00, 0x1D, 0x0C2D)
411#define PI_RDLVL_TRAIN_SEQ_1 DDR_REGDEF(0x00, 0x1B, 0x0C42)
412#define PI_RDLVL_TRAIN_SEQ_2 DDR_REGDEF(0x00, 0x1B, 0x0C43)
413#define PI_RDLVL_TRAIN_SEQ_3 DDR_REGDEF(0x00, 0x1B, 0x0C44)
414#define PI_RDLVL_TRAIN_SEQ_4 DDR_REGDEF(0x00, 0x1B, 0x0C45)
415#define PI_RDLVL_TRAIN_SEQ_5 DDR_REGDEF(0x00, 0x1B, 0x0C46)
416#define PI_SEQ_WAIT_16_F2 DDR_REGDEF(0x00, 0x18, 0x0C77)
417#define PI_SEQ_WAIT_17_F2 DDR_REGDEF(0x00, 0x18, 0x0C7A)
418#define PI_SEQ_WAIT_18_F2 DDR_REGDEF(0x00, 0x18, 0x0C7D)
419#define PI_SEQ_WAIT_19_F2 DDR_REGDEF(0x00, 0x18, 0x0C80)
420#define PI_SEQ_WAIT_20_F2 DDR_REGDEF(0x00, 0x18, 0x0C83)
421#define PI_SEQ_WAIT_21_F2 DDR_REGDEF(0x00, 0x18, 0x0C86)
422#define PI_SEQ_WAIT_22_F2 DDR_REGDEF(0x00, 0x18, 0x0C89)
423#define PI_SEQ_WAIT_23_F2 DDR_REGDEF(0x00, 0x18, 0x0C8C)
424#define PI_SEQ_WAIT_24_F2 DDR_REGDEF(0x00, 0x18, 0x0C8F)
425#define PI_SEQ_WAIT_25_F2 DDR_REGDEF(0x00, 0x18, 0x0C92)
426#define PI_SEQ_WAIT_26_F2 DDR_REGDEF(0x00, 0x18, 0x0C95)
427#define PI_SEQ_WAIT_30_F2 DDR_REGDEF(0x00, 0x18, 0x0CA1)
428#define PI_DARRAY3_0_CS0_F0 DDR_REGDEF(0x00, 0x08, 0x0D0B)
429#define PI_DARRAY3_1_CS0_F0 DDR_REGDEF(0x08, 0x08, 0x0D0B)
430#define PI_DARRAY3_0_CS0_F1 DDR_REGDEF(0x00, 0x08, 0x0D15)
431#define PI_DARRAY3_1_CS0_F1 DDR_REGDEF(0x08, 0x08, 0x0D15)
432#define PI_DARRAY3_0_CS0_F2 DDR_REGDEF(0x00, 0x08, 0x0D1F)
433#define PI_DARRAY3_1_CS0_F2 DDR_REGDEF(0x08, 0x08, 0x0D1F)
434#define PI_DARRAY3_4_CS0_F2 DDR_REGDEF(0x00, 0x08, 0x0D20)
435#define PI_DARRAY3_20_CS0_F2 DDR_REGDEF(0x00, 0x08, 0x0D24)
436#define PI_DARRAY3_0_CS1_F0 DDR_REGDEF(0x00, 0x08, 0x0D29)
437#define PI_DARRAY3_1_CS1_F0 DDR_REGDEF(0x08, 0x08, 0x0D29)
438#define PI_DARRAY3_0_CS1_F1 DDR_REGDEF(0x00, 0x08, 0x0D33)
439#define PI_DARRAY3_1_CS1_F1 DDR_REGDEF(0x08, 0x08, 0x0D33)
440#define PI_DARRAY3_0_CS1_F2 DDR_REGDEF(0x00, 0x08, 0x0D3D)
441#define PI_DARRAY3_1_CS1_F2 DDR_REGDEF(0x08, 0x08, 0x0D3D)
442#define PI_DARRAY3_4_CS1_F2 DDR_REGDEF(0x00, 0x08, 0x0D3E)
443#define PI_DARRAY3_20_CS1_F2 DDR_REGDEF(0x00, 0x08, 0x0D42)
444
445/* The setting table of Data Slice for V4H */
446static const u32 DDR_PHY_SLICE_REGSET_V4H[DDR_PHY_SLICE_REGSET_NUM_V4H] = {
447 0x30020370, 0x00000000, 0x01000002, 0x00000000,
448 0x00000000, 0x00000000, 0x00010300, 0x04000100,
449 0x00010000, 0x01000000, 0x00000000, 0x00000000,
450 0x00010000, 0x08010000, 0x00022003, 0x00000000,
451 0x040F0100, 0x1404034F, 0x04040102, 0x04040404,
452 0x00000100, 0x00000000, 0x00000000, 0x000800C0,
453 0x000F18FF, 0x00000000, 0x00000001, 0x00070000,
454 0x0000AAAA, 0x00005555, 0x0000B5B5, 0x00004A4A,
455 0x00005656, 0x0000A9A9, 0x0000A9A9, 0x0000B5B5,
456 0x00000000, 0xBFBF0000, 0xCCCCF7F7, 0x00000000,
457 0x00000000, 0x00000000, 0x00080815, 0x08040000,
458 0x00000004, 0x00103000, 0x000C0040, 0x00200200,
459 0x01010000, 0x00000000, 0x00000000, 0x00000000,
460 0x00000000, 0x00000000, 0x00000000, 0x00000000,
461 0x00000000, 0x00000000, 0x00000000, 0x00000000,
462 0x00000000, 0x00000000, 0x00000020, 0x00000000,
463 0x00000000, 0x00000000, 0x00000000, 0x00000000,
464 0x00000000, 0x00000000, 0x00000000, 0x00000000,
465 0x00000000, 0x00000004, 0x001F07FF, 0x08000303,
466 0x10200080, 0x00000006, 0x00000401, 0x00000000,
467 0x20CEC201, 0x00000001, 0x00017706, 0x01007706,
468 0x00000000, 0x008D006D, 0x00100001, 0x03FF0100,
469 0x00006E01, 0x00000301, 0x00000000, 0x00000000,
470 0x00000000, 0x00500050, 0x00500050, 0x00500050,
471 0x00500050, 0x0D000050, 0x10100004, 0x06102010,
472 0x61619041, 0x07097000, 0x00644180, 0x00803280,
Marek Vasut021b08e2025-03-16 14:51:42 +0100473 0x00808001, 0x13010101, 0x02000016, 0x10001003,
Marek Vasut1f7ba642024-12-12 14:34:30 +0100474 0x06093E42, 0x0F063D01, 0x011700C8, 0x04100140,
475 0x00000100, 0x000001D1, 0x05000068, 0x00030402,
476 0x01400000, 0x80800300, 0x00160010, 0x76543210,
477 0x00000008, 0x03010301, 0x03010301, 0x03010301,
478 0x03010301, 0x03010301, 0x00000000, 0x00500050,
479 0x00500050, 0x00500050, 0x00500050, 0x00500050,
480 0x00500050, 0x00500050, 0x00500050, 0x00500050,
481 0x00070087, 0x00000000, 0x08010007, 0x00000000,
482 0x20202020, 0x20202020, 0x20202020, 0x00000000,
483 0x00000000, 0x00000000, 0x00000000, 0x00000000,
484 0x00000000, 0x00000000, 0x00000000, 0x00000000,
485 0x00000000
486};
487
488/* The setting table of Address Slice for V4H */
489static const u32 DDR_PHY_ADR_V_REGSET_V4H[DDR_PHY_ADR_V_REGSET_NUM_V4H] = {
490 0x00200030, 0x00200002, 0x76543210, 0x00010001,
491 0x06543210, 0x03070000, 0x00001000, 0x00000000,
492 0x00000000, 0x00000000, 0x00000000, 0x00000000,
493 0x00000000, 0x00000000, 0x00000000, 0x0000807F,
494 0x00000001, 0x00000003, 0x00000000, 0x000F0000,
495 0x030C000F, 0x00020103, 0x0000000F, 0x00000100,
496 0x00000000, 0x00000000, 0x00000000, 0x00000000,
497 0x00000000, 0x02000400, 0x0000002A, 0x00000000,
498 0x00000000, 0x00000000, 0x00000000, 0x00200101,
499 0x10002C03, 0x00000003, 0x00030240, 0x00008008,
500 0x00081020, 0x01200000, 0x00010001, 0x00000000,
501 0x00100302, 0x003E4208, 0x01400140, 0x01400140,
502 0x01400140, 0x01400140, 0x00000100, 0x00000100,
503 0x00000100, 0x00000100, 0x00000000, 0x00000000,
504 0x00000000, 0x00000000, 0x00020580, 0x03000040,
505 0x00000000
506};
507
508/* The setting table of Address Control Slice for V4H */
509static const u32 DDR_PHY_ADR_G_REGSET_V4H[DDR_PHY_ADR_G_REGSET_NUM_V4H] = {
510 0x00000000, 0x00000100, 0x00000001, 0x23800000,
511 0x00000000, 0x01000101, 0x00000000, 0x00000001,
512 0x00000000, 0x00000000, 0x00000000, 0x00000000,
513 0x00040101, 0x00000000, 0x00000000, 0x00000064,
514 0x00000000, 0x00000000, 0x39421B42, 0x00010124,
515 0x00520052, 0x00000052, 0x00000000, 0x00000000,
Marek Vasut021b08e2025-03-16 14:51:42 +0100516 0x00010001, 0x00000000, 0x00000000, 0x00010001,
517 0x00000000, 0x00000000, 0x00010001, 0x07030102,
Marek Vasut1f7ba642024-12-12 14:34:30 +0100518 0x01030307, 0x00000054, 0x00004096, 0x08200820,
519 0x08200820, 0x08200820, 0x08200820, 0x00000820,
520 0x004103B8, 0x0000003F, 0x000C0006, 0x00000000,
521 0x000004C0, 0x00007A12, 0x00000208, 0x00000000,
522 0x00000000, 0x00000000, 0x00000000, 0x00000000,
523 0x03000000, 0x00000000, 0x00000000, 0x04102002,
524 0x00041020, 0x01C98C98, 0x3F400000, 0x003F3F3F,
525 0x00000000, 0x00000000, 0x76543210, 0x00010198,
526 0x00000007, 0x00000000, 0x00000000, 0x00000000,
527 0x00000002, 0x00000000, 0x00000000, 0x00000000,
528 0x01032380, 0x00000100, 0x00000000, 0x31421342,
529 0x00308000, 0x00000080, 0x00063F77, 0x00000006,
530 0x0000033F, 0x00000000, 0x0000033F, 0x00000000,
531 0x0000033F, 0x00000000, 0x00033F00, 0x00CC0000,
532 0x00033F77, 0x00000000, 0x00033F00, 0x00EE0000,
533 0x00033F00, 0x00EE0000, 0x00033F00, 0x00EE0000,
534 0x00200106
535};
536
537/* The setting table of PI Register for V4H */
538static const u32 DDR_PI_REGSET_V4H[DDR_PI_REGSET_NUM_V4H] = {
539 0x00000D00, 0x00010100, 0x00640004, 0x00000001,
540 0x00000000, 0x00000000, 0x00000000, 0x00000000,
541 0xFFFFFFFF, 0x02010000, 0x00000003, 0x00000005,
542 0x00000002, 0x00000000, 0x00000101, 0x0012080E,
543 0x00000000, 0x001E2C0E, 0x00000000, 0x00030300,
544 0x01010700, 0x00000001, 0x00000000, 0x00000000,
545 0x00000000, 0x00000000, 0x00000000, 0x00000000,
546 0x01000000, 0x00002807, 0x00000000, 0x32000300,
547 0x00000000, 0x00000000, 0x04022004, 0x01040100,
548 0x00010000, 0x00000100, 0x000000AA, 0x00000055,
549 0x000000B5, 0x0000004A, 0x00000056, 0x000000A9,
550 0x000000A9, 0x000000B5, 0x00000000, 0x01000000,
551 0x00030300, 0x0000001A, 0x000007D0, 0x00000300,
552 0x00000000, 0x00000000, 0x01000000, 0x00000101,
553 0x00000000, 0x00000000, 0x00000000, 0x00000200,
554 0x03030300, 0x01000000, 0x00000000, 0x00000100,
555 0x00000003, 0x001100EF, 0x01A1120B, 0x00051400,
556 0x001A0700, 0x001101FC, 0x00011A00, 0x00000000,
557 0x001F0000, 0x00000000, 0x00000000, 0x00051500,
558 0x001103FC, 0x00011A00, 0x00051500, 0x001102FC,
559 0x00011A00, 0x00001A00, 0x00000000, 0x001F0000,
560 0x001100FC, 0x00011A00, 0x01A1120B, 0x001A0701,
561 0x00000000, 0x001F0000, 0x00000000, 0x00000000,
562 0x001100EF, 0x01A1120B, 0x00051400, 0x01910480,
563 0x01821009, 0x001F0000, 0x00000000, 0x00000000,
564 0x00000000, 0x00000000, 0x001A0700, 0x01A11E14,
565 0x001101FC, 0x00211A00, 0x00051500, 0x001103FC,
566 0x00011A00, 0x00051500, 0x001102FC, 0x00011A00,
567 0x00031A00, 0x001A0701, 0x00000000, 0x001F0000,
568 0x00000000, 0x00000000, 0x01A11E14, 0x01A1120B,
569 0x00000000, 0x001F0000, 0x00000000, 0x00000000,
570 0x00000000, 0x00000000, 0x001100FD, 0x00012E00,
571 0x00051700, 0x01A1120B, 0x001A0701, 0x001F0000,
572 0x00000000, 0x00000000, 0x001100EF, 0x01A1120B,
573 0x00051400, 0x001A0700, 0x001102FD, 0x00012E00,
574 0x00000000, 0x001F0000, 0x00000000, 0x00000000,
575 0x00070700, 0x00000000, 0x01000000, 0x00000300,
576 0x17030000, 0x00000000, 0x00000000, 0x00000000,
577 0x0A0A140A, 0x10020201, 0x332A0002, 0x01010000,
578 0x0B000404, 0x04030308, 0x00010100, 0x02020301,
579 0x01001000, 0x00000034, 0x00000000, 0x00000000,
580 0x00000000, 0x00000000, 0x55AA55AA, 0x33CC33CC,
581 0x0FF00FF0, 0x0F0FF0F0, 0x00008E38, 0x00000001,
582 0x00000002, 0x00020001, 0x00020001, 0x02010201,
583 0x0000000F, 0x00000000, 0x00000000, 0x00000000,
584 0x00000000, 0x00000000, 0x00000000, 0x00000000,
585 0x00000000, 0x00000000, 0x00000000, 0xAAAAA593,
586 0xA5939999, 0x00000000, 0x00005555, 0x00003333,
587 0x0000CCCC, 0x00000000, 0x0003FFFF, 0x00003333,
588 0x0000CCCC, 0x00000000, 0x036DB6DB, 0x00249249,
589 0x05B6DB6D, 0x00000000, 0x00000000, 0x00000000,
590 0x00000000, 0x00000000, 0x036DB6DB, 0x00249249,
591 0x05B6DB6D, 0x00000000, 0x00000000, 0x00000000,
592 0x00000000, 0x00000000, 0x01000000, 0x00000100,
593 0x00000000, 0x00000000, 0x00000000, 0x00000000,
594 0x00000000, 0x00000000, 0x00000000, 0x00000000,
595 0x00010000, 0x00000000, 0x00000000, 0x00000000,
596 0x00000000, 0x00000000, 0x00000000, 0x00000000,
597 0x00000000, 0x00000000, 0x00000000, 0x00000000,
598 0x00000000, 0x00010000, 0x00000000, 0x00000000,
599 0x00000000, 0x00000000, 0x00000000, 0x00000000,
600 0x00000000, 0x00000000, 0x00000000, 0x00000000,
601 0x00000000, 0x00000000, 0x00080000, 0x00000000,
602 0x00000000, 0x00000000, 0x00000000, 0x00000000,
603 0x00000000, 0x00000000, 0x00000000, 0x00000000,
604 0x00000000, 0x00000000, 0x00000000, 0x00000000,
605 0x00000000, 0x00000000, 0x00000000, 0x00000000,
606 0x00000000, 0x00000000, 0x00000000, 0x01180400,
607 0x03020100, 0x00060504, 0x00010100, 0x00000008,
608 0x00080000, 0x00000001, 0x00000000, 0x0001AA00,
609 0x00000100, 0x00000000, 0x00010000, 0x00000000,
610 0x00000000, 0x00000000, 0x00000000, 0x00000000,
611 0x00000000, 0x00000000, 0x00000000, 0x00000000,
612 0x00000000, 0x00000000, 0x00000000, 0x00000000,
613 0x00000000, 0x00000000, 0x00000000, 0x00000000,
614 0x00000000, 0x00000000, 0x00000000, 0x00000000,
615 0x00000000, 0x00000000, 0x00000000, 0x00000000,
616 0x00000000, 0x00000000, 0x00000000, 0x00000000,
617 0x00000000, 0x00000000, 0x00000000, 0x00000000,
618 0x00020000, 0x00000100, 0x00010000, 0x0000000B,
619 0x0000001C, 0x00000100, 0x00000000, 0x00000000,
620 0x00000000, 0x00000000, 0x03010000, 0x01000100,
621 0x01020001, 0x00010300, 0x05000104, 0x01060001,
622 0x00010700, 0x00000000, 0x00000000, 0x00010000,
623 0x00000000, 0x00000000, 0x00000000, 0x00000000,
624 0x00000301, 0x00000000, 0x00000000, 0x01010000,
625 0x00000000, 0x00000200, 0x00000000, 0xB8000000,
626 0x010000FF, 0x0000FFE8, 0x00FFA801, 0xFFD80100,
627 0x00007F10, 0x00000000, 0x00000034, 0x0000003D,
628 0x00020079, 0x02000200, 0x02000204, 0x06000C06,
629 0x04040200, 0x04100804, 0x14090004, 0x1C081024,
630 0x0000120C, 0x00000015, 0x000000CF, 0x00000026,
631 0x0000017F, 0x00000130, 0x04000C2E, 0x00000404,
632 0x01080032, 0x01080032, 0x000F0032, 0x00000000,
633 0x00000000, 0x00000000, 0x00010300, 0x00010301,
634 0x03030000, 0x00000001, 0x00010303, 0x00030000,
635 0x0013000C, 0x0A060037, 0x03030526, 0x000C0032,
636 0x0017003D, 0x0025004B, 0x00010101, 0x0000000E,
637 0x00000019, 0x010000C8, 0x000F000F, 0x0007000C,
638 0x001A0100, 0x0015001A, 0x0100000B, 0x00C900C9,
639 0x005100A1, 0x29003329, 0x33290033, 0x0A070600,
640 0x0A07060D, 0x0D09070D, 0x000C000D, 0x00001000,
641 0x00000C00, 0x00001000, 0x00000C00, 0x02001000,
642 0x0002000E, 0x00160019, 0x1E1A00C8, 0x00100004,
643 0x361C0008, 0x00000000, 0x0000000C, 0x0006000C,
644 0x0300361C, 0x04001300, 0x000D0019, 0x0000361C,
645 0x20003300, 0x00000000, 0x02000000, 0x04040802,
646 0x00060404, 0x0003C34F, 0x05022001, 0x0203000A,
647 0x04040408, 0xC34F0604, 0x10010005, 0x040A0502,
648 0x0A080F11, 0x1C0A040A, 0x0022C34F, 0x0C0C1002,
649 0x00019E0A, 0x0000102C, 0x000002FE, 0x00001DEC,
650 0x0000185C, 0x0000F398, 0x04000400, 0x03030400,
651 0x002AF803, 0x00002AF8, 0x0000D6D7, 0x00000003,
652 0x0000006E, 0x00000016, 0x00004E20, 0x00004E20,
653 0x00030D40, 0x00000005, 0x000000C8, 0x00000027,
654 0x00027100, 0x00027100, 0x00186A00, 0x00000028,
655 0x00000640, 0x01000136, 0x00530040, 0x00010004,
656 0x00960040, 0x00010004, 0x04B00040, 0x00000318,
657 0x00280005, 0x05040404, 0x00070603, 0x06030503,
658 0x0503000D, 0x00640603, 0x06040608, 0x00040604,
659 0x00260015, 0x01050130, 0x01000100, 0x00020201,
660 0x04040000, 0x01010104, 0x03020302, 0x00000100,
661 0x02020101, 0x00000000, 0x09910260, 0x11911600,
662 0x19A21009, 0x19A10100, 0x19A10201, 0x19A10302,
663 0x19A10A03, 0x19A10B04, 0x19A10C05, 0x19A10E07,
664 0x19A10F08, 0x19A1110A, 0x19A1120B, 0x19A1130C,
665 0x19A1140D, 0x19A00C00, 0x199F0000, 0x199F0000,
666 0x199F0000, 0x199F0000, 0x01910300, 0x01A21009,
667 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
668 0x001140BF, 0x01811009, 0x01850400, 0x01A10C05,
669 0x01850300, 0x01A10C11, 0x01850300, 0x001100BF,
670 0x01811009, 0x01850500, 0x019F0000, 0x019F0000,
671 0x01510001, 0x01D102A0, 0x01E21009, 0x00051900,
672 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
673 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
674 0x019F0000, 0x019F0000, 0x019F0000, 0x01510001,
675 0x01D10290, 0x01E21009, 0x01510001, 0x01D10000,
676 0x01E21009, 0x00051800, 0x019F0000, 0x019F0000,
677 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
678 0x019F0000, 0x019F0000, 0x0011008F, 0x00910000,
679 0x01811009, 0x01910040, 0x01A21009, 0x019F0000,
680 0x01911000, 0x01A21009, 0x01A10100, 0x01A10201,
681 0x01A10302, 0x01A10A03, 0x01A10B04, 0x01A10C05,
682 0x01A10E07, 0x01A10F08, 0x01A1110A, 0x01A1120B,
683 0x01A1130C, 0x01A1140D, 0x01A00C00, 0x01910800,
684 0x01A21009, 0x019F0000, 0x019F0000, 0x019F0000,
685 0x0101017F, 0x00010101, 0x00000000, 0x00000000,
686 0x00000000, 0x00000000, 0x01000000, 0x01000101,
687 0x00000000, 0x00000000, 0x00050000, 0x00070100,
688 0x000F0200, 0x00000000, 0x01A10100, 0x01A10201,
689 0x01A10302, 0x01A00B04, 0x00210D06, 0x01A1110A,
690 0x01A1140D, 0x00098000, 0x019F0000, 0x019F0000,
691 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
692 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
693 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
694 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
695 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
696 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
697 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
698 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
699 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
700 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
701 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
702 0x019F0000, 0x019F0000, 0x019F0000, 0x019F0000,
703 0x019F0000, 0x019F0000, 0x01A10100, 0x01A10201,
704 0x01A10302, 0x01A10A03, 0x01A10B04, 0x00210D06,
705 0x01A1110A, 0x00000000, 0x01A1140D, 0x00000000,
706 0x00000000, 0x00000000, 0x01A1120B, 0x000A0000,
707 0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
708 0x001F0000, 0x001F0000, 0x000A0000, 0x01061300,
709 0x00000000, 0x00000000, 0x00061180, 0x000612C0,
710 0x00000000, 0x00000000, 0x001F0000, 0x00000000,
711 0x00000000, 0x00000000, 0x00000000, 0x00000000,
712 0x00000000, 0x00000000, 0x00000000, 0x00000000,
713 0x00000000, 0x00000000, 0x01811009, 0x0011EFAF,
714 0x01A1120B, 0x001F0000, 0x001F0000, 0x001F0000,
715 0x001F0000, 0x001F0000, 0x001F0000, 0x001100BF,
716 0x01A1120B, 0x080D0000, 0x001F0000, 0x001F0000,
717 0x001F0000, 0x080C0000, 0x001F0000, 0x001F0000,
718 0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
719 0x001F0000, 0x001F0000, 0x001F0200, 0x001F0200,
720 0x001F0200, 0x001F0200, 0x001F0200, 0x001F0200,
721 0x001F0200, 0x001F0200, 0x001F0200, 0x001F0200,
722 0x001F0200, 0x001F0200, 0x001100EF, 0x01A1120B,
723 0x001F0000, 0x00000000, 0x00000000, 0x00000000,
724 0x00000000, 0x00000000, 0x00000000, 0x00000000,
725 0x00000000, 0x00000000, 0x00000000, 0x00000000,
726 0x00000000, 0x00000000, 0x01A1120B, 0x001F0000,
727 0x00000000, 0x00000000, 0x00000000, 0x00000000,
728 0x00000000, 0x00000000, 0x00000000, 0x00000000,
729 0x00000000, 0x00000000, 0x00000000, 0x00000000,
730 0x00000000, 0x00000000, 0x001100EF, 0x01A1120B,
731 0x001F0000, 0x00000000, 0x00000000, 0x00000000,
732 0x00000000, 0x00000000, 0x00000000, 0x00000000,
733 0x00000000, 0x00000000, 0x00000000, 0x00000000,
734 0x00000000, 0x00000000, 0x00211F14, 0x00212014,
735 0x00212116, 0x00212217, 0x001F0000, 0x00000000,
736 0x00000000, 0x00000000, 0x00000000, 0x00000000,
737 0x001A85FF, 0x00051E00, 0x001F0000, 0x00000000,
738 0x00211F14, 0x00212015, 0x00212116, 0x00212217,
739 0x01A1120B, 0x001F0000, 0x00000000, 0x00000000,
740 0x00000000, 0x00000000, 0x0031FFBF, 0x01A11009,
741 0x01A10E07, 0x01A10F08, 0x003100BF, 0x01A11009,
742 0x00051800, 0x003F0000, 0x003F0000, 0x003F0000,
743 0x003F0000, 0x003F0000, 0x003F0000, 0x003F0000,
744 0x003F0000, 0x003F0000, 0x0031FFBF, 0x01A11009,
745 0x01A10E07, 0x01A10F08, 0x003100BF, 0x01A11009,
746 0x00051800, 0x003F0000, 0x003F0000, 0x003F0000,
747 0x003F0000, 0x003F0000, 0x003F0000, 0x003F0000,
748 0x003F0000, 0x003F0000, 0x08084340, 0x0011FFFF,
749 0x2011FFFB, 0x00012E00, 0x001100EF, 0x01A1120B,
750 0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
751 0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
752 0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
753 0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
754 0x001F0000, 0x001F0000, 0x083E4340, 0x00212E00,
755 0x01A1120B, 0x003F0000, 0x003F0000, 0x003F0000,
756 0x003F0000, 0x003F0000, 0x003F0000, 0x08201020,
757 0x28100020, 0x08083020, 0x08400020, 0x08402020,
758 0x08483020, 0x10083020, 0x20180020, 0x30480020,
759 0x78880020, 0x488010E0, 0x494B0000, 0x49089080,
760 0x49080000, 0x490011C0, 0x0A000020, 0x08000020,
761 0x08000020, 0x08000020, 0x08000020, 0x08000020,
762 0x08000020, 0x08000020, 0x08000020, 0x08000020,
763 0x08000020, 0x08000020, 0x08000020, 0x08000020,
764 0x08000020, 0x08000020, 0x08000020, 0x08000020,
765 0x08000020, 0x08000020, 0x08000020, 0x08000020,
766 0x08000020, 0x08000020, 0x08000020, 0x08000020,
767 0x08000020, 0x08000020, 0x08000020, 0x08000020,
768 0x001100FF, 0x01810302, 0x001100DF, 0x00010D06,
769 0x001100EF, 0x01A1120B, 0x001F0000, 0x001F0000,
770 0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
771 0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
772 0x00010D06, 0x01810302, 0x0181160E, 0x001F0000,
773 0x001F0000, 0x001F0000, 0x001F0000, 0x001F0000,
774 0x081A52FD, 0x001A12FF, 0x00051A00, 0x001A13FF,
775 0x00051B00, 0x001F13FF, 0x081A52FD, 0x001A12FF,
776 0x00051A00, 0x001A13FF, 0x00051B00, 0x001F13FF,
777 0x081A52FD, 0x001A12FF, 0x00051A00, 0x001A13FF,
778 0x00051B00, 0x001F13FF, 0x00032300, 0x00032400,
779 0x001F0000, 0x001F0000, 0x00800000, 0x0031FFBF,
780 0x01A11009, 0x01A10E07, 0x01A10F08, 0x003100BF,
781 0x01A11009, 0x00051800, 0x003F0000, 0x003F0000,
782 0x003F0000, 0x003F0000, 0x003F0000, 0x003F0000,
783 0x003F0000, 0x003F0000, 0x00800000, 0x0031FFBF,
784 0x01A11009, 0x01A10E07, 0x01A10F08, 0x003100BF,
785 0x01A11009, 0x00051800, 0x003F0000, 0x003F0000,
786 0x003F0000, 0x003F0000, 0x003F0000, 0x003F0000,
787 0x003F0000, 0x003F0000, 0x081100DF, 0x08010D06,
788 0x0011000F, 0x0181160E, 0x001100EF, 0x01A1120B,
789 0x001F0000, 0x001F0000, 0x001F0000, 0x009C0000,
790 0x08010D06, 0x0181160E, 0x01A1120B, 0x001F0000,
791 0x001F0000, 0x001F0000, 0x00000000, 0x00000000,
792 0x00000000, 0x00000000, 0x00000000, 0x00000000,
793 0x00000000, 0x00000000, 0x00000000, 0x11910048,
794 0x09910060, 0x19A21009, 0x19A10100, 0x19A10201,
795 0x19A10302, 0x19A10A03, 0x19A10B04, 0x18051C00,
796 0x19A1110A, 0x19A1120B, 0x19A1130C, 0x19A1140D,
797 0x19A1160E, 0x181140BF, 0x19A11009, 0x19A10C05,
798 0x19A00C00, 0x19A10E07, 0x19A10F08, 0x19910280,
799 0x19A21009, 0x18051000, 0x18861101, 0x181F0000,
800 0x18000000, 0x18000000, 0x18000000, 0x18000000,
801 0x18000000, 0x18000000, 0x18000000, 0x18000000,
802 0x18000000, 0x18000000, 0x18000000, 0x18000000,
803 0x18000000, 0x18000000, 0x18000000, 0x18861100,
804 0x19A11009, 0x101B0001, 0x181B0100, 0x18000500,
805 0x181B0200, 0x00000000, 0x181B0600, 0x181B0C00,
806 0x181B0100, 0x181B0200, 0x181B0300, 0x181B0400,
807 0x181F0000, 0x18000000, 0x18000000, 0x18000000,
808 0x18000000, 0x18000000, 0x18000000, 0x18000000,
809 0x18000000, 0x18000000, 0x18000000, 0x18000000,
810 0x18000000, 0x18000000, 0x18000000, 0x18000000,
811 0x18000000, 0x004B1040, 0x001011C0, 0x00089080,
812 0x000811C0, 0x040811C0, 0x02000000, 0x00000000,
813 0x00000000, 0x00000000, 0x00000000, 0x00000000,
814 0x00000000, 0x00000000, 0x00000000, 0x00000000,
815 0x00000000, 0x00000000, 0x00000000, 0x00000000,
816 0x00000000, 0x00000000, 0x00000000, 0x5F407FAA,
817 0x007B776F, 0x4AB555AA, 0xB5A9A956, 0x9F80BFAA,
818 0x00BBB7AF, 0x00000000, 0x00000000, 0x00000000,
819 0x00000000, 0x00000000, 0x00000000, 0x00000000,
820 0x00000000, 0x00002AF8, 0x0000D6D7, 0x0000006E,
821 0x00000000, 0x00000000, 0x00000000, 0x00000000,
822 0x00000000, 0x00000000, 0x00000000, 0x00000000,
823 0x00000000, 0x00000000, 0x00000000, 0x00000000,
824 0x00000000, 0x0000000E, 0x00000019, 0x000000C8,
825 0x00000001, 0x00000001, 0x00000003, 0x00000007,
826 0x00000007, 0x00000009, 0x00000001, 0x00000001,
827 0x00000003, 0x00000001, 0x00000001, 0x00000003,
828 0x0000006E, 0x000000C8, 0x00000640, 0x00000001,
829 0x00000001, 0x00000003, 0x00000002, 0x00000004,
830 0x0000001C, 0x00000007, 0x0000000B, 0x00000051,
831 0x0000000C, 0x00000015, 0x000000A1, 0x00000003,
832 0x00000000, 0x0000000C, 0x00000000, 0x00000000,
833 0x00000000, 0x0000000F, 0x0000000F, 0x0000000F,
834 0x00002AF9, 0x00002AF9, 0x00002AF9, 0x00000034,
835 0x0000001E, 0x0000003C, 0x00000000, 0x00000000,
836 0x00000000, 0x00000000, 0x00000000, 0x00000000,
837 0x00000000, 0x00000000, 0x00000000, 0x00000000,
838 0x00000000, 0x00000000, 0x00000000, 0x00000000,
839 0x00000000, 0x00000000, 0x00000000, 0x00000000,
840 0x00000000, 0x00000000, 0x00000000, 0x00000000,
841 0x00000000, 0x00000000, 0x00000000, 0x00000000,
842 0x00000000, 0x00000000, 0x00000000, 0x00000000,
843 0x00000000, 0x00000000, 0x00000000, 0x00000000,
844 0x00000000, 0x00000000, 0x00000000, 0x00000000,
845 0x00000000, 0x00000000, 0x00000000, 0x00000000,
846 0x00000000, 0x00000000, 0x00000000, 0x00000000,
847 0x00000000, 0x00000000, 0x00000000, 0x00000000,
848 0x000000C0, 0x00000000, 0x00000000, 0x55550000,
849 0x00003C5A, 0x00000000, 0x00000000, 0x00000000,
850 0x00000000, 0x00000000, 0x00000000, 0x00000000,
851 0x00000000, 0x00000000, 0x00000000, 0x00000000,
852 0x00000000, 0x00000000, 0x00000000, 0x00000000,
853 0x00000000, 0x00000000, 0x00000000, 0x00000000,
854 0x00000000, 0x00000000, 0x00000000, 0x00000000,
855 0x00000000, 0x00000000, 0x00000000, 0x00000000,
856 0x00000000, 0x00000000, 0x00000000, 0x00000000,
857 0x00000000, 0x00000000, 0x00000000, 0x00000000,
858 0x00000000, 0x00000000, 0x00000000, 0x00000000,
859 0x00000000, 0x00000000, 0x00000000, 0x00000000,
860 0x00000000, 0x00000000, 0x00000000, 0x00000000,
861 0x00000000, 0x00000000, 0x00000000, 0x00D60000,
862 0x50005000, 0x803E0050, 0x00000200, 0x00000000,
863 0x00000000, 0x00007800, 0x00000000, 0x00000000,
864 0x00000000, 0x00C61110, 0x2C002834, 0x0C06002C,
865 0x00000200, 0x00000000, 0x00000000, 0x00007800,
866 0x00000000, 0x00000000, 0x00000000, 0x00C6BBB0,
867 0x2C002834, 0x0C06002C, 0x00000200, 0x00000000,
868 0x00000000, 0x00007800, 0x00000000, 0x00000000,
869 0x00000000, 0x00D60000, 0x50005000, 0x803E0050,
870 0x00000200, 0x00000000, 0x00000000, 0x00007800,
871 0x00000000, 0x00000000, 0x00000000, 0x00C61110,
872 0x2C002834, 0x082E002C, 0x00000200, 0x00000000,
873 0x00000000, 0x00007800, 0x00000000, 0x00000000,
874 0x00000000, 0x00C6BBB0, 0x2C002834, 0x082E002C,
875 0x00000200, 0x00000000, 0x00000000, 0x00007800,
876 0x00000000, 0x00000000, 0x00000000, 0x80808080,
877 0x800D8080, 0x80808080, 0x17808080, 0x80808025,
878 0x2221201F, 0x80808080, 0x80808080, 0x80808080,
879 0x80808080, 0x80808080, 0x80808080, 0x80808080,
880 0x80808080, 0x80808080, 0x80808080, 0x80808080,
881 0x80808080, 0x80808080, 0x80808080, 0x0A030201,
882 0x0E800C0B, 0x1211100F, 0x80161413, 0x08004C80,
883 0x8080801E, 0x80804E80, 0x80808080, 0x80808080,
884 0x80808080
885};
886
887struct dbsc5_table_patch {
888 const u32 reg;
889 const u32 val;
890};
891
892static const struct dbsc5_table_patch dbsc5_table_patch_slice_3200[] = {
893 { PHY_REGULATOR_EN_CNT, 0x10 },
894 { PHY_RX_CAL_ALL_DLY, 0x07 },
895 { PHY_RDDATA_EN_TSEL_DLY, 0x08 },
896 { PHY_RDDATA_EN_OE_DLY, 0x0B },
897 { PHY_RPTR_UPDATE, 0x07 },
898 { PHY_WRLVL_RESP_WAIT_CNT, 0x25 },
899 { PHY_RDLVL_MAX_EDGE, 0x012D },
900 { PHY_RDDATA_EN_DLY, 0x0B },
901 { PHY_RDDQS_LATENCY_ADJUST, 0x04 },
902 { PHY_RDDQS_GATE_SLAVE_DELAY, 0x05 },
903 { PHY_GTLVL_LAT_ADJ_START, 0x03 },
904 { PHY_LP4_BOOT_RX_PCLK_CLK_SEL, 0x00 }
905};
906
907static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_3200[] = {
908 { PHY_ADR_MEAS_DLY_STEP_ENABLE, 0x00 },
909 { PHY_ADR_CALVL_DLY_STEP, 0x02 }
910};
911
912static const struct dbsc5_table_patch dbsc5_table_patch_pi_3200[] = {
913 { PI_TCKCKEL_F2, 0x03 },
914 { PI_TDELAY_RDWR_2_BUS_IDLE_F2, 0x57 },
915 { PI_TREF_F2, 0x613 },
916 { PI_TDFI_WRLVL_WW_F0, 0x2B },
917 { PI_TDFI_WRLVL_WW_F1, 0x2B },
918 { PI_TDFI_WRLVL_WW_F2, 0x2B },
919 { PI_RDLAT_ADJ_F2, 0x22 },
920 { PI_TDFI_CALVL_CAPTURE_F2, 0x1D },
921 { PI_TDFI_CALVL_CC_F2, 0x43 },
922 { PI_TVRCG_ENABLE_F2, 0x51 },
923 { PI_TVRCG_DISABLE_F2, 0x29 },
924 { PI_TXP_F2, 0x07 },
925 { PI_TMRWCKEL_F2, 0x0A },
926 { PI_TDFI_CALVL_STROBE_F2, 0x06 },
927 { PI_TFC_F2, 0x64 },
928 { PI_TCKEHDQS_F2, 0x12 },
929 { PI_TDFI_WDQLVL_RW_F2, 0x09 },
930 { PI_TDFI_WDQLVL_WR_F2, 0x10 },
931 { PI_MBIST_TWCKENL_RD_ADJ_F2, 0x10 },
932 { PI_MBIST_RDLAT_ADJ_F2, 0x1E },
933 { PI_TWTR_S_F2, 0x05 },
934 { PI_TWTR_L_F2, 0x05 },
935 { PI_TWTR_F2, 0x05 },
936 { PI_TWR_F2, 0x0E },
937 { PI_TDQSCK_MAX_F2, 0x01 },
938 { PI_TDFI_CTRLUPD_MAX_F2, 0x0C26 },
939 { PI_TDFI_CTRLUPD_INTERVAL_F2, 0x797C },
940 { PI_TXSNR_F2, 0x9B },
941 { PI_ZQRESET_F2, 0x0014 },
942 { PI_TCBTRTW_F2, 0x04 },
943 { PI_SEQ_WAIT_16_F2, 0x000064 },
944 { PI_SEQ_WAIT_17_F2, 0x000002 },
945 { PI_SEQ_WAIT_18_F2, 0x000007 },
946 { PI_SEQ_WAIT_19_F2, 0x000002 },
947 { PI_SEQ_WAIT_20_F2, 0x000002 },
948 { PI_SEQ_WAIT_21_F2, 0x000320 },
949 { PI_SEQ_WAIT_22_F2, 0x000002 },
950 { PI_SEQ_WAIT_23_F2, 0x00000E },
951 { PI_SEQ_WAIT_24_F2, 0x000029 },
952 { PI_SEQ_WAIT_25_F2, 0x000051 },
953 { PI_SEQ_WAIT_26_F2, 0x000003 },
954 { PI_SEQ_WAIT_30_F2, 0x00002B },
955 { PI_WRDCM_LVL_EN_F1, 0x00 },
956 { PI_WRDCM_LVL_EN_F2, 0x00 },
957 { PI_DRAMDCA_LVL_EN_F1, 0x00 },
958 { PI_DRAMDCA_LVL_EN_F2, 0x00 },
959 { PI_TINIT_F2, 0x013880 },
960 { PI_TINIT1_F2, 0x013880 },
961 { PI_TINIT3_F2, 0x0C3500 },
962 { PI_TINIT4_F2, 0x000014 },
963 { PI_TINIT5_F2, 0x000320 }
964};
965
966static const struct dbsc5_table_patch dbsc5_table_patch_slice_3733[] = {
967 { PHY_REGULATOR_EN_CNT, 0x13 },
968 { PHY_RX_CAL_ALL_DLY, 0x08 },
969 { PHY_RDDATA_EN_TSEL_DLY, 0x0A },
970 { PHY_RDDATA_EN_OE_DLY, 0x0D },
971 { PHY_RPTR_UPDATE, 0x08 },
972 { PHY_WRLVL_RESP_WAIT_CNT, 0x2A },
973 { PHY_RDLVL_MAX_EDGE, 0x0149 },
974 { PHY_RDDATA_EN_DLY, 0x0D },
975 { PHY_RDDQS_LATENCY_ADJUST, 0x04 },
976 { PHY_RDDQS_GATE_SLAVE_DELAY, 0x9C },
977 { PHY_GTLVL_LAT_ADJ_START, 0x04 },
978 { PHY_LP4_BOOT_RX_PCLK_CLK_SEL, 0x00 }
979};
980
981static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_3733[] = {
982 { PHY_ADR_MEAS_DLY_STEP_ENABLE, 0x00 },
983 { PHY_ADR_CALVL_DLY_STEP, 0x02 }
984};
985
986static const struct dbsc5_table_patch dbsc5_table_patch_pi_3733[] = {
987 { PI_TCKCKEL_F2, 0x03 },
988 { PI_TDELAY_RDWR_2_BUS_IDLE_F2, 0x5B },
989 { PI_TREF_F2, 0x717 },
990 { PI_TDFI_WRLVL_WW_F0, 0x2C },
991 { PI_TDFI_WRLVL_WW_F1, 0x2C },
992 { PI_TDFI_WRLVL_WW_F2, 0x2C },
993 { PI_RDLAT_ADJ_F2, 0x24 },
994 { PI_TDFI_CALVL_CAPTURE_F2, 0x1F },
995 { PI_TDFI_CALVL_CC_F2, 0x45 },
996 { PI_TVRCG_ENABLE_F2, 0x5F },
997 { PI_TVRCG_DISABLE_F2, 0x30 },
998 { PI_TXP_F2, 0x07 },
999 { PI_TMRWCKEL_F2, 0x0A },
1000 { PI_TDFI_CALVL_STROBE_F2, 0x06 },
1001 { PI_TFC_F2, 0x75 },
1002 { PI_TCKEHDQS_F2, 0x13 },
1003 { PI_TDFI_WDQLVL_RW_F2, 0x09 },
1004 { PI_TDFI_WDQLVL_WR_F2, 0x12 },
1005 { PI_MBIST_TWCKENL_RD_ADJ_F2, 0x10 },
1006 { PI_MBIST_RDLAT_ADJ_F2, 0x20 },
1007 { PI_TWTR_S_F2, 0x06 },
1008 { PI_TWTR_L_F2, 0x06 },
1009 { PI_TWTR_F2, 0x06 },
1010 { PI_TWR_F2, 0x10 },
1011 { PI_TDFI_CTRLUPD_MAX_F2, 0x0E2E },
1012 { PI_TDFI_CTRLUPD_INTERVAL_F2, 0x8DCC },
1013 { PI_TXSNR_F2, 0xB5 },
1014 { PI_ZQRESET_F2, 0x0018 },
1015 { PI_TCBTRTW_F2, 0x05 },
1016 { PI_SEQ_WAIT_16_F2, 0x000075 },
1017 { PI_SEQ_WAIT_17_F2, 0x000002 },
1018 { PI_SEQ_WAIT_18_F2, 0x000007 },
1019 { PI_SEQ_WAIT_19_F2, 0x000002 },
1020 { PI_SEQ_WAIT_20_F2, 0x000002 },
1021 { PI_SEQ_WAIT_21_F2, 0x0003A6 },
1022 { PI_SEQ_WAIT_22_F2, 0x000002 },
1023 { PI_SEQ_WAIT_23_F2, 0x000011 },
1024 { PI_SEQ_WAIT_24_F2, 0x000030 },
1025 { PI_SEQ_WAIT_25_F2, 0x00005F },
1026 { PI_SEQ_WAIT_26_F2, 0x000005 },
1027 { PI_SEQ_WAIT_30_F2, 0x00002D },
1028 { PI_TINIT_F2, 0x016C90 },
1029 { PI_TINIT1_F2, 0x016C90 },
1030 { PI_TINIT3_F2, 0x0E3D98 },
1031 { PI_TINIT4_F2, 0x000018 },
1032 { PI_TINIT5_F2, 0x0003A6 }
1033};
1034
1035static const struct dbsc5_table_patch dbsc5_table_patch_slice_4266[] = {
1036 { PHY_REGULATOR_EN_CNT, 0x16 },
1037 { PHY_RX_CAL_ALL_DLY, 0x09 },
1038 { PHY_RDDATA_EN_TSEL_DLY, 0x0B },
1039 { PHY_RDDATA_EN_OE_DLY, 0x0E },
1040 { PHY_RPTR_UPDATE, 0x08 },
1041 { PHY_WRLVL_RESP_WAIT_CNT, 0x2E },
1042 { PHY_RDLVL_MAX_EDGE, 0x0164 },
1043 { PHY_RDDATA_EN_DLY, 0x0E },
1044 { PHY_RDDQS_LATENCY_ADJUST, 0x05 },
1045 { PHY_RDDQS_GATE_SLAVE_DELAY, 0x30 },
1046 { PHY_GTLVL_LAT_ADJ_START, 0x04 },
1047 { PHY_LP4_BOOT_RX_PCLK_CLK_SEL, 0x00 }
1048};
1049
1050static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_4266[] = {
1051 { PHY_ADR_MEAS_DLY_STEP_ENABLE, 0x00 },
1052 { PHY_ADR_CALVL_DLY_STEP, 0x02 }
1053};
1054
1055static const struct dbsc5_table_patch dbsc5_table_patch_pi_4266[] = {
1056 { PI_TCKCKEL_F2, 0x03 },
1057 { PI_TDELAY_RDWR_2_BUS_IDLE_F2, 0x64 },
1058 { PI_TREF_F2, 0x81C },
1059 { PI_TDFI_WRLVL_WW_F0, 0x2D },
1060 { PI_TDFI_WRLVL_WW_F1, 0x2D },
1061 { PI_TDFI_WRLVL_WW_F2, 0x2D },
1062 { PI_RDLAT_ADJ_F2, 0x2B },
1063 { PI_TDFI_CALVL_CAPTURE_F2, 0x20 },
1064 { PI_TDFI_CALVL_CC_F2, 0x46 },
1065 { PI_TVRCG_ENABLE_F2, 0x6C },
1066 { PI_TVRCG_DISABLE_F2, 0x37 },
1067 { PI_TXP_F2, 0x07 },
1068 { PI_TMRWCKEL_F2, 0x0A },
1069 { PI_TFC_F2, 0x86 },
1070 { PI_TCKEHDQS_F2, 0x14 },
1071 { PI_TDFI_WDQLVL_RW_F2, 0x0B },
1072 { PI_TDFI_WDQLVL_WR_F2, 0x13 },
1073 { PI_MBIST_TWCKENL_RD_ADJ_F2, 0x14 },
1074 { PI_MBIST_RDLAT_ADJ_F2, 0x27 },
1075 { PI_TWTR_S_F2, 0x07 },
1076 { PI_TWTR_L_F2, 0x07 },
1077 { PI_TWTR_F2, 0x07 },
1078 { PI_TWR_F2, 0x13 },
1079 { PI_TDFI_CTRLUPD_MAX_F2, 0x1038 },
1080 { PI_TDFI_CTRLUPD_INTERVAL_F2, 0xA230 },
1081 { PI_TXSNR_F2, 0xCF },
1082 { PI_ZQRESET_F2, 0x001B },
1083 { PI_TCBTRTW_F2, 0x06 },
1084 { PI_SEQ_WAIT_16_F2, 0x000086 },
1085 { PI_SEQ_WAIT_17_F2, 0x000002 },
1086 { PI_SEQ_WAIT_18_F2, 0x000007 },
1087 { PI_SEQ_WAIT_19_F2, 0x000002 },
1088 { PI_SEQ_WAIT_20_F2, 0x000002 },
1089 { PI_SEQ_WAIT_21_F2, 0x00042B },
1090 { PI_SEQ_WAIT_22_F2, 0x000002 },
1091 { PI_SEQ_WAIT_23_F2, 0x000013 },
1092 { PI_SEQ_WAIT_24_F2, 0x000037 },
1093 { PI_SEQ_WAIT_25_F2, 0x00006C },
1094 { PI_SEQ_WAIT_26_F2, 0x000006 },
1095 { PI_SEQ_WAIT_30_F2, 0x000032 },
1096 { PI_TINIT_F2, 0x01A0AB },
1097 { PI_TINIT1_F2, 0x01A0AB },
1098 { PI_TINIT3_F2, 0x1046AB },
1099 { PI_TINIT4_F2, 0x00001B },
1100 { PI_TINIT5_F2, 0x00042B }
1101};
1102
1103static const struct dbsc5_table_patch dbsc5_table_patch_slice_4800[] = {
1104 { PHY_REGULATOR_EN_CNT, 0x18 },
1105 { PHY_RX_CAL_ALL_DLY, 0x0A },
1106 { PHY_RDDATA_EN_TSEL_DLY, 0x0D },
1107 { PHY_RDDATA_EN_OE_DLY, 0x10 },
1108 { PHY_RPTR_UPDATE, 0x08 },
1109 { PHY_WRLVL_RESP_WAIT_CNT, 0x31 },
1110 { PHY_RDLVL_MAX_EDGE, 0x017F },
1111 { PHY_RDDATA_EN_DLY, 0x10 },
1112 { PHY_RDDQS_LATENCY_ADJUST, 0x05 },
1113 { PHY_RDDQS_GATE_SLAVE_DELAY, 0xC6 },
1114 { PHY_GTLVL_LAT_ADJ_START, 0x05 },
1115 { PHY_LP4_BOOT_RX_PCLK_CLK_SEL, 0x00 }
1116};
1117
1118static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_4800[] = {
1119 { PHY_ADR_MEAS_DLY_STEP_ENABLE, 0x00 },
1120 { PHY_ADR_CALVL_DLY_STEP, 0x02 }
1121};
1122
1123static const struct dbsc5_table_patch dbsc5_table_patch_pi_4800[] = {
1124 { PI_TCKCKEL_F2, 0x03 },
1125 { PI_TDELAY_RDWR_2_BUS_IDLE_F2, 0x68 },
1126 { PI_RDLAT_ADJ_F2, 0x2D },
1127 { PI_TREF_F2, 0x920 },
1128 { PI_TDFI_WRLVL_WW_F0, 0x2E },
1129 { PI_TDFI_WRLVL_WW_F1, 0x2E },
1130 { PI_TDFI_WRLVL_WW_F2, 0x2E },
1131 { PI_TDFI_CALVL_CAPTURE_F2, 0x21 },
1132 { PI_TDFI_CALVL_CC_F2, 0x47 },
1133 { PI_TVRCG_DISABLE_F2, 0x3D },
1134 { PI_TVRCG_ENABLE_F2, 0x79 },
1135 { PI_TXP_F2, 0x08 },
1136 { PI_TMRWCKEL_F2, 0x0A },
1137 { PI_TCKEHDQS_F2, 0x14 },
1138 { PI_TFC_F2, 0x96 },
1139 { PI_TDFI_WDQLVL_RW_F2, 0x0B },
1140 { PI_TDFI_WDQLVL_WR_F2, 0x15 },
1141 { PI_MBIST_TWCKENL_RD_ADJ_F2, 0x18 },
1142 { PI_MBIST_RDLAT_ADJ_F2, 0x29 },
1143 { PI_TWTR_S_F2, 0x08 },
1144 { PI_TWR_F2, 0x15 },
1145 { PI_TWTR_F2, 0x08 },
1146 { PI_TWTR_L_F2, 0x08 },
1147 { PI_TDFI_CTRLUPD_MAX_F2, 0x1240 },
1148 { PI_TDFI_CTRLUPD_INTERVAL_F2, 0xB680 },
1149 { PI_TXSNR_F2, 0x0E9 },
1150 { PI_ZQRESET_F2, 0x001E },
1151 { PI_TCBTRTW_F2, 0x06 },
1152 { PI_SEQ_WAIT_16_F2, 0x000096 },
1153 { PI_SEQ_WAIT_17_F2, 0x000002 },
1154 { PI_SEQ_WAIT_18_F2, 0x000008 },
1155 { PI_SEQ_WAIT_19_F2, 0x000002 },
1156 { PI_SEQ_WAIT_20_F2, 0x000002 },
1157 { PI_SEQ_WAIT_21_F2, 0x0004B0 },
1158 { PI_SEQ_WAIT_22_F2, 0x000002 },
1159 { PI_SEQ_WAIT_23_F2, 0x000015 },
1160 { PI_SEQ_WAIT_24_F2, 0x00003D },
1161 { PI_SEQ_WAIT_25_F2, 0x000079 },
1162 { PI_SEQ_WAIT_26_F2, 0x000008 },
1163 { PI_SEQ_WAIT_30_F2, 0x000034 },
1164 { PI_TINIT_F2, 0x01D4A9 },
1165 { PI_TINIT1_F2, 0x01D4A9 },
1166 { PI_TINIT3_F2, 0x124E91 },
1167 { PI_TINIT4_F2, 0x00001E },
1168 { PI_TINIT5_F2, 0x0004B0 }
1169};
1170
1171static const struct dbsc5_table_patch dbsc5_table_patch_slice_5500[] = {
1172 { PHY_REGULATOR_EN_CNT, 0x1C },
1173 { PHY_RX_CAL_ALL_DLY, 0x0C },
1174 { PHY_RDDATA_EN_TSEL_DLY, 0x10 },
1175 { PHY_RDDATA_EN_OE_DLY, 0x13 },
1176 { PHY_WRLVL_RESP_WAIT_CNT, 0x37 },
1177 { PHY_RDLVL_MAX_EDGE, 0x01A3 },
1178 { PHY_RDDATA_EN_DLY, 0x13 },
1179 { PHY_RDDQS_LATENCY_ADJUST, 0x06 },
1180 { PHY_RDDQS_GATE_SLAVE_DELAY, 0x8F },
1181 { PHY_GTLVL_LAT_ADJ_START, 0x06 },
1182 { PHY_LP4_BOOT_RX_PCLK_CLK_SEL, 0x00 }
1183};
1184
1185static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_5500[] = {
1186 { PHY_ADR_MEAS_DLY_STEP_ENABLE, 0x00 },
1187 { PHY_ADR_CALVL_DLY_STEP, 0x02 }
1188};
1189
1190static const struct dbsc5_table_patch dbsc5_table_patch_pi_5500[] = {
1191 { PI_TDELAY_RDWR_2_BUS_IDLE_F2, 0x71 },
1192 { PI_RDLAT_ADJ_F2, 0x32 },
1193 { PI_TREF_F2, 0xA79 },
1194 { PI_TDFI_WRLVL_WW_F0, 0x30 },
1195 { PI_TDFI_WRLVL_WW_F1, 0x30 },
1196 { PI_TDFI_WRLVL_WW_F2, 0x30 },
1197 { PI_TDFI_CALVL_CAPTURE_F2, 0x23 },
1198 { PI_TDFI_CALVL_CC_F2, 0x49 },
1199 { PI_TVRCG_DISABLE_F2, 0x46 },
1200 { PI_TVRCG_ENABLE_F2, 0x8B },
1201 { PI_TMRWCKEL_F2, 0x0B },
1202 { PI_TCKEHDQS_F2, 0x15 },
1203 { PI_TFC_F2, 0xAD },
1204 { PI_TDFI_WDQLVL_RW_F2, 0x0C },
1205 { PI_TDFI_WDQLVL_WR_F2, 0x17 },
1206 { PI_MBIST_TWCKENL_RD_ADJ_F2, 0x1C },
1207 { PI_MBIST_RDLAT_ADJ_F2, 0x2E },
1208 { PI_TWTR_S_F2, 0x09 },
1209 { PI_TWR_F2, 0x18 },
1210 { PI_TWTR_F2, 0x09 },
1211 { PI_TWTR_L_F2, 0x09 },
1212 { PI_TDFI_CTRLUPD_MAX_F2, 0x14F2 },
1213 { PI_TDFI_CTRLUPD_INTERVAL_F2, 0xD174 },
1214 { PI_TXSNR_F2, 0x10B },
1215 { PI_ZQRESET_F2, 0x0023 },
1216 { PI_TCBTRTW_F2, 0x07 },
1217 { PI_SEQ_WAIT_16_F2, 0x0000AD },
1218 { PI_SEQ_WAIT_21_F2, 0x000561 },
1219 { PI_SEQ_WAIT_23_F2, 0x000019 },
1220 { PI_SEQ_WAIT_24_F2, 0x000046 },
1221 { PI_SEQ_WAIT_25_F2, 0x00008B },
1222 { PI_SEQ_WAIT_26_F2, 0x00000A },
1223 { PI_SEQ_WAIT_30_F2, 0x000038 },
1224 { PI_TINIT_F2, 0x0219AF },
1225 { PI_TINIT1_F2, 0x0219AF },
1226 { PI_TINIT3_F2, 0x1500CF },
1227 { PI_TINIT4_F2, 0x000023 },
1228 { PI_TINIT5_F2, 0x000561 }
1229};
1230
1231static const struct dbsc5_table_patch dbsc5_table_patch_slice_6000[] = {
1232 { PHY_REGULATOR_EN_CNT, 0x1F },
1233 { PHY_RDDATA_EN_TSEL_DLY, 0x12 },
1234 { PHY_RDDATA_EN_OE_DLY, 0x15 },
1235 { PHY_WRLVL_RESP_WAIT_CNT, 0x3A },
1236 { PHY_RDLVL_MAX_EDGE, 0x01BD },
1237 { PHY_RDDATA_EN_DLY, 0x15 },
1238 { PHY_RDDQS_LATENCY_ADJUST, 0x07 },
1239 { PHY_RDDQS_GATE_SLAVE_DELAY, 0x1B },
1240 { PHY_GTLVL_LAT_ADJ_START, 0x06 },
1241 { PHY_LP4_BOOT_RX_PCLK_CLK_SEL, 0x00 }
1242};
1243
1244static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_6000[] = {
1245 { PHY_ADR_MEAS_DLY_STEP_ENABLE, 0x00 },
1246 { PHY_ADR_CALVL_DLY_STEP, 0x02 }
1247};
1248
1249static const struct dbsc5_table_patch dbsc5_table_patch_pi_6000[] = {
1250 { PI_TDELAY_RDWR_2_BUS_IDLE_F2, 0x75 },
1251 { PI_RDLAT_ADJ_F2, 0x34 },
1252 { PI_TREF_F2, 0xB6B },
1253 { PI_TDFI_WRLVL_WW_F0, 0x31 },
1254 { PI_TDFI_WRLVL_WW_F1, 0x31 },
1255 { PI_TDFI_WRLVL_WW_F2, 0x31 },
1256 { PI_TVRCG_DISABLE_F2, 0x4D },
1257 { PI_TVRCG_ENABLE_F2, 0x98 },
1258 { PI_TMRWCKEL_F2, 0x0C },
1259 { PI_TFC_F2, 0xBC },
1260 { PI_TDFI_WDQLVL_RW_F2, 0x0C },
1261 { PI_MBIST_TWCKENL_RD_ADJ_F2, 0x1C },
1262 { PI_MBIST_RDLAT_ADJ_F2, 0x30 },
1263 { PI_TWR_F2, 0x1A },
1264 { PI_TDFI_CTRLUPD_MAX_F2, 0x16D6 },
1265 { PI_TDFI_CTRLUPD_INTERVAL_F2, 0xE45C },
1266 { PI_TXSNR_F2, 0x123 },
1267 { PI_ZQRESET_F2, 0x0026 },
1268 { PI_SEQ_WAIT_16_F2, 0x0000BC },
1269 { PI_SEQ_WAIT_21_F2, 0x0005DD },
1270 { PI_SEQ_WAIT_23_F2, 0x00001B },
1271 { PI_SEQ_WAIT_24_F2, 0x00004D },
1272 { PI_SEQ_WAIT_25_F2, 0x000098 },
1273 { PI_SEQ_WAIT_30_F2, 0x00003A },
1274 { PI_TINIT_F2, 0x024A16 },
1275 { PI_TINIT1_F2, 0x024A16 },
1276 { PI_TINIT3_F2, 0x16E4D8 },
1277 { PI_TINIT4_F2, 0x000026 },
1278 { PI_TINIT5_F2, 0x0005DD }
1279};
1280
1281static const struct dbsc5_table_patch dbsc5_table_patch_slice_mbpsdiv_640 = {
1282 PHY_DATA_DC_CAL_CLK_SEL, 0x05
1283};
1284
1285static const struct dbsc5_table_patch dbsc5_table_patch_adr_v_mbpsdiv_640 = {
1286 PHY_CLK_DC_CAL_CLK_SEL, 0x04
1287};
1288
1289static const struct dbsc5_table_patch dbsc5_table_patch_adr_g_mbpsdiv_640 = {
1290 PHY_CAL_CLK_SELECT_0, 0x05
1291};
1292
1293static const struct dbsc5_table_patch dbsc5_table_patch_slice_mbpsdiv_572 = {
1294 PHY_RX_PCLK_CLK_SEL, 0x3
1295};
1296
1297static const struct dbsc5_table_patch dbsc5_table_patch_adr_g_mbpsdiv_572 = {
Marek Vasut021b08e2025-03-16 14:51:42 +01001298 PHY_PAD_ACS_RX_PCLK_CLK_SEL, 0x02
Marek Vasut1f7ba642024-12-12 14:34:30 +01001299};
1300
1301static const struct dbsc5_table_patch dbsc5_table_patch_adr_g_mbpsdiv_400[] = {
1302 { PHY_PLL_CTRL, 0x1542 },
1303 { PHY_PLL_CTRL_8X, 0x3342 }
1304};
1305
1306/* Array of addresses for setting PI_DARRAY3_0 in each CS and frequency-set */
1307static const u32 PI_DARRAY3_0_CSx_Fx[CS_CNT][3] = {
1308 { PI_DARRAY3_0_CS0_F0, PI_DARRAY3_0_CS0_F1, PI_DARRAY3_0_CS0_F2 },
1309 { PI_DARRAY3_0_CS1_F0, PI_DARRAY3_0_CS1_F1, PI_DARRAY3_0_CS1_F2 }
1310};
1311
1312/* Array of addresses for setting PI_DARRAY3_1 in each CS and frequency-set */
1313static const u32 PI_DARRAY3_1_CSx_Fx[CS_CNT][3] = {
1314 { PI_DARRAY3_1_CS0_F0, PI_DARRAY3_1_CS0_F1, PI_DARRAY3_1_CS0_F2 },
1315 { PI_DARRAY3_1_CS1_F0, PI_DARRAY3_1_CS1_F1, PI_DARRAY3_1_CS1_F2 }
1316};
1317
1318/* DBSC registers */
1319#define DBSC_DBSYSCONF0 0x0
1320#define DBSC_DBSYSCONF1 0x0
1321#define DBSC_DBSYSCONF1A 0x4
1322#define DBSC_DBSYSCONF2 0x4
1323#define DBSC_DBPHYCONF0 0x8
1324#define DBSC_DBSYSCONF2A 0x8
1325#define DBSC_DBMEMKIND 0x20
1326#define DBSC_DBMEMKINDA 0x20
1327#define DBSC_DBMEMCONF(ch, cs) (0x30 + (0x2000 * ((ch) & 0x2)) + (0x10 * ((ch) & 0x1)) + (0x4 * (cs)))
1328#define DBSC_DBMEMCONFA(ch, cs) (0x30 + (0x4000 * ((ch) & 0x2)) + (0x10 * ((ch) & 0x1)) + (0x4 * (cs)))
1329#define DBSC_DBSYSCNT0 0x100
1330#define DBSC_DBSYSCNT0A 0x100
1331#define DBSC_DBACEN 0x200
1332#define DBSC_DBRFEN 0x204
1333#define DBSC_DBCMD 0x208
1334#define DBSC_DBWAIT 0x210
1335#define DBSC_DBBL 0x400
1336#define DBSC_DBBLA 0x400
1337#define DBSC_DBRFCNF1 0x414
1338#define DBSC_DBRFCNF2 0x418
1339#define DBSC_DBCALCNF 0x424
1340#define DBSC_DBDBICNT 0x518
1341#define DBSC_DBDFIPMSTRCNF 0x520
1342#define DBSC_DBDFICUPDCNF 0x540
1343#define DBSC_DBBCAMDIS 0x9FC
1344#define DBSC_DBSCHRW1 0x1024
1345#define DBSC_DBSCHTR0 0x1030
1346#define DBSC_DBTR(x) (0x300 + (0x4 * (x)))
1347#define DBSC_DBRNK(x) (0x430 + (0x4 * (x)))
1348#define DBSC_DBDFISTAT(ch) (0x600 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
1349#define DBSC_DBDFICNT(ch) (0x604 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
1350#define DBSC_DBPDCNT2(ch) (0x618 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
1351#define DBSC_DBPDLK(ch) (0x620 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
1352#define DBSC_DBPDRGA(ch) (0x624 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
1353#define DBSC_DBPDRGD(ch) (0x628 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
1354#define DBSC_DBPDRGM(ch) (0x62C + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
1355#define DBSC_DBPDSTAT0(ch) (0x630 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
1356#define DBSC_DBPDSTAT1(ch) (0x634 + (0x2000 * ((ch) & 0x2)) + (0x40 * ((ch) & 0x1)))
1357#define DBSC_DBSCHFCTST0 0x1040
1358#define DBSC_DBSCHFCTST1 0x1044
1359
1360/* CPG PLL3 registers */
1361#define CPG_CPGWPR 0x0
1362#define CPG_FRQCRD0 0x80C
1363#define CPG_PLLECR 0x820
1364#define CPG_PLL3CR0 0x83C
1365#define CPG_PLL3CR1 0x8C0
1366#define CPG_FSRCHKCLRR4 0x590
1367#define CPG_FSRCHKSETR4 0x510
1368#define CPG_FSRCHKRA4 0x410
1369#define CPG_SRCR4 0x2C10
1370#define CPG_SRSTCLR4 0x2C90
1371
1372#define CPG_FRQCRD_KICK_BIT BIT(31)
1373#define CPG_PLL3CR0_KICK_BIT BIT(31)
1374#define CPG_PLLECR_PLL3ST_BIT BIT(11)
1375
1376#define CLK_DIV(a, diva, b, divb) (((a) * (divb)) / ((b) * (diva)))
1377
1378struct renesas_dbsc5_board_config {
1379 /* Channels in use */
1380 u8 bdcfg_phyvalid;
1381 /* Read vref (SoC) training range */
1382 u32 bdcfg_vref_r;
1383 /* Write vref (MR14, MR15) training range */
1384 u16 bdcfg_vref_w;
1385 /* CA vref (MR12) training range */
1386 u16 bdcfg_vref_ca;
1387 /* RFM required check */
1388 bool bdcfg_rfm_chk;
1389
1390 /* Board parameter about channels */
1391 struct {
1392 /*
1393 * 0x00: 4Gb dual channel die / 2Gb single channel die
1394 * 0x01: 6Gb dual channel die / 3Gb single channel die
1395 * 0x02: 8Gb dual channel die / 4Gb single channel die
1396 * 0x03: 12Gb dual channel die / 6Gb single channel die
1397 * 0x04: 16Gb dual channel die / 8Gb single channel die
1398 * 0x05: 24Gb dual channel die / 12Gb single channel die
1399 * 0x06: 32Gb dual channel die / 16Gb single channel die
1400 * 0x07: 24Gb single channel die
1401 * 0x08: 32Gb single channel die
1402 * 0xFF: NO_MEMORY
1403 */
1404 u8 bdcfg_ddr_density[CS_CNT];
1405 /* SoC caX([6][5][4][3][2][1][0]) -> MEM caY: */
1406 u32 bdcfg_ca_swap;
1407 /* SoC dqsX([1][0]) -> MEM dqsY: */
1408 u8 bdcfg_dqs_swap;
1409 /* SoC dq([7][6][5][4][3][2][1][0]) -> MEM dqY/dm: (8 means DM) */
1410 u32 bdcfg_dq_swap[SLICE_CNT];
1411 /* SoC dm -> MEM dqY/dm: (8 means DM) */
1412 u8 bdcfg_dm_swap[SLICE_CNT];
1413 /* SoC ckeX([1][0]) -> MEM csY */
1414 u8 bdcfg_cs_swap;
1415 } ch[4];
1416};
1417
1418struct renesas_dbsc5_dram_priv {
1419 void __iomem *regs;
1420 void __iomem *cpg_regs;
1421
1422 /* The board parameter structure of the board */
1423 const struct renesas_dbsc5_board_config *dbsc5_board_config;
1424
1425 /* The board clock frequency */
1426 u32 brd_clk;
1427 u32 brd_clkdiv;
1428 u32 brd_clkdiva;
1429
1430 /* The Mbps of Bus */
1431 u32 bus_clk;
1432 u32 bus_clkdiv;
1433
1434 /* The Mbps of DDR */
1435 u32 ddr_mbps;
1436 u32 ddr_mbpsdiv;
1437
1438 /* DDR memory multiplier setting value */
1439 u32 ddr_mul;
1440 u32 ddr_mul_nf;
1441 u32 ddr_mul_low;
1442 u32 ddr_mul_reg;
1443
1444 /* Value indicating the enabled channel */
1445 u32 ddr_phyvalid;
1446
1447 /* The tccd value of DDR */
1448 u32 ddr_tccd;
1449
1450 /* Memory capacity in each channel and each CS */
1451 u8 ddr_density[DRAM_CH_CNT][CS_CNT];
1452 /* Channels used for each memory rank */
1453 u32 ch_have_this_cs[CS_CNT];
1454 /* The maximum memory capacity */
1455 u32 max_density;
1456
1457 /* Index of jedec spec1 setting table you use */
1458 u32 js1_ind;
1459 /* Array of jedec spec2 setting table */
1460 u32 js2[JS2_CNT];
1461 /* Read latency */
1462 u32 RL;
1463 /* Write latency */
1464 u32 WL;
1465
1466 /* Array for DDR PI Slice settings */
1467 u32 DDR_PI_REGSET[DDR_PI_REGSET_NUM_V4H];
1468 /* Array for DDRPHY Slice settings */
1469 u32 DDR_PHY_SLICE_REGSET[DDR_PHY_SLICE_REGSET_NUM_V4H];
1470 /* Array for DDRPHY ADRRESS VALUE Slice settings */
1471 u32 DDR_PHY_ADR_V_REGSET[DDR_PHY_SLICE_REGSET_NUM_V4H];
1472 /* Array for DDRPHY ADRRESS CONTROL Slice settings */
1473 u32 DDR_PHY_ADR_G_REGSET[DDR_PHY_SLICE_REGSET_NUM_V4H];
1474};
1475
1476static const struct renesas_dbsc5_board_config renesas_v4h_dbsc5_board_config = {
1477 /* RENESAS V4H White Hawk (64Gbit 1rank) */
1478 .bdcfg_phyvalid = 0xF,
1479 .bdcfg_vref_r = 0x0,
1480 .bdcfg_vref_w = 0x0,
1481 .bdcfg_vref_ca = 0x0,
1482 .bdcfg_rfm_chk = true,
1483 .ch = {
1484 [0] = {
1485 .bdcfg_ddr_density = { 0x06, 0xFF },
1486 .bdcfg_ca_swap = 0x04506132,
1487 .bdcfg_dqs_swap = 0x01,
1488 .bdcfg_dq_swap = { 0x26147085, 0x12306845 },
1489 .bdcfg_dm_swap = { 0x03, 0x07 },
1490 .bdcfg_cs_swap = 0x10
1491 },
1492 [1] = {
1493 .bdcfg_ddr_density = { 0x06, 0xFF },
1494 .bdcfg_ca_swap = 0x02341065,
1495 .bdcfg_dqs_swap = 0x10,
1496 .bdcfg_dq_swap = { 0x56782314, 0x71048365 },
1497 .bdcfg_dm_swap = { 0x00, 0x02 },
1498 .bdcfg_cs_swap = 0x10
1499 },
1500 [2] = {
1501 .bdcfg_ddr_density = { 0x06, 0xFF },
1502 .bdcfg_ca_swap = 0x02150643,
1503 .bdcfg_dqs_swap = 0x10,
1504 .bdcfg_dq_swap = { 0x58264071, 0x41207536 },
1505 .bdcfg_dm_swap = { 0x03, 0x08 },
1506 .bdcfg_cs_swap = 0x10
1507 },
1508 [3] = {
1509 .bdcfg_ddr_density = { 0x06, 0xFF },
1510 .bdcfg_ca_swap = 0x01546230,
1511 .bdcfg_dqs_swap = 0x01,
1512 .bdcfg_dq_swap = { 0x45761328, 0x62801745 },
1513 .bdcfg_dm_swap = { 0x00, 0x03 },
1514 .bdcfg_cs_swap = 0x10
1515 }
1516 }
1517};
1518
1519/**
1520 * r_vch_nxt() - Macro for channel selection loop
1521 *
1522 * Return the ID of the channel to be used. Check for valid channels
1523 * between the value of posn and the maximum number of CHs. If a valid
1524 * channel is found, returns the value of that channel.
1525 */
1526static u32 r_vch_nxt(struct udevice *dev, u32 pos)
1527{
1528 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1529 int posn;
1530
1531 for (posn = pos; posn < DRAM_CH_CNT; posn++)
1532 if (priv->ddr_phyvalid & BIT(posn))
1533 break;
1534
1535 return posn;
1536}
1537
1538/* Select only valid channels in all channels from CH0. */
1539#define r_foreach_vch(dev, ch) \
1540for ((ch) = r_vch_nxt((dev), 0); (ch) < DRAM_CH_CNT; (ch) = r_vch_nxt((dev), (ch) + 1))
1541
1542/* All channels are selected. */
1543#define r_foreach_ech(ch) \
1544for (ch = 0; ch < DRAM_CH_CNT; ch++)
1545
1546/**
1547 * dbsc5_clk_cpg_write_32() - Write clock control register
1548 *
1549 * Write the complement value of setting value to the CPG_CPGWPR register
1550 * for releaseing the protect. Write setting value to destination address.
1551 */
1552static void dbsc5_clk_cpg_write_32(struct udevice *dev, void __iomem *a, u32 v)
1553{
1554 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1555
1556 writel(~v, priv->cpg_regs + CPG_CPGWPR);
1557 writel(v, a);
1558}
1559
1560enum dbsc5_clk_pll3_mode {
1561 PLL3_LOW_FREQUENCY_MODE = 0,
1562 PLL3_HIGH_FREQUENCY_MODE,
1563 PLL3_HIGH_FREQUENCY_MODE_LOAD_REGISTER
1564};
1565
1566/**
1567 * dbsc5_clk_pll3_control() - Set PLL3
1568 * @dev: DBSC5 device
1569 * @mode: PLL3 frequency mode
1570 *
1571 * Determine the set value according to the frequency mode of the argument.
1572 * Write the set value to CPG_FRQCRD0 register and CPG_FRQCRD0 one.
1573 * Reflect settings
1574 */
1575static void dbsc5_clk_pll3_control(struct udevice *dev, u32 mode)
1576{
1577 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1578 u32 data_div, data_mul, data_nf, ssmode, val;
1579 int ret;
1580
1581 /*
1582 * PLL3VCO = EXTAL * priv->ddr_mul * 1/2
1583 * clk_ctlr_sync = PLL3VCO * pll3_div
1584 * priv->ddr_mul = (NI[7:0] + 1) * 2 + NF[24:0] / 2^24
1585 */
1586
1587 switch (mode) {
1588 case PLL3_LOW_FREQUENCY_MODE:
1589 /* Low frequency mode (50MHz) */
1590 data_mul = (priv->ddr_mul_low / 2) - 1; /* PLL3VCO = 1600MHz */
1591 data_div = 0x9; /* div = 32 */
1592 data_nf = 0x0;
1593 ssmode = 0x0;
1594 break;
1595 case PLL3_HIGH_FREQUENCY_MODE:
1596 /* High frequency mode */
1597 data_mul = (priv->ddr_mul / 2) - 1;
1598 data_div = 0x0; /* div = 2 */
1599 data_nf = priv->ddr_mul_nf;
1600 ssmode = 0x4;
1601 break;
1602 case PLL3_HIGH_FREQUENCY_MODE_LOAD_REGISTER:
1603 /* High frequency mode for loading to DDRPHY registers */
1604 data_mul = (priv->ddr_mul_reg / 2) - 1;
1605 data_div = 0x0; /* div = 2 */
1606 data_nf = 0x0;
1607 ssmode = 0x4;
1608 break;
1609 default:
1610 printf("%s Mode %d not supported\n", __func__, mode);
1611 hang();
1612 }
1613
1614 data_mul = (data_mul << 20) | (ssmode << 16);
1615 data_nf = data_nf << 21;
1616
1617 if (((readl(priv->cpg_regs + CPG_PLL3CR0) & 0x3FFFFF7F) != data_mul) ||
1618 (readl(priv->cpg_regs + CPG_PLL3CR1) != data_nf)) {
1619 /* PLL3CR0 multiplie set */
1620 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_PLL3CR0, data_mul);
1621 /* PLL3CR1 multiplie set */
1622 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_PLL3CR1, data_nf);
1623 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_PLL3CR0,
1624 readl(priv->cpg_regs + CPG_PLL3CR0) |
1625 CPG_PLL3CR0_KICK_BIT);
1626
1627 ret = readl_poll_timeout(priv->cpg_regs + CPG_PLLECR, val,
1628 (val & CPG_PLLECR_PLL3ST_BIT),
1629 1000000);
1630 if (ret < 0) {
1631 printf("%s CPG_PLLECR bit CPG_PLLECR_PLL3ST_BIT timeout\n", __func__);
1632 hang();
1633 }
1634 }
1635
1636 /* PLL3 DIV set(Target value) */
1637 ret = readl_poll_timeout(priv->cpg_regs + CPG_FRQCRD0, val,
1638 ((val & CPG_FRQCRD_KICK_BIT) == 0),
1639 1000000);
1640 if (ret < 0) {
1641 printf("%s CPG_FRQCRD0 bit CPG_FRQCRD_KICK_BIT div set timeout\n", __func__);
1642 hang();
1643 }
1644
1645 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FRQCRD0,
1646 (readl(priv->cpg_regs + CPG_FRQCRD0) & 0xFFFFFFF0) |
1647 data_div);
1648 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FRQCRD0,
1649 readl(priv->cpg_regs + CPG_FRQCRD0) |
1650 CPG_FRQCRD_KICK_BIT);
1651 ret = readl_poll_timeout(priv->cpg_regs + CPG_FRQCRD0, val,
1652 ((val & CPG_FRQCRD_KICK_BIT) == 0),
1653 1000000);
1654 if (ret < 0) {
1655 printf("%s CPG_FRQCRD0 bit CPG_FRQCRD_KICK_BIT timeout\n", __func__);
1656 hang();
1657 }
1658}
1659
1660/**
1661 * dbsc5_clk_wait_freqchgreq() - Training handshake functions
1662 *
1663 * Check the value of the argument req_assert. If req_assert is 1, wait until
1664 * FREQCHGREQ of all channels is 1 before time expires. If req_assert is 0,
1665 * wait until FREQCHGREQ of all channels is 0 before time expires. Return the
1666 * result of whether time has expired or not as a return value.
1667 */
1668static u32 dbsc5_clk_wait_freqchgreq(struct udevice *dev, u32 req_assert)
1669{
1670 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1671 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
1672 u32 count = 0xFFFFFF;
1673 u32 ch, reg;
1674
1675 do {
1676 reg = !!req_assert;
1677 r_foreach_vch(dev, ch)
1678 reg &= readl(regs_dbsc_d + DBSC_DBPDSTAT0(ch));
1679 count = count - 1;
1680 } while (((reg & 0x1) != !!req_assert) && (count != 0));
1681
1682 return count == 0x0;
1683}
1684
1685/**
1686 * dbsc5_clk_set_freqchgack() - Training handshake functions
1687 * @dev: DBSC5 device
1688 * @ack_assert: Select DBSC_DBPDCNT2 content
1689 *
1690 * Check the value of the argument ackassert. If the value of ackassert
1691 * is greater than or equal to 0, write 0xCF01 to DBSC_DBPDCNT2.
1692 * If the value of ackassert is 0, write 0x0 to DBSC_DBPDCNT2.
1693 */
1694static void dbsc5_clk_set_freqchgack(struct udevice *dev, u32 ack_assert)
1695{
1696 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1697 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
1698 const u32 reg = ack_assert ? 0xcf01 : 0x0;
1699 u32 ch;
1700
1701 r_foreach_vch(dev, ch)
1702 writel(reg, regs_dbsc_d + DBSC_DBPDCNT2(ch));
1703}
1704
1705/**
1706 * dbsc5_clk_wait_dbpdstat1() - Wait for status register update
1707 * @dev: DBSC5 device
1708 * @status: Expected status
1709 *
1710 * Read value the DBSC_DBPDSTAT1(ch) register. Wait until the contents
1711 * of the status register are the same as status.
1712 */
1713static void dbsc5_clk_wait_dbpdstat1(struct udevice *dev, u32 status)
1714{
1715 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1716 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
Marek Vasut021b08e2025-03-16 14:51:42 +01001717 u32 i, ch, chk, reg;
Marek Vasut1f7ba642024-12-12 14:34:30 +01001718
1719 for (i = 0; i < 2; i++) {
1720 do {
1721 reg = status;
Marek Vasut021b08e2025-03-16 14:51:42 +01001722 chk = 0;
1723 r_foreach_vch(dev, ch) {
Marek Vasut1f7ba642024-12-12 14:34:30 +01001724 reg &= readl(regs_dbsc_d + DBSC_DBPDSTAT1(ch));
Marek Vasut021b08e2025-03-16 14:51:42 +01001725 chk |= readl(regs_dbsc_d + DBSC_DBPDSTAT0(ch));
1726 }
1727 } while (reg != status && !(chk & BIT(0)));
Marek Vasut1f7ba642024-12-12 14:34:30 +01001728 }
1729}
1730
1731/**
1732 * dbsc5_clk_pll3_freq() - Set up the pll3 frequency
1733 * @dev: DBSC5 device
1734 *
1735 * Wait for frequency change request. DBSC_DBPDSTAT0 value determines whether
1736 * dbsc5_clk_pll3_control is called in low frequency mode or high frequency
1737 * mode. Call dbsc5_clk_set_freqchgack(1) function. Check update completion until
1738 * timeout. Call dbsc5_clk_set_freqchgack(0) function. If timed out, return with
1739 * error log Wait for status register update.
1740 */
1741static int dbsc5_clk_pll3_freq(struct udevice *dev)
1742{
1743 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1744 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
1745 u32 fsel, timeout;
1746
1747 dbsc5_clk_wait_freqchgreq(dev, 1);
1748
1749 fsel = (readl(regs_dbsc_d + DBSC_DBPDSTAT0(0)) & 0x300) >> 8;
1750 dbsc5_clk_pll3_control(dev, fsel ? PLL3_HIGH_FREQUENCY_MODE :
1751 PLL3_LOW_FREQUENCY_MODE);
1752
1753 dbsc5_clk_set_freqchgack(dev, 1);
1754 timeout = dbsc5_clk_wait_freqchgreq(dev, 0);
1755 dbsc5_clk_set_freqchgack(dev, 0);
1756
1757 if (timeout) {
1758 printf("Time out\n");
1759 return -ETIMEDOUT;
1760 }
1761
1762 dbsc5_clk_wait_dbpdstat1(dev, 0x7);
1763
1764 return 0;
1765}
1766
1767/**
1768 * dbsc5_reg_write() - Write DBSC register
1769 * @addr: Destination address
1770 * @data: Setting value to be written
1771 *
1772 * Write 32bit value @data to register at @addr .
1773 */
1774static void dbsc5_reg_write(void __iomem *addr, u32 data)
1775{
1776 writel(data, addr);
1777
1778 if (((uintptr_t)addr & 0x000A0000) == 0x000A0000)
1779 writel(data, addr + 0x4000);
1780 else
1781 writel(data, addr + 0x8000);
1782}
1783
1784/**
1785 * dbsc5_reg_write() - DRAM Command Write Access
1786 * @dev: DBSC5 device
1787 * @cmd DRAM command.
1788 *
1789 * First, execute the dummy read to DBSC_DBCMD.
1790 * Confirm that no DBSC command operation is in progress 0.
1791 * Write the contents of the command to be sent to DRAM.
1792 */
1793static void dbsc5_send_dbcmd2(struct udevice *dev, u32 cmd)
1794{
1795 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1796 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
1797 u32 val;
1798 int ret;
1799
1800 /* dummy read */
1801 readl(regs_dbsc_d + DBSC_DBCMD);
1802
1803 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBWAIT, val, ((val & BIT(0)) == 0), 1000000);
1804 if (ret < 0) {
1805 printf("%s DBWAIT bit 0 timeout\n", __func__);
1806 hang();
1807 }
1808
1809 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBWAIT + 0x4000, val, ((val & BIT(0)) == 0), 1000000);
1810 if (ret < 0) {
1811 printf("%s DBWAIT + 0x4000 bit 0 timeout\n", __func__);
1812 hang();
1813 }
1814
1815 dbsc5_reg_write(regs_dbsc_d + DBSC_DBCMD, cmd);
1816}
1817
1818/**
1819 * dbsc5_reg_ddrphy_read() - Read setting from DDR PHY register
1820 * @dev: DBSC5 device
1821 * @ch: Target channel
1822 * @regadd: Destination address
1823 *
1824 * Write matching values to DBPDRGA register and read value out of DBSC_DBPDRGD.
1825 * Wait until the write process completed in each step.
1826 */
1827static u32 dbsc5_reg_ddrphy_read(struct udevice *dev, u32 ch, u32 regadd)
1828{
1829 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1830 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
1831 u32 val;
1832 int ret;
1833
1834 writel(regadd | BIT(14), regs_dbsc_d + DBSC_DBPDRGA(ch));
1835 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == (regadd | BIT(15) | BIT(14))), 1000000);
1836 if (ret < 0) {
1837 printf("%s regs_dbsc_d + DBSC_DBPDRGA timeout\n", __func__);
1838 hang();
1839 }
1840
1841 val = readl(regs_dbsc_d + DBSC_DBPDRGA(ch));
1842
1843 writel(regadd | BIT(15), regs_dbsc_d + DBSC_DBPDRGA(ch));
1844 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == regadd), 1000000);
1845 if (ret < 0) {
1846 printf("%s regs_dbsc_d + DBSC_DBPDRGA | BIT(15) timeout\n", __func__);
1847 hang();
1848 }
1849
1850 writel(regadd | BIT(15), regs_dbsc_d + DBSC_DBPDRGA(ch));
1851 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == regadd), 1000000);
1852 if (ret < 0) {
1853 printf("%s regs_dbsc_d + DBSC_DBPDRGA | BIT(15) again timeout\n", __func__);
1854 hang();
1855 }
1856
1857 return readl(regs_dbsc_d + DBSC_DBPDRGD(ch));
1858}
1859
1860/**
1861 * dbsc5_reg_ddrphy_write(dev, ) - Write setting to DDR PHY register
1862 * @dev: DBSC5 device
1863 * @ch: Target channel
1864 * @regadd: Destination address
1865 * @regdata: Value to be written
1866 *
1867 * Write matching values to DBPDRGA, DBPDRGD, DBPDRGA, DBPDRGA registers.
1868 * Wait until the write process completed in each step.
1869 */
1870static void dbsc5_reg_ddrphy_write(struct udevice *dev, u32 ch, u32 regadd, u32 regdata)
1871{
1872 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1873 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
1874 u32 val;
1875 int ret;
1876
1877 writel(regadd, regs_dbsc_d + DBSC_DBPDRGA(ch));
1878 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == regadd), 1000000);
1879 if (ret < 0) {
1880 printf("%s regs_dbsc_d + DBSC_DBPDRGA timeout\n", __func__);
1881 hang();
1882 }
1883
1884 writel(regdata, regs_dbsc_d + DBSC_DBPDRGD(ch));
1885 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == (regadd | BIT(15))), 1000000);
1886 if (ret < 0) {
1887 printf("%s regs_dbsc_d + DBSC_DBPDRGD timeout\n", __func__);
1888 hang();
1889 }
1890
1891 writel(regadd | BIT(15), regs_dbsc_d + DBSC_DBPDRGA(ch));
1892 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == regadd), 1000000);
1893 if (ret < 0) {
1894 printf("%s regs_dbsc_d + DBSC_DBPDRGA | BIT(15) timeout\n", __func__);
1895 hang();
1896 }
1897
1898 writel(regadd, regs_dbsc_d + DBSC_DBPDRGA(ch));
1899}
1900
1901/*
1902 * dbsc5_reg_ddrphy_write_all() - Write setting from DDR PHY register for all channels
1903 * @dev: DBSC5 device
1904 * @regadd: Destination address
1905 * @regdata: Value to be written
1906 *
1907 * Wrapper around dbsc5_reg_ddrphy_write() for all channels.
1908 */
1909static void dbsc5_reg_ddrphy_write_all(struct udevice *dev, u32 regadd, u32 regdata)
1910{
1911 u32 ch;
1912
1913 r_foreach_vch(dev, ch)
1914 dbsc5_reg_ddrphy_write(dev, ch, regadd, regdata);
1915}
1916
1917/**
1918 * dbsc5_reg_ddrphy_masked_write() - Write setting to DDR PHY register with mask
1919 * @dev: DBSC5 device
1920 * @ch: Target channel
1921 * @regadd: Destination address
1922 * @regdata: Value to be written
1923 * @msk: Register mask
1924 *
1925 * Wrapper around dbsc5_reg_ddrphy_write() with DBPDRGM set.
1926 */
1927static void dbsc5_reg_ddrphy_masked_write(struct udevice *dev, u32 ch, u32 regadd, u32 regdata, u32 msk)
1928{
1929 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1930 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
1931 u32 val;
1932 int ret;
1933
1934 writel(msk, regs_dbsc_d + DBSC_DBPDRGM(ch));
1935 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGM(ch), val, (val == msk), 1000000);
1936 if (ret < 0) {
1937 printf("%s regs_dbsc_d + DBSC_DBPDRGM timeout\n", __func__);
1938 hang();
1939 }
1940
1941 dbsc5_reg_ddrphy_write(dev, ch, regadd, regdata);
1942
1943 writel(0, regs_dbsc_d + DBSC_DBPDRGM(ch));
1944 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGM(ch), val, (val == 0), 1000000);
1945 if (ret < 0) {
1946 printf("%s regs_dbsc_d + DBSC_DBPDRGM != 0 timeout\n", __func__);
1947 hang();
1948 }
1949}
1950
1951/**
1952 * dbsc5_ddr_setval_slice() - Write setting to DDR PHY hardware
1953 * @dev: DBSC5 device
1954 * @ch: Target channel
1955 * @slice: Target slice
1956 * @regdef: Encoded PHY/PI register and bitfield
1957 * @val: Value to be written
1958 *
1959 * Calculate the bit field in which to write the setting value
1960 * from encoded register and bitfield @regdef parameter. Call
1961 * dbsc5_reg_ddrphy_masked_write() to write the value to hardware.
1962 */
1963static void dbsc5_ddr_setval_slice(struct udevice *dev, u32 ch, u32 slice, u32 regdef, u32 val)
1964{
1965 const u32 adr = DDR_REGDEF_ADR(regdef) + (0x100 * slice);
1966 const u32 len = DDR_REGDEF_LEN(regdef);
1967 const u32 lsb = DDR_REGDEF_LSB(regdef);
1968 const u32 msk = (len == 32) ? 0xffffffff : ((BIT(len) - 1) << lsb);
1969 const u32 dms = ~((!!(msk & BIT(24)) << 3) | (!!(msk & BIT(16)) << 2) |
1970 (!!(msk & BIT(8)) << 1) | !!(msk & BIT(0))) & 0xf;
1971
1972 dbsc5_reg_ddrphy_masked_write(dev, ch, adr, val << lsb, dms);
1973}
1974
1975/*
1976 * dbsc5_ddr_setval() - Write setting from DDR PHY hardware slice 0
1977 * @dev: DBSC5 device
1978 * @ch: Target channel
1979 * @regdef: Encoded PHY/PI register and bitfield
1980 * @val: Value to be written
1981 *
1982 * Wrapper around dbsc5_ddr_setval_slice() for slice 0.
1983 */
1984static void dbsc5_ddr_setval(struct udevice *dev, u32 ch, u32 regdef, u32 val)
1985{
1986 dbsc5_ddr_setval_slice(dev, ch, 0, regdef, val);
1987}
1988
1989/*
1990 * dbsc5_ddr_setval_all_ch_slice() - Write setting from DDR PHY hardware for all channels and one slice
1991 * @dev: DBSC5 device
1992 * @slice: Target slice
1993 * @regdef: Encoded PHY/PI register and bitfield
1994 * @val: Value to be written
1995 *
1996 * Wrapper around dbsc5_ddr_setval_slice() for slice 0.
1997 */
1998static void dbsc5_ddr_setval_all_ch_slice(struct udevice *dev, u32 slice, u32 regdef, u32 val)
1999{
2000 u32 ch;
2001
2002 r_foreach_vch(dev, ch)
2003 dbsc5_ddr_setval_slice(dev, ch, slice, regdef, val);
2004}
2005
2006/*
2007 * dbsc5_ddr_setval_all_ch() - Write setting from DDR PHY hardware for all channels and slice 0
2008 * @dev: DBSC5 device
2009 * @regdef: Encoded PHY/PI register and bitfield
2010 * @val: Value to be written
2011 *
2012 * Wrapper around dbsc5_ddr_setval_all_ch_slice() for slice 0.
2013 */
2014static void dbsc5_ddr_setval_all_ch(struct udevice *dev, u32 regdef, u32 val)
2015{
2016 dbsc5_ddr_setval_all_ch_slice(dev, 0, regdef, val);
2017}
2018
2019/*
2020 * dbsc5_ddr_setval_all_ch_all_slice() - Write setting from DDR PHY hardware for all channels and all slices
2021 * @dev: DBSC5 device
2022 * @regdef: Encoded PHY/PI register and bitfield
2023 * @val: Value to be written
2024 *
2025 * Wrapper around dbsc5_ddr_setval_all_ch_slice() for slice 0.
2026 */
2027static void dbsc5_ddr_setval_all_ch_all_slice(struct udevice *dev, u32 regdef, u32 val)
2028{
2029 u32 slice;
2030
2031 for (slice = 0; slice < SLICE_CNT; slice++)
2032 dbsc5_ddr_setval_all_ch_slice(dev, slice, regdef, val);
2033}
2034
2035/**
2036 * dbsc5_ddr_getval_slice() - Read setting from DDR PHY/PI hardware
2037 * @dev: DBSC5 device
2038 * @ch: Target channel
2039 * @slice: Target slice
2040 * @regdef: Encoded PHY/PI register and bitfield
2041 *
2042 * Calculate the address and the bit-field from "regdef" value.
2043 * Call dbsc5_reg_ddrphy_read() to read value from the target address.
2044 */
2045static u32 dbsc5_ddr_getval_slice(struct udevice *dev, u32 ch, u32 slice, u32 regdef)
2046{
2047 const u32 adr = DDR_REGDEF_ADR(regdef) + (0x100 * slice);
2048 const u32 len = DDR_REGDEF_LEN(regdef);
2049 const u32 lsb = DDR_REGDEF_LSB(regdef);
2050 const u32 msk = (len == 32) ? 0xffffffff : (BIT(len) - 1);
2051
2052 return (dbsc5_reg_ddrphy_read(dev, ch, adr) >> lsb) & msk;
2053}
2054
2055/**
2056 * dbsc5_ddr_getval() - Read setting from DDR PHY/PI hardware slice 0
2057 * @dev: DBSC5 device
2058 * @ch: Target channel
2059 * @regdef: Encoded PHY/PI register and bitfield
2060 *
2061 * Wrapper around dbsc5_ddr_getval_slice() for slice 0.
2062 */
2063static u32 dbsc5_ddr_getval(struct udevice *dev, u32 ch, u32 regdef)
2064{
2065 return dbsc5_ddr_getval_slice(dev, ch, 0, regdef);
2066}
2067
2068/**
2069 * dbsc5_table_patch_set() - Modify DDR PHY/PI settings table
2070 * @tbl: DDR PHY/PI setting table pointer
2071 * @adrmsk_pi: Use wider address mask for PI register
2072 * @patch: List of modifications to the settings table
2073 * @patchlen: Length of the list of modifications to the settings table
2074 *
2075 * Calculate the target index of settings table, calculate the bit-field
2076 * to write the setting value, and write the setting value to the target
2077 * bit-field in the index.
2078 */
2079static void dbsc5_table_patch_set(u32 *tbl, const bool adrmsk_pi,
2080 const struct dbsc5_table_patch *patch,
2081 int patchlen)
2082{
2083 const u32 adrmsk = adrmsk_pi ? 0x7FF : 0xFF;
2084 u32 adr, len, lsb, msk;
2085 int i;
2086
2087 for (i = 0; i < patchlen; i++) {
2088 adr = DDR_REGDEF_ADR(patch[i].reg);
2089 len = DDR_REGDEF_LEN(patch[i].reg);
2090 lsb = DDR_REGDEF_LSB(patch[i].reg);
2091 msk = (len == 32) ? 0xffffffff : ((BIT(len) - 1) << lsb);
2092
2093 tbl[adr & adrmsk] &= ~msk;
2094 tbl[adr & adrmsk] |= (patch[i].val << lsb) & msk;
2095 }
2096}
2097
2098/**
2099 * dbsc5_ddrtbl_getval() - Read setting from DDR PHY/PI settings table
2100 * @tbl: DDR PHY/PI setting table pointer
2101 * @regdef: Encoded PHY/PI register and bitfield
2102 * @adrmsk_pi: Use wider address mask for PI register
2103 *
2104 * Calculate the target index of *tbl and the bit-field to read the
2105 * setting value and read and return the setting value from the target
2106 * bit-field in the index.
2107 */
2108static u32 dbsc5_ddrtbl_getval(const u32 *tbl, u32 regdef, bool adrmsk_pi)
2109{
2110 const u32 adrmsk = adrmsk_pi ? 0x7FF : 0xFF;
2111 const u32 adr = DDR_REGDEF_ADR(regdef);
2112 const u32 len = DDR_REGDEF_LEN(regdef);
2113 const u32 lsb = DDR_REGDEF_LSB(regdef);
2114 const u32 msk = (len == 32) ? 0xffffffff : (BIT(len) - 1);
2115
2116 return (tbl[adr & adrmsk] >> lsb) & msk;
2117}
2118
2119/**
2120 * dbsc5_f_scale() - Calculate the best value for DBSC timing setting
2121 * @priv: Driver private data
2122 * @frac: Perform fractional rounding
2123 * @ps Optimal setting value in pico second
2124 * @cyc Optimal setting value in cycle count
2125 *
2126 * Convert the optimal value in pico second to in cycle count. Optionally, if @frac is true,
2127 * perform fractional rounding. Compare the value of the result of the conversion with the
2128 * value of the argument @cyc and return the larger value.
2129 */
2130static u32 dbsc5_f_scale(struct renesas_dbsc5_dram_priv *priv, const bool frac, u32 ps, u32 cyc)
2131{
2132 const u32 mul = frac ? 8 : 800000;
2133 const u32 tmp = DIV_ROUND_UP(ps, 10UL) * priv->ddr_mbps;
2134 const u32 f_scale_div = DIV_ROUND_UP(tmp, mul * priv->ddr_mbpsdiv);
2135
2136 return (f_scale_div > cyc) ? f_scale_div : cyc;
2137}
2138
2139/**
2140 * dbsc5_f_scale_js2() - Select optimal settings based on jedec_spec2
2141 * @priv: Driver private data
2142 *
2143 * Calculate and assign each setting value of jedec_spec2 by "dbsc5_f_scale" function.
2144 * Only the following array elements are calculated using different formulas from those
2145 * described above -- JS2_tRRD/JS2_tFAW/JS2_tZQCALns/JS2_tRCpb/JS2_tRCab.
2146 */
2147static void dbsc5_f_scale_js2(struct renesas_dbsc5_dram_priv *priv)
2148{
2149 const int derate = 0;
2150 int i;
2151
2152 for (i = 0; i < JS2_TBLCNT; i++) {
2153 priv->js2[i] = dbsc5_f_scale(priv, false,
2154 jedec_spec2[derate][i].ps,
2155 jedec_spec2[derate][i].cyc);
2156 }
2157
2158 priv->js2[JS2_tZQCALns] = dbsc5_f_scale(priv, false,
2159 jedec_spec2[derate][JS2_tZQCALns].ps * 1000UL, 0);
2160 priv->js2[JS2_tDQ72DQns] = dbsc5_f_scale(priv, false,
2161 jedec_spec2[derate][JS2_tDQ72DQns].ps * 1000UL, 0);
2162 priv->js2[JS2_tCAENTns] = dbsc5_f_scale(priv, false,
2163 jedec_spec2[derate][JS2_tCAENTns].ps * 1000UL, 0);
2164 priv->js2[JS2_tRCpb] = priv->js2[JS2_tRAS] + priv->js2[JS2_tRPpb];
2165 priv->js2[JS2_tRCab] = priv->js2[JS2_tRAS] + priv->js2[JS2_tRPab];
2166 priv->js2[JS2_tRFCab] = dbsc5_f_scale(priv, false,
2167 jedec_spec2_tRFC_ab[priv->max_density] * 1000UL, 0);
2168
2169 priv->js2[JS2_tRBTP] = dbsc5_f_scale(priv, false, 7500, 2) - 2;
2170 priv->js2[JS2_tXSR] = priv->js2[JS2_tRFCab] +
2171 dbsc5_f_scale(priv, false, 7500, 2);
2172 priv->js2[JS2_tPDN] = dbsc5_f_scale(priv, false, 10000, 0) + 1;
2173 priv->js2[JS2_tPDN_DSM] = dbsc5_f_scale(priv, true,
2174 jedec_spec2[derate][JS2_tPDN_DSM].ps * 10UL, 0);
2175 priv->js2[JS2_tXSR_DSM] = dbsc5_f_scale(priv, true,
2176 jedec_spec2[derate][JS2_tXSR_DSM].ps * 10UL, 0);
2177 priv->js2[JS2_tXDSM_XP] = dbsc5_f_scale(priv, true,
2178 jedec_spec2[derate][JS2_tXDSM_XP].ps * 10UL, 0);
2179 priv->js2[JS2_tWLWCKOFF] = dbsc5_f_scale(priv, false, 14000, 5);
2180}
2181
2182/**
2183 * dbsc5_ddrtbl_calc() - Calculate JS1/JS2
2184 * @priv: Driver private data
2185 *
2186 * Determine jedec_spec1 configuration table based on priv->ddr_mbps
2187 * and priv->ddr_mbpsdiv. Calculate the value of the jedec_spec2
2188 * configuration table from priv->ddr_mbps and priv->ddr_mbpsdiv.
2189 */
2190static void dbsc5_ddrtbl_calc(struct renesas_dbsc5_dram_priv *priv)
2191{
2192 int i;
2193
2194 /* Search jedec_spec1 index */
2195 for (i = JS1_USABLEC_SPEC_LO; i < JS1_FREQ_TBL_NUM - 1; i++)
2196 if (js1[i].fx3 * 2 * priv->ddr_mbpsdiv >= priv->ddr_mbps * 3)
2197 break;
2198
Marek Vasutbc90b9c2025-03-16 14:51:40 +01002199 priv->js1_ind = clamp(i, 0, JS1_USABLEC_SPEC_HI);
Marek Vasut1f7ba642024-12-12 14:34:30 +01002200
2201 priv->RL = js1[priv->js1_ind].RLset1;
2202 priv->WL = js1[priv->js1_ind].WLsetA;
2203
2204 /* Calculate jedec_spec2 */
2205 dbsc5_f_scale_js2(priv);
2206};
2207
2208/**
2209 * dbsc5_ddrtbl_load() Load table data into DDR registers
2210 * @dev: DBSC5 device
2211 *
2212 * Copy the base configuration table to a local array. Change PI register table
2213 * settings to match priv->ddr_mbps and priv->ddr_mbpsdiv.
2214 *
2215 * If the set value vref_r is not 0, change the "Read Vref (SoC side) Training range"
2216 * setting in the configuration table.
2217 *
2218 * If the set value vref_w is not 0, change the "Write Vref (MR14, MR15) Training range"
2219 * setting in the configuration table.
2220 *
2221 * If the set value vref_ca is not 0, change the "CA Vref (MR12) Training range"
2222 * setting in the configuration table.
2223 *
2224 * If priv->ddr_mbps/priv->ddr_mbpsdiv is less than 5120,
2225 * change the contents of the PHY register setting table.
2226 * If priv->ddr_mbps/priv->ddr_mbpsdiv is less than 4576,
2227 * change the contents of the PHY register setting table.
2228 *
2229 * Reflect the contents of the configuration table in the register.
2230 */
2231static void dbsc5_ddrtbl_load(struct udevice *dev)
2232{
2233 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
2234 const struct dbsc5_table_patch dbsc5_table_patch_adr_g_mbps = {
2235 PHY_CAL_INTERVAL_COUNT_0, 10000 * priv->ddr_mbps / priv->ddr_mbpsdiv / 8 / 256,
2236 };
2237
2238 const struct dbsc5_table_patch dbsc5_table_patch_pi_js[] = {
2239 { PI_WRLAT_F2, priv->WL },
2240 { PI_TWCKENL_WR_ADJ_F2, (js1[priv->js1_ind].WCKENLW * 4) + 4 },
2241 { PI_TWCKENL_RD_ADJ_F2, (js1[priv->js1_ind].WCKENLR * 4) + 4 },
2242 { PI_TWCKPRE_STATIC_F2, (js1[priv->js1_ind].WCKPRESTA * 4) },
2243 { PI_TWCKPRE_TOGGLE_RD_F2, (js1[priv->js1_ind].WCKPRETGLR) * 4 },
2244 { PI_CASLAT_F2, priv->RL },
2245 { PI_TWCKENL_FS_ADJ_F2, (js1[priv->js1_ind].WCKENLF * 4) + 4 },
2246 { PI_TRFC_F2, priv->js2[JS2_tRFCab] },
2247 { PI_WRLVL_WCKOFF_F2, (priv->js2[JS2_tWLWCKOFF]) + 3 },
2248 { PI_WRLAT_ADJ_F2, (priv->WL * 4) + 2 },
2249 { PI_TCAENT_F2, priv->js2[JS2_tCAENTns] },
2250 { PI_TVREF_LONG_F2, (priv->js2[JS2_tCAENTns]) + 1 },
2251 { PI_TVREF_SHORT_F2, (priv->js2[JS2_tCAENTns]) + 1 },
2252 { PI_TRCD_F2, priv->js2[JS2_tRCD] },
2253 { PI_TRP_F2, priv->js2[JS2_tRPab] },
2254 { PI_TRTP_F2, js1[priv->js1_ind].nRBTP },
2255 { PI_TRAS_MIN_F2, priv->js2[JS2_tRAS] },
2256 { PI_TMRD_F2, (priv->js2[JS2_tMRD]) + 1 },
2257 { PI_TSR_F2, priv->js2[JS2_tSR] },
2258 { PI_TZQCAL_F2, priv->js2[JS2_tZQCALns] },
2259 { PI_TZQLAT_F2, priv->js2[JS2_tZQLAT] },
2260 { PI_TDQ72DQ_F2, priv->js2[JS2_tDQ72DQns] },
2261 { PI_MC_TRFC_F2, priv->js2[JS2_tRFCab] },
2262 };
2263
2264 const u32 vref_r = priv->dbsc5_board_config->bdcfg_vref_r;
2265 const struct dbsc5_table_patch dbsc5_table_patch_slice_vref_r[] = {
2266 { PHY_VREF_INITIAL_START_POINT, vref_r & 0xFF },
2267 { PHY_VREF_INITIAL_STOP_POINT, (vref_r & 0xFF00) >> 8 },
2268 { PHY_VREF_INITIAL_STEPSIZE, (vref_r & 0xFF0000) >> 16 }
2269 };
2270
2271 const u32 vref_w = priv->dbsc5_board_config->bdcfg_vref_w;
2272 const struct dbsc5_table_patch dbsc5_table_patch_pi_vref_w[] = {
2273 { PI_WDQLVL_VREF_INITIAL_START_POINT_F0, vref_w & 0xff },
2274 { PI_WDQLVL_VREF_INITIAL_START_POINT_F1, vref_w & 0xff },
2275 { PI_WDQLVL_VREF_INITIAL_START_POINT_F2, vref_w & 0xff },
2276 { PI_WDQLVL_VREF_INITIAL_STOP_POINT_F0, (vref_w & 0xff00) >> 8 },
2277 { PI_WDQLVL_VREF_INITIAL_STOP_POINT_F1, (vref_w & 0xff00) >> 8 },
2278 { PI_WDQLVL_VREF_INITIAL_STOP_POINT_F2, (vref_w & 0xff00) >> 8 }
2279 };
2280
2281 const u32 vref_ca = priv->dbsc5_board_config->bdcfg_vref_ca;
2282 const struct dbsc5_table_patch dbsc5_table_patch_pi_vref_ca[] = {
2283 { PI_CALVL_VREF_INITIAL_START_POINT_F0, vref_ca & 0xff },
2284 { PI_CALVL_VREF_INITIAL_START_POINT_F1, vref_ca & 0xff },
2285 { PI_CALVL_VREF_INITIAL_START_POINT_F2, vref_ca & 0xff },
2286 { PI_CALVL_VREF_INITIAL_STOP_POINT_F0, (vref_ca & 0xff00) >> 8 },
2287 { PI_CALVL_VREF_INITIAL_STOP_POINT_F1, (vref_ca & 0xff00) >> 8 },
2288 { PI_CALVL_VREF_INITIAL_STOP_POINT_F2, (vref_ca & 0xff00) >> 8 }
2289 };
2290
2291 int i, cs, slice;
2292 u32 adr;
2293
2294 /* Prepare register tables */
2295 memcpy(priv->DDR_PHY_SLICE_REGSET, DDR_PHY_SLICE_REGSET_V4H, sizeof(DDR_PHY_SLICE_REGSET_V4H));
2296 memcpy(priv->DDR_PHY_ADR_V_REGSET, DDR_PHY_ADR_V_REGSET_V4H, sizeof(DDR_PHY_ADR_V_REGSET_V4H));
2297 memcpy(priv->DDR_PHY_ADR_G_REGSET, DDR_PHY_ADR_G_REGSET_V4H, sizeof(DDR_PHY_ADR_G_REGSET_V4H));
2298 memcpy(priv->DDR_PI_REGSET, DDR_PI_REGSET_V4H, sizeof(DDR_PI_REGSET_V4H));
2299
2300 /* Adjust PI parameters */
2301 dbsc5_table_patch_set(priv->DDR_PHY_ADR_G_REGSET, false,
2302 &dbsc5_table_patch_adr_g_mbps, 1);
2303 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2304 dbsc5_table_patch_pi_js,
2305 ARRAY_SIZE(dbsc5_table_patch_pi_js));
2306
2307 if (priv->ddr_mbps < (3201 * priv->ddr_mbpsdiv)) {
2308 /* 2751-3200 */
2309 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2310 dbsc5_table_patch_slice_3200,
2311 ARRAY_SIZE(dbsc5_table_patch_slice_3200));
2312 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2313 dbsc5_table_patch_adr_v_3200,
2314 ARRAY_SIZE(dbsc5_table_patch_adr_v_3200));
2315 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2316 dbsc5_table_patch_pi_3200,
2317 ARRAY_SIZE(dbsc5_table_patch_pi_3200));
2318 } else if (priv->ddr_mbps < (3734 * priv->ddr_mbpsdiv)) {
2319 /* 3201-3733 */
2320 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2321 dbsc5_table_patch_slice_3733,
2322 ARRAY_SIZE(dbsc5_table_patch_slice_3733));
2323 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2324 dbsc5_table_patch_adr_v_3733,
2325 ARRAY_SIZE(dbsc5_table_patch_adr_v_3733));
2326 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2327 dbsc5_table_patch_pi_3733,
2328 ARRAY_SIZE(dbsc5_table_patch_pi_3733));
2329 } else if (priv->ddr_mbps < (4268 * priv->ddr_mbpsdiv)) {
2330 /* 3734-4267 */
2331 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2332 dbsc5_table_patch_slice_4266,
2333 ARRAY_SIZE(dbsc5_table_patch_slice_4266));
2334 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2335 dbsc5_table_patch_adr_v_4266,
2336 ARRAY_SIZE(dbsc5_table_patch_adr_v_4266));
2337 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2338 dbsc5_table_patch_pi_4266,
2339 ARRAY_SIZE(dbsc5_table_patch_pi_4266));
2340 } else if (priv->ddr_mbps < (4801 * priv->ddr_mbpsdiv)) {
2341 /* 4269-4800 */
2342 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2343 dbsc5_table_patch_slice_4800,
2344 ARRAY_SIZE(dbsc5_table_patch_slice_4800));
2345 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2346 dbsc5_table_patch_adr_v_4800,
2347 ARRAY_SIZE(dbsc5_table_patch_adr_v_4800));
2348 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2349 dbsc5_table_patch_pi_4800,
2350 ARRAY_SIZE(dbsc5_table_patch_pi_4800));
2351 } else if (priv->ddr_mbps < (5501 * priv->ddr_mbpsdiv)) {
2352 /* 4801 - 5500 */
2353 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2354 dbsc5_table_patch_slice_5500,
2355 ARRAY_SIZE(dbsc5_table_patch_slice_5500));
2356 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2357 dbsc5_table_patch_adr_v_5500,
2358 ARRAY_SIZE(dbsc5_table_patch_adr_v_5500));
2359 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2360 dbsc5_table_patch_pi_5500,
2361 ARRAY_SIZE(dbsc5_table_patch_pi_5500));
2362 } else if (priv->ddr_mbps < (6001 * priv->ddr_mbpsdiv)) {
2363 /* 5501 - 6000 */
2364 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2365 dbsc5_table_patch_slice_6000,
2366 ARRAY_SIZE(dbsc5_table_patch_slice_6000));
2367 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2368 dbsc5_table_patch_adr_v_6000,
2369 ARRAY_SIZE(dbsc5_table_patch_adr_v_6000));
2370 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2371 dbsc5_table_patch_pi_6000,
2372 ARRAY_SIZE(dbsc5_table_patch_pi_6000));
2373 }
2374
2375 for (cs = 0; cs < CS_CNT; cs++) {
2376 struct dbsc5_table_patch dbsc5_table_patch_pi_mr12[] = {
2377 { PI_DARRAY3_0_CSx_Fx[cs][2], js1[priv->js1_ind].MR1 },
2378 { PI_DARRAY3_1_CSx_Fx[cs][2], js1[priv->js1_ind].MR2 },
2379 };
2380
2381 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2382 dbsc5_table_patch_pi_mr12,
2383 ARRAY_SIZE(dbsc5_table_patch_pi_mr12));
2384 }
2385
2386 /* Read Vref (SoC side) Training range */
2387 if (priv->dbsc5_board_config->bdcfg_vref_r) {
2388 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2389 dbsc5_table_patch_slice_vref_r,
2390 ARRAY_SIZE(dbsc5_table_patch_slice_vref_r));
2391 }
2392
2393 /* Write Vref (MR14, MR15) Training range */
2394 if (priv->dbsc5_board_config->bdcfg_vref_w) {
2395 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2396 dbsc5_table_patch_pi_vref_w,
2397 ARRAY_SIZE(dbsc5_table_patch_pi_vref_w));
2398 }
2399
2400 /* CA Vref (MR12) Training range */
2401 if (priv->dbsc5_board_config->bdcfg_vref_ca) {
2402 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2403 dbsc5_table_patch_pi_vref_ca,
2404 ARRAY_SIZE(dbsc5_table_patch_pi_vref_ca));
2405 }
2406
2407 /* Low Freq setting */
2408 if (priv->ddr_mbps < (8 * 640 * priv->ddr_mbpsdiv)) {
2409 /* CAL_CLK(10-20MHz) */
2410 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2411 &dbsc5_table_patch_slice_mbpsdiv_640, 1);
2412 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2413 &dbsc5_table_patch_adr_v_mbpsdiv_640, 1);
2414 dbsc5_table_patch_set(priv->DDR_PHY_ADR_G_REGSET, false,
2415 &dbsc5_table_patch_adr_g_mbpsdiv_640, 1);
2416 }
2417
2418 if (priv->ddr_mbps < (8 * 572 * priv->ddr_mbpsdiv)) {
2419 /* CAL_CLK(10-20MHz) */
2420 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2421 &dbsc5_table_patch_slice_mbpsdiv_572, 1);
2422 dbsc5_table_patch_set(priv->DDR_PHY_ADR_G_REGSET, false,
2423 &dbsc5_table_patch_adr_g_mbpsdiv_572, 1);
2424 }
2425
2426 if (priv->ddr_mbps < (8 * 401 * priv->ddr_mbpsdiv)) {
2427 dbsc5_table_patch_set(priv->DDR_PHY_ADR_G_REGSET, false,
2428 dbsc5_table_patch_adr_g_mbpsdiv_400,
2429 ARRAY_SIZE(dbsc5_table_patch_adr_g_mbpsdiv_400));
2430 }
2431
2432 /* SET DATA SLICE TABLE */
2433 for (slice = 0; slice < SLICE_CNT; slice++) {
2434 adr = DDR_PHY_SLICE_REGSET_OFS_V4H + (DDR_PHY_SLICE_REGSET_SIZE_V4H * slice);
2435 for (i = 0; i < DDR_PHY_SLICE_REGSET_NUM_V4H; i++)
2436 dbsc5_reg_ddrphy_write_all(dev, adr + i, priv->DDR_PHY_SLICE_REGSET[i]);
2437 }
2438
2439 /* SET ADR SLICE TABLE */
2440 for (i = 0; i < DDR_PHY_ADR_V_REGSET_NUM_V4H; i++)
2441 dbsc5_reg_ddrphy_write_all(dev, DDR_PHY_ADR_V_REGSET_OFS_V4H + i, priv->DDR_PHY_ADR_V_REGSET[i]);
2442
2443 /* SET ADRCTRL SLICE TABLE */
2444 for (i = 0; i < DDR_PHY_ADR_G_REGSET_NUM_V4H; i++)
2445 dbsc5_reg_ddrphy_write_all(dev, DDR_PHY_ADR_G_REGSET_OFS_V4H + i, priv->DDR_PHY_ADR_G_REGSET[i]);
2446
2447 /* SET PI REGISTERS */
2448 for (i = 0; i < DDR_PI_REGSET_NUM_V4H; i++)
2449 dbsc5_reg_ddrphy_write_all(dev, DDR_PI_REGSET_OFS_V4H + i, priv->DDR_PI_REGSET[i]);
2450}
2451
2452/**
2453 * dbsc5_ddr_config() - Configure DDR registers
2454 * @dev: DBSC5 device
2455 *
2456 * Set up wiring for DQ and DM pins and VREF_DRIVING. Set the CA pin wiring
2457 * and ADR_CALVL_SWIZZLE settings. Make wiring settings for the CS pin. When
2458 * memory rank is 1, set RANK setting to 1 to disable CS training. Configure
2459 * the DATA_BYTE_SWAP setting.
2460 */
2461static void dbsc5_ddr_config(struct udevice *dev)
2462{
2463 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
2464 u32 ca_swap, cs_swap, dqs_swap;
2465 u32 ch, slice;
2466
2467 r_foreach_vch(dev, ch) {
2468 /* Board settings (DQ, DM, VREF_DRIVING) */
2469 dqs_swap = priv->dbsc5_board_config->ch[ch].bdcfg_dqs_swap;
2470 for (slice = 0; slice < SLICE_CNT; slice++) {
2471 dbsc5_ddr_setval_slice(dev, ch, slice, PHY_DQ_DM_SWIZZLE0,
2472 priv->dbsc5_board_config->ch[ch].bdcfg_dq_swap[slice]);
2473 dbsc5_ddr_setval_slice(dev, ch, slice, PHY_DQ_DM_SWIZZLE1,
2474 priv->dbsc5_board_config->ch[ch].bdcfg_dm_swap[slice]);
2475 dbsc5_ddr_setval_slice(dev, ch, slice, PHY_CALVL_VREF_DRIVING_SLICE,
2476 !((dqs_swap >> (4 * slice)) & 1));
2477 }
2478 dbsc5_ddr_setval(dev, ch, PHY_DATA_BYTE_ORDER_SEL,
2479 priv->dbsc5_board_config->ch[ch].bdcfg_dqs_swap | 0x76543200);
2480
2481 /* Board settings (CA, ADDR_MUX) */
2482 ca_swap = priv->dbsc5_board_config->ch[ch].bdcfg_ca_swap;
2483
2484 /* ADDR_MUX */
2485 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_0, ca_swap & 0xf);
2486 ca_swap >>= 4;
2487 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_1, ca_swap & 0xf);
2488 ca_swap >>= 4;
2489 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_2, ca_swap & 0xf);
2490 ca_swap >>= 4;
2491 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_3, ca_swap & 0xf);
2492 ca_swap >>= 4;
2493 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_4, ca_swap & 0xf);
2494 ca_swap >>= 4;
2495 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_5, ca_swap & 0xf);
2496 ca_swap >>= 4;
2497 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_6, ca_swap & 0xf);
2498 ca_swap >>= 4;
2499
2500 /* ADR_CALVL_SWIZZLE */
2501 ca_swap = priv->dbsc5_board_config->ch[ch].bdcfg_ca_swap;
2502 dbsc5_ddr_setval(dev, ch, PHY_ADR_CALVL_SWIZZLE0, ca_swap & 0x0fffffff);
2503
2504 /* Board settings (CS) */
2505 /* CKE_MUX */
2506 /* SoC CKE -> DRAM CS */
2507 cs_swap = priv->dbsc5_board_config->ch[ch].bdcfg_cs_swap;
2508 dbsc5_ddr_setval(dev, ch, PI_CKE_MUX_0, (cs_swap & 0xf) + 2);
2509 dbsc5_ddr_setval(dev, ch, PI_CKE_MUX_1, ((cs_swap >> 4) & 0xf) + 2);
2510 dbsc5_ddr_setval(dev, ch, PHY_CS_ACS_ALLOCATION_BIT2_2, (cs_swap & 0xf) + 1);
2511 dbsc5_ddr_setval(dev, ch, PHY_CS_ACS_ALLOCATION_BIT3_2, ((cs_swap >> 4) & 0xf) + 1);
2512
2513 /* Mask CS_MAP if RANK1 is not found */
2514 if (!(priv->ch_have_this_cs[1] & BIT(ch))) {
2515 dbsc5_ddr_setval(dev, ch, PHY_ADR_CALVL_RANK_CTRL, 0x0);
2516 for (slice = 0; slice < SLICE_CNT; slice++)
2517 dbsc5_ddr_setval_slice(dev, ch, slice, PHY_PER_CS_TRAINING_EN, 0x0);
2518 }
2519 }
2520
2521 r_foreach_vch(dev, ch) {
2522 /* DATA_BYTE_SWAP */
2523 dqs_swap = priv->dbsc5_board_config->ch[ch].bdcfg_dqs_swap;
2524
2525 dbsc5_ddr_setval(dev, ch, PI_DATA_BYTE_SWAP_EN, 0x1);
2526 dbsc5_ddr_setval(dev, ch, PI_DATA_BYTE_SWAP_SLICE0, dqs_swap & 0xf);
2527 dbsc5_ddr_setval(dev, ch, PI_DATA_BYTE_SWAP_SLICE1, (dqs_swap >> 4) & 0xf);
2528
2529 if (!(priv->ch_have_this_cs[1] & BIT(ch)))
2530 dbsc5_ddr_setval(dev, ch, PI_CS_MAP, 0x1);
2531 }
2532}
2533
2534/**
2535 * dbsc5_dbsc_regset_pre() - Configure primary DDR registers
2536 * @dev: DBSC5 device
2537 *
2538 * Set SDRAM type, Burst length, and PHY type. Frequency mode setting.
2539 * Write SDRAM configuration contents to registers.
2540 */
2541static void dbsc5_dbsc_regset_pre(struct udevice *dev)
2542{
2543#define DBMEMCONF_REG(d3, row, bg, bank, col, dw) \
2544 (((d3) << 30) | ((row) << 24) | ((bg) << 20) | ((bank) << 16) | ((col) << 8) | (dw))
2545#define DBMEMCONF_REGD(density) /* 16bit */ \
2546 DBMEMCONF_REG(((density) % 2), ((((density) + 1) / 2) + (28 - 2 - 2 - 10 - 1)), 2, 2, 10, 1)
2547
2548 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
2549 void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
2550 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
2551 u32 density;
2552 u32 ch, cs;
2553
2554 /* Primary settings */
2555 /* LPDDR5, BL=16, DFI interface */
2556 dbsc5_reg_write(regs_dbsc_d + DBSC_DBMEMKIND, 0xC);
2557 dbsc5_reg_write(regs_dbsc_a + DBSC_DBMEMKINDA, 0xC);
2558 dbsc5_reg_write(regs_dbsc_d + DBSC_DBBL, 0x2);
2559 dbsc5_reg_write(regs_dbsc_a + DBSC_DBBLA, 0x2);
2560 dbsc5_reg_write(regs_dbsc_d + DBSC_DBPHYCONF0, 0x1);
2561
2562 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCONF0, 0x1);
2563
2564 /* FREQRATIO=2 */
2565 dbsc5_reg_write(regs_dbsc_d + DBSC_DBSYSCONF1, 0x20000);
2566 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCONF1A, 0x0);
2567
2568 dbsc5_reg_write(regs_dbsc_d + DBSC_DBSYSCONF2, 0x1);
2569 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCONF2A, 0x241);
2570
2571 r_foreach_ech(ch) {
2572 for (cs = 0; cs < CS_CNT; cs++) {
2573 if (priv->ddr_density[ch][cs] == 0xFF) {
2574 writel(0x00, regs_dbsc_d + DBSC_DBMEMCONF(ch, cs));
2575 writel(0x00, regs_dbsc_a + DBSC_DBMEMCONFA(ch, cs));
2576 } else {
2577 density = priv->ddr_density[ch][cs];
2578 writel(DBMEMCONF_REGD(density),
2579 regs_dbsc_d + DBSC_DBMEMCONF(ch, cs));
2580 writel(DBMEMCONF_REGD(density),
2581 regs_dbsc_a + DBSC_DBMEMCONFA(ch, cs));
2582 }
2583 }
2584 }
2585}
2586
2587/**
2588 * dbsc5_dbsc_regset() - Set DBSC timing parameters
2589 * @dev: DBSC5 device
2590 *
2591 * Set the timing registers of the DBSC.
2592 * Configure Scheduler settings.
2593 */
2594static void dbsc5_dbsc_regset(struct udevice *dev)
2595{
2596 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
2597 void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
2598 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
2599 u32 tmp[4];
2600
2601 /* DBTR0.CL : RL */
2602 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(0), priv->RL);
2603
2604 /* DBTR1.CWL : WL */
2605 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(1), priv->WL);
2606
2607 /* DBTR2.AL = 0 */
2608 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(2), 0x0);
2609
2610 /* DBTR3.TRCD: tRCD */
2611 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(3), priv->js2[JS2_tRCD]);
2612
2613 /* DBTR4.TRPA,TRP: tRPab,tRPpb */
2614 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(4), (priv->js2[JS2_tRPab] << 16) |
2615 priv->js2[JS2_tRPpb]);
2616
2617 /* DBTR5.TRC : tRCpb */
2618 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(5), priv->js2[JS2_tRCpb]);
2619
2620 /* DBTR6.TRAS : tRAS */
2621 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(6), priv->js2[JS2_tRAS]);
2622
2623 /* DBTR7.TRRD : tRRD */
2624 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(7), ((priv->js2[JS2_tRRD] - 1) << 16) |
2625 (priv->js2[JS2_tRRD] - 1));
2626
2627 /* DBTR8.TFAW : tFAW */
2628 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(8), priv->js2[JS2_tFAW] - 1);
2629
2630 /* DBTR9.TRDPR: nRBTP */
2631 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(9), js1[priv->js1_ind].nRBTP);
2632
2633 /* DBTR10.TWR : nWR */
2634 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(10), js1[priv->js1_ind].nWR);
2635
2636 /*
2637 * DBTR11.TRDWR : RL + BL/n_max + RU(tWCK2DQO(max)/tCK) +
2638 * RD(tRPST/tCK) - ODTLon - RD(tODTon(min)/tCK) + 1 + feature
2639 */
2640 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(11),
2641 priv->RL + 4 + priv->js2[JS2_tWCK2DQO_HF] -
Marek Vasut0da0bd22025-03-16 14:51:41 +01002642 js1[priv->js1_ind].ODTLon - priv->js2[JS2_tODTon_min] + 2);
Marek Vasut1f7ba642024-12-12 14:34:30 +01002643
2644 /* DBTR12.TWRRD_S : WL + BL/2 + tWTR_S, TWRRD_L : WL + BL + tWTR_L */
2645 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(12),
2646 ((priv->WL + 2 + priv->js2[JS2_tWTR_S]) << 16) |
2647 (priv->WL + 4 + priv->js2[JS2_tWTR_L]));
2648
2649 /* DBTR13.TRFCAB : tRFCab */
2650 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(13), priv->js2[JS2_tRFCab]);
2651
2652 /* DBTR14.TCSCAL,TCKEHDLL,tCKEH : tCSCAL,tXP,tXP */
2653 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(14), (priv->js2[JS2_tCSCAL] << 24) |
2654 (priv->js2[JS2_tXP] << 16) |
2655 priv->js2[JS2_tXP]);
2656
2657 /* DBTR15.TESPD,TCKESR,TCKEL : tESPD = 2,tSR,tSR */
2658 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(15), (0x02 << 24) |
2659 (priv->js2[JS2_tSR] << 16) |
2660 priv->js2[JS2_tSR]);
2661
2662 /* DBTR16 */
2663 /* wdql(tphy_wrlat + tphy_wrdata) */
2664 tmp[0] = (priv->WL * 4) - 1 + 5;
2665 /* dqenltcy(tphy_wrlat) */
2666 tmp[1] = (priv->WL * 4) - 2 - 2 + 5;
2667 /* dql(tphy_rdlat + trddata_en) RL * 4 + phy_rptr_update + phy_rddqs_latency_adjust + 39 */
2668 tmp[2] = (priv->RL * 4) +
2669 dbsc5_ddrtbl_getval(priv->DDR_PHY_SLICE_REGSET, PHY_RPTR_UPDATE, false) +
2670 dbsc5_ddrtbl_getval(priv->DDR_PHY_SLICE_REGSET, PHY_RDDQS_LATENCY_ADJUST, false) +
2671 39;
2672 /* dqienltncy(trddata_en) RL * 4 - phy_rddata_en_dly_X + 4 * phy_wck_freq_ratio_X */
2673 tmp[3] = (priv->RL * 4) + 4 -
2674 dbsc5_ddrtbl_getval(priv->DDR_PHY_SLICE_REGSET, PHY_RDDATA_EN_DLY, false);
2675 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(16), (tmp[3] << 24) | (tmp[2] << 16) |
2676 (tmp[1] << 8) | tmp[0]);
2677
2678 /* DBTR17.TMODRD,TMOD: tMRR,tMRW */
2679 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(17), (priv->js2[JS2_tMRR] << 24) |
2680 (priv->js2[JS2_tMRW] << 16));
2681
2682 /* DBTR18. RODTL, RODTA = 0 */
2683 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(18), 0x0);
2684
2685 /* DBTR19. TZQCL, TZQCS = 0 */
2686 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(19), 0x0);
2687
2688 /* DBTR20.TXSDLL, TXS : tXSR,tXSR */
2689 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(20), ((priv->js2[JS2_tXSR]) << 16) |
2690 priv->js2[JS2_tXSR]);
2691
2692 /* DBTR21.TCCD */
2693 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(21), (priv->ddr_tccd << 16) |
2694 (priv->ddr_tccd * 2));
2695
2696 /* DBTR22.TZQCAL,TZQLAT : tZQCAL,tZQLAT */
2697 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(22), (priv->js2[JS2_tZQCALns] << 16) | priv->js2[JS2_tZQLAT]);
2698
2699 /* DBTR23. RRSPC = 0 */
2700 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(23), 0x0);
2701
2702 /* DBTR24 */
2703 /* WRCSLAT(tphy_wrcslat) */
2704 tmp[0] = (priv->WL * 4) - 2;
2705 /* WRCSGAP(tphy_wrcsgap) */
2706 tmp[1] = 0x0C;
2707 /* RDCSLAT(tphy_rdcslat) */
2708 tmp[2] = priv->RL * 4;
2709 /* RDCSGAP(tphy_rdcsgap) */
2710 tmp[3] = 0x0C;
2711 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(24), (tmp[3] << 24) | (tmp[2] << 16) |
2712 (tmp[1] << 8) | tmp[0]);
2713
2714 /* DBTR25. TWDQLVLDIS = 0 */
2715 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(25), 0x0);
2716
2717 /* DBTR26. TWCK2DQOOSC,TDQSOSC : WCK2DQI interval timer run time, WCK2DQO interval timer run time */
2718 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(26), 0x0);
2719
2720 /* DBTR27.TPDN : tPDN */
2721 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(27), priv->js2[JS2_tPDN]);
2722
2723 /* DBTR28.txsrdsm : tXSR_DSM */
2724 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(28), priv->js2[JS2_tXSR_DSM]);
2725
2726 /* DBTR29.tdsmxp : tXDSM_XP */
2727 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(29), priv->js2[JS2_tXDSM_XP]);
2728
2729 /* DBTR30.TCMDPD : tCMDPD = 3 */
2730 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(30), 0x3);
2731
2732 /* DBTR31.TWCK2DQOMAX,TWCK2DQIMAX : tWCK2DQI/O_HF/LF */
2733 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(31), (priv->js2[JS2_tWCK2DQO_HF] << 4) |
2734 priv->js2[JS2_tWCK2DQI_HF]);
2735
2736 /* DBTR32 */
2737 /* twckenr */
2738 tmp[0] = (js1[priv->js1_ind].WCKENLR * 4) + 4 - 1;
2739 /* twckenw */
2740 tmp[1] = (js1[priv->js1_ind].WCKENLW * 4) + 4 - 1;
2741 /* twckenlf */
2742 tmp[2] = (js1[priv->js1_ind].WCKENLF * 4) + 4;
2743 /* twckpresta */
2744 tmp[3] = js1[priv->js1_ind].WCKPRESTA * 4;
2745 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(32), (tmp[3] << 24) | (tmp[2] << 16) |
2746 (tmp[1] << 8) | tmp[0]);
2747
2748 /* DBTR33 */
2749 /* TWCKTGL */
2750 tmp[0] = 4;
2751 /* TWCKDIS (RL+ bl/n_max) * 4 + RU(tWCKPST/tWCK) : tWCKPST = 2.5(MR10[3:2]) */
2752 tmp[1] = ((priv->RL + 4) * 4) + 3;
2753 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(33), (tmp[1] << 8) | tmp[0]);
2754
2755 /* DBTR34 */
2756 /* TWCKSUS = 4 */
2757 tmp[0] = 4;
2758 /* TWCKPST RU(tWCKPST/tCK) : tWCKPST=2.5(MR10[3:2]) */
2759 tmp[1] = 1;
2760 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(34), (tmp[1] << 8) | tmp[0]);
2761
2762 /* DBTR35 */
2763 /* TRD2WCKOFF RL + BL/n_max + RD(tWCKPST/tCK) + 1 */
2764 tmp[0] = priv->RL + 4 + 0 + 1;
2765 /* TWR2WCKOFF WL + BL/n_max + RD(tWCKPST/tCK) + 1 */
2766 tmp[1] = priv->WL + 4 + 0 + 1;
2767 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(35), (tmp[1] << 16) | tmp[0]);
2768
2769 /* DBTR36 */
2770 /* TWSSUSWRX : CAS(WCKSUS)WRX */
2771 tmp[0] = 3;
2772 /* TWSOFFWRX : CAS(WS_OFF)WRX */
2773 tmp[1] = 3;
2774 /* TWSFSWRX : CAS(WS_FS)WRX */
2775 tmp[2] = 2;
2776 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(36), (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2777
2778 /* DBTR37 */
2779 /* tOSCO */
2780 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(37), priv->js2[JS2_tOSCODQI]);
2781
2782 /* DBRNK2 */
2783 /* RNKRR = 12 */
2784 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRNK(2), 0xCC);
2785
2786 /* DBRNK3 */
2787 /* RNKRW = 6 */
2788 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRNK(3), 0x66);
2789
2790 /* DBRNK4 */
2791 /* RNKWR = 6 */
2792 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRNK(4), 0x66);
2793
2794 /* DBRNK5 */
2795 /* RNKWW = 14 */
2796 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRNK(5), 0xEE);
2797
2798 /* Timing registers for Scheduler */
2799 /* SCFCTST0 */
2800 /* SCPREACT */
2801 tmp[0] = priv->js2[JS2_tRPpb] * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2802 priv->ddr_mbps / priv->bus_clkdiv;
2803 /* SCACTRDWR */
2804 tmp[1] = (priv->WL + 2 + 1 + js1[priv->js1_ind].nWR + priv->js2[JS2_tRPpb]) *
2805 priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2806 priv->ddr_mbps / priv->bus_clkdiv;
2807 /* SCRDACRT */
2808 tmp[2] = ((js1[priv->js1_ind].nRBTP + 2) + priv->js2[JS2_tRPpb]) *
2809 priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2810 priv->ddr_mbps / priv->bus_clkdiv;
2811 /* SCACTACT */
2812 tmp[3] = priv->js2[JS2_tRCpb] * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2813 priv->ddr_mbps / priv->bus_clkdiv;
2814 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSCHFCTST0, (tmp[3] << 24) | (tmp[2] << 16) |
2815 (tmp[1] << 8) | tmp[0]);
2816
2817 /* SCFCTST1 */
2818 /* SCASYNCOFS */
2819 tmp[0] = 12;
2820 /* SCACTRDWR */
2821 tmp[1] = priv->js2[JS2_tRCD] * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2822 priv->ddr_mbps / priv->bus_clkdiv;
2823 /* SCWRRD */
2824 tmp[2] = (readl(regs_dbsc_d + DBSC_DBTR(12)) & 0xFF) * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2825 priv->ddr_mbps / priv->bus_clkdiv;
2826 /* SCRDWR */
2827 tmp[3] = (readl(regs_dbsc_d + DBSC_DBTR(11)) & 0xFF) * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2828 priv->ddr_mbps / priv->bus_clkdiv;
2829 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSCHFCTST1, (tmp[3] << 24) | (tmp[2] << 16) |
2830 (tmp[1] << 8) | tmp[0]);
2831
2832 /* DBSCHRW1 */
2833 /* SCTRFCAB */
2834 tmp[0] = (priv->js2[JS2_tRFCab] + priv->js2[JS2_tZQLAT]) *
2835 priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2836 priv->ddr_mbps / priv->bus_clkdiv;
2837 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSCHRW1, tmp[0]);
2838
2839 /* DBSCHTR0 */
2840 /* SCDT0 */
2841 tmp[0] = (4 * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2842 priv->ddr_mbps / priv->bus_clkdiv) - 1;
2843 /* SCDT1 */
2844 tmp[1] = (8 * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2845 priv->ddr_mbps / priv->bus_clkdiv) - 1;
2846 /* SCDT2 */
2847 tmp[2] = (12 * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2848 priv->ddr_mbps / priv->bus_clkdiv) - 1;
2849 /* SCDT3 */
2850 tmp[3] = (16 * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2851 priv->ddr_mbps / priv->bus_clkdiv) - 1;
2852 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSCHTR0, (tmp[3] << 24) | (tmp[2] << 16) |
2853 (tmp[1] << 8) | tmp[0]);
2854
2855 /* QOS and CAM */
2856 dbsc5_reg_write(regs_dbsc_a + DBSC_DBBCAMDIS, 0x1);
2857}
2858
2859/**
2860 * dbsc5_dbsc_regset_post() - Set DBSC registers
2861 * @dev: DBSC5 device
2862 *
2863 * If memory rank is 2, CS_TRAINING_EN is set to the other side.
2864 * Configure DBI read/write settings. Execute DRAM refresh settings.
2865 * Set WTmode of DFI PHY to OFF. Set up PHY Periodic Write DQ training.
2866 * Set WTmode of DFI PHY to ON. Calibration settings for PHY PAD.
2867 * Set SDRAM calibration. Make DFI Control Update Setting settings.
2868 * In the case of WARM_BOOT, cancel the self-refresh setting.
2869 * Enable SDRAM auto refresh. Set up PHY Periodic Write DQ training.
2870 * Enable access to SDRAM.
2871 */
2872static void dbsc5_dbsc_regset_post(struct udevice *dev)
2873{
2874 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
2875 void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
2876 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
2877 /* Average periodic refresh interval/Average Refresh Interval [ns] */
2878 const u32 dbsc_refint = 1920;
2879 /* 0: Average interval is REFINT, 1: Average interval is 1/2 REFINT */
2880 const u32 dbsc_refints = 0;
2881 /* Periodic-WriteDQ/ReadDQ Training Interval [us] */
2882 const u32 periodic_training_interval = 20000;
2883 u32 phymster_req_interval;
2884 u32 ch, slice;
2885 u32 clk_count;
2886 u32 refcycle;
2887 u32 ctrl_clk;
2888 u32 reg;
2889
2890 if ((renesas_get_cpu_rev_integer() < 3) && priv->ch_have_this_cs[1]) {
2891 r_foreach_vch(dev, ch) {
2892 for (slice = 0; slice < SLICE_CNT; slice++) {
2893 dbsc5_ddr_setval_slice(dev, ch, slice,
2894 PHY_PER_CS_TRAINING_EN,
2895 0x0);
2896 }
2897 }
2898 }
2899
2900 dbsc5_reg_write(regs_dbsc_d + DBSC_DBDBICNT, 0x3);
2901
2902 /* set REFCYCLE */
2903 refcycle = dbsc_refint * priv->ddr_mbps / 8000 / priv->ddr_mbpsdiv;
2904 /* refpmax=8 */
2905 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRFCNF1, (refcycle & 0xFFFF) | BIT(19));
2906 /* refpmin=1 */
2907 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRFCNF2, dbsc_refints | BIT(16));
2908
2909 dbsc5_reg_write(regs_dbsc_d + DBSC_DBDFIPMSTRCNF, 0x0);
2910
2911 /* Periodic-WriteDQ Training setting */
2912 dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_EN_F2, 0x3);
2913 dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_VREF_EN, 0x0);
2914 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_DATA_DC_WDQLVL_ENABLE, 0x0);
2915 dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_PERIODIC, 0x1);
2916
2917 /* Periodic-ReadDQ Training setting */
2918 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_EN_F2, 0x3);
2919 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_VREF_EN_F2, 0x0);
2920 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDLVL_DLY_STEP, 0x4);
2921 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_PERIODIC, 0x1);
2922
2923 /* DFI_PHYMSTR_ACK , WTmode = b'01 */
2924 dbsc5_reg_write(regs_dbsc_d + DBSC_DBDFIPMSTRCNF, 0x11);
2925
2926 /* periodic SoC zqcal enable */
2927 reg = dbsc5_ddrtbl_getval(priv->DDR_PHY_ADR_G_REGSET, PHY_CAL_MODE_0, false);
2928 dbsc5_ddr_setval_all_ch(dev, PHY_CAL_MODE_0, reg | BIT(1));
2929
2930 /* Periodic dram zqcal enable */
2931 dbsc5_reg_write(regs_dbsc_d + DBSC_DBCALCNF, 0x1000010);
2932
2933 /* Periodic phy ctrl update enable */
2934 dbsc5_reg_write(regs_dbsc_d + DBSC_DBDFICUPDCNF, 0x504C0001);
2935
2936 /* Set Auto Refresh */
2937 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRFEN, 0x1);
2938
2939 /* Periodic-WriteDQ/ReadDQ Training Interval setting */
2940 phymster_req_interval = periodic_training_interval - 3000;
2941 clk_count = 1024 - (dbsc5_ddrtbl_getval(priv->DDR_PI_REGSET, PI_LONG_COUNT_MASK, true) * 32);
2942 ctrl_clk = priv->ddr_mbps / priv->ddr_mbpsdiv / 8;
2943 reg = phymster_req_interval * ctrl_clk / clk_count;
2944
2945 dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_INTERVAL, reg);
2946
2947 /* DRAM access enable */
2948 dbsc5_reg_write(regs_dbsc_a + DBSC_DBACEN, 0x1);
2949}
2950
2951/**
2952 * dbsc5_pi_training() - Training by PI
2953 * @dev: DBSC5 device
2954 *
2955 * Enable WCK signal training and read gate training. Start PI training.
2956 * After DFI initialization for all channels is once turned off, turned
2957 * on all chennels of it. Power down the DRAM device once and then release
2958 * the power down mode. Perform training in low frequency mode and training
2959 * in high frequency mode. Wait for the DFI training completion status
2960 * bit to stand until the time limit. Turn off DFI initialization for all
2961 * channels. Turn off WTMODE of DFI PHY. Check if CA/CS Training has failed.
2962 * Check if Wrlvl training is in error. If an error can be confirmed from
2963 * the check result, the result is returned as a return value. Clear the
2964 * status register for PI training.
2965 */
2966static u32 dbsc5_pi_training(struct udevice *dev)
2967{
2968 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
2969 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
2970 const int retry_max = 0x10000;
2971 u32 ca_training_ng = 0;
2972 u32 wr_training_ng = 0;
2973 u32 phytrainingok = 0;
2974 u32 complete_ng = 0;
2975 bool frqchg_req;
2976 u32 ch, reg;
2977 int retry;
2978 int ret;
2979
2980 /* Init start */
2981 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_EN_F2, 0x0);
2982 dbsc5_ddr_setval_all_ch(dev, PI_WRDCM_LVL_EN_F2, 0x0);
2983 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_EN_F2, 0x0);
2984 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_EN_F2, 0x0);
2985 dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_EN_F2, 0x0);
2986 dbsc5_ddr_setval_all_ch(dev, PI_DFS_INITIALIZATION_SEQ_9, 0x0);
2987 dbsc5_ddr_setval_all_ch(dev, PI_DFS_INITIALIZATION_SEQ_10, 0x0);
2988
2989 /* PI_START */
2990 dbsc5_ddr_setval_all_ch(dev, PI_START, 0x1);
2991
2992 r_foreach_vch(dev, ch)
2993 writel(0x20, regs_dbsc_d + DBSC_DBDFICNT(ch));
2994
2995 r_foreach_vch(dev, ch)
2996 writel(0x21, regs_dbsc_d + DBSC_DBDFICNT(ch));
2997
2998 /* Dummy PDE */
2999 dbsc5_send_dbcmd2(dev, 0x8840000);
3000
3001 /* PDX */
3002 dbsc5_send_dbcmd2(dev, 0x8840001);
3003
3004 /* Wait init_complete */
3005 for (retry = 0; retry < retry_max; retry++) {
3006 frqchg_req = false;
3007 for (ch = 0; ch < DRAM_CH_CNT; ch++) {
3008 if (!((~phytrainingok & priv->ddr_phyvalid) & BIT(ch)))
3009 continue;
3010
3011 if (!(readl(regs_dbsc_d + DBSC_DBPDSTAT0(ch)) & BIT(0)))
3012 continue;
3013
3014 frqchg_req = true;
3015 break;
3016 }
3017
3018 if (frqchg_req) {
3019 ret = dbsc5_clk_pll3_freq(dev);
3020 if (ret)
3021 break;
3022 } else {
3023 r_foreach_vch(dev, ch) {
3024 if (readl(regs_dbsc_d + DBSC_DBDFISTAT(ch)) & BIT(0))
3025 phytrainingok |= BIT(ch);
3026 }
3027
3028 if (phytrainingok == priv->ddr_phyvalid)
3029 break;
3030 }
3031 }
3032
3033 /*
3034 * dbdficnt0:
3035 * dfi_dram_clk_disable=0
3036 * dfi_frequency = 0
3037 * freq_ratio = 10 (4:1)
3038 * init_start =0
3039 */
3040 r_foreach_vch(dev, ch)
3041 writel(0x20, regs_dbsc_d + DBSC_DBDFICNT(ch));
3042
3043 /* DFI_PHYMSTR_ACK */
3044 dbsc5_reg_write(regs_dbsc_d + DBSC_DBDFIPMSTRCNF, 0x1);
3045
3046 /* Error check */
3047 r_foreach_vch(dev, ch) {
3048 /* CA/CS Training Error Check */
3049 /* PI_CALVL_ERROR_BIT */
3050 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(4);
3051 /* Error on decrement/increment pass */
3052 reg |= dbsc5_ddr_getval(dev, ch, PHY_ADR_CALVL_OBS1) & (0x3 << 30);
3053 /* Start outside of initial search range */
3054 reg |= dbsc5_ddr_getval(dev, ch, PHY_ADR_CALVL_OBS2) & (0x3 << 24);
3055 /* CSlvl error */
3056 reg |= dbsc5_ddr_getval(dev, ch, PHY_CSLVL_OBS1) & (0xF << 28);
3057 if (reg) {
3058 ca_training_ng |= BIT(ch);
3059 printf("%s pi_training_error:1\n", __func__);
3060 }
3061
3062 /* Wrlvl Error Check */
3063 /* PI_WRLVL_ERROR_BIT */
3064 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(3);
3065 /* SLICE0 wrlvl error */
3066 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_STATUS_OBS) & BIT(12);
3067 /* SLICE1 wrlvl error */
3068 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_STATUS_OBS) & BIT(12);
3069 /* SLICE0 wrlvl error */
3070 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_ERROR_OBS);
3071 /* SLICE1 wrlvl error */
3072 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_ERROR_OBS);
3073 if (reg) {
3074 wr_training_ng |= BIT(ch);
3075 printf("%s pi_training_error:2\n", __func__);
3076 }
3077 }
3078
3079 complete_ng = (wr_training_ng | ca_training_ng);
3080 if (complete_ng)
3081 return ~complete_ng;
3082
3083 /* PI_INT_ACK assert */
3084 r_foreach_vch(dev, ch) {
3085 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
3086 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
3087 }
3088
3089 return phytrainingok;
3090}
3091
3092/**
3093 * dbsc5_write_leveling_adjust() - Write Leveling Cycle Adjust
3094 * @dev: DBSC5 device
3095 *
3096 * Get delay value from the result write leveling of slice 0 and 1.
3097 * Calculate latency of dfi_wrdata_en / dfi_wrdata / dfi_wrdata_mask
3098 * signals based on delay values.
3099 */
3100static void dbsc5_write_leveling_adjust(struct udevice *dev)
3101{
3102 u32 result_hard0, result_hard1;
3103 u32 avg, avg_frac, avg_cycle;
3104 u32 ch;
3105
3106 r_foreach_vch(dev, ch) {
3107 /* SLICE0 */
3108 result_hard0 = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_HARD0_DELAY_OBS);
3109 result_hard1 = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_HARD1_DELAY_OBS);
3110
3111 avg = result_hard0 + result_hard1;
3112 if (result_hard0 > result_hard1)
3113 avg += 0x400;
3114 avg /= 2;
3115
3116 avg_frac = avg & 0xFF;
3117 avg_cycle = (avg >> 8) & 0x3;
3118
3119 if (avg_cycle == 0x3) {
3120 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_DEC, 0x1);
3121 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_ADD, 0x0);
3122 } else {
3123 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_DEC, 0x0);
3124 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_ADD, avg_cycle);
3125 }
3126 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_FRAC, avg_frac);
3127
3128 /* SLICE1 */
3129 result_hard0 = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_HARD0_DELAY_OBS);
3130 result_hard1 = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_HARD1_DELAY_OBS);
3131
3132 avg = result_hard0 + result_hard1;
3133 if (result_hard0 >= result_hard1)
3134 avg += 0x400;
3135 avg /= 2;
3136 avg_frac = avg & 0xFF;
3137 avg_cycle = (avg >> 8) & 0x3;
3138
3139 if (avg_cycle == 0x3) {
3140 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_DEC, 0x1);
3141 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_ADD, 0x0);
3142 } else {
3143 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_DEC, 0x0);
3144 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_ADD, avg_cycle);
3145 }
3146 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_FRAC, avg_frac);
3147 }
3148
3149 dbsc5_ddr_setval_all_ch_all_slice(dev, SC_PHY_WCK_CALC, 0x1);
3150}
3151
3152/**
3153 * dbsc5_wl_gt_training() - Re-run Write Leveling & Read Gate Training
3154 * @dev: DBSC5 device
3155 *
3156 * Set CA leveling OFF, read gate leveling ON, write gate leveling ON,
3157 * PI dram wck training ON. Perform PI_DFS configuration. Start PI
3158 * frequency training in manual mode. Perform training in high-frequency
3159 * mode. Check for Write leveling Error and Gate leveling Error. If an
3160 * error is identified, the resulting value is inverted and returned.
3161 * Clear the PI status register.
3162 */
3163static u32 dbsc5_wl_gt_training(struct udevice *dev)
3164{
3165 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3166 const int retry_max = 0x10000;
3167 u32 gt_training_ng = 0;
3168 u32 wr_training_ng = 0;
3169 u32 phytrainingok = 0;
3170 u32 complete_ng = 0;
3171 int retry, ret;
3172 u32 ch, reg;
3173
3174 dbsc5_ddr_setval_all_ch(dev, PI_CALVL_EN_F2, 0x0);
3175 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_EN_F2, 0x1);
3176
3177 dbsc5_ddr_setval_all_ch(dev, PI_DFS_ENTRY_SEQ_0, 0x181F0000);
3178 dbsc5_ddr_setval_all_ch(dev, PI_DFS_INITIALIZATION_SEQ_1, 0x0);
3179 dbsc5_ddr_setval_all_ch(dev, PI_TRAIN_ALL_FREQ_REQ, 0x1);
3180
3181 /* Freq Change High to High*/
3182 ret = dbsc5_clk_pll3_freq(dev);
3183 if (ret)
3184 return ret;
3185
3186 for (retry = 0; retry < retry_max; retry++) {
3187 r_foreach_vch(dev, ch)
3188 if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(0))
3189 phytrainingok |= BIT(ch);
3190
3191 if (phytrainingok == priv->ddr_phyvalid)
3192 break;
3193 }
3194
3195 /* Error Check */
3196 r_foreach_vch(dev, ch) {
3197 /* Wrlvl Error Check */
3198 /* PI_WRLVL_ERROR_BIT */
3199 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(3);
3200 /* SLICE0 wrlvl error */
3201 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_STATUS_OBS) & BIT(12);
3202 /* SLICE1 wrlvl error */
3203 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_STATUS_OBS) & BIT(12);
3204 /* SLICE0 wrlvl error */
3205 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_ERROR_OBS);
3206 /* SLICE1 wrlvl error */
3207 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_ERROR_OBS);
3208 if (reg) {
3209 wr_training_ng |= BIT(ch);
3210 printf("%s wl_gt_training_error:1\n", __func__);
3211 }
3212
3213 /* Gtlvl Error Check */
3214 /* PI_RDLVL_GATE_ERROR_BIT */
3215 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(2);
3216 /* SLICE0 delay setup error */
3217 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_GTLVL_STATUS_OBS) & (0x3 << 7);
3218 /* SLICE1 delay setup error */
3219 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_GTLVL_STATUS_OBS) & (0x3 << 7);
3220 if (reg) {
3221 gt_training_ng |= BIT(ch);
3222 printf("%s wl_gt_training_error:2\n", __func__);
3223 }
3224 }
3225
3226 complete_ng = (wr_training_ng | gt_training_ng);
3227 if (complete_ng)
3228 return ~complete_ng;
3229
3230 /* PI_INT_ACK assert */
3231 r_foreach_vch(dev, ch) {
3232 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
3233 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
3234 }
3235
3236 return phytrainingok;
3237}
3238
3239/**
3240 * dbsc5_pi_int_ack_0_assert() - Training handshake functions
3241 * @dev: DBSC5 device
3242 * @bit: Status bit to poll
3243 *
3244 * Wait for the status bit specified in the argument to become 1 until the
3245 * time limit. After checking status bits on all channels, clear the target
3246 * status bits and returns the result of the check as the return value.
3247 */
3248static u32 dbsc5_pi_int_ack_0_assert(struct udevice *dev, u32 bit)
3249{
3250 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3251 const int retry_max = 0x10000;
3252 u32 ch, phytrainingok = 0;
3253 int retry;
3254
3255 for (retry = 0; retry < retry_max; retry++) {
3256 r_foreach_vch(dev, ch)
3257 if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(bit))
3258 phytrainingok |= BIT(ch);
3259
3260 if (phytrainingok == priv->ddr_phyvalid)
3261 break;
3262 }
3263
3264 if (phytrainingok != priv->ddr_phyvalid)
3265 return phytrainingok;
3266
3267 r_foreach_vch(dev, ch)
3268 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, BIT(bit));
3269
3270 return phytrainingok;
3271}
3272
3273/**
3274 * dbsc5_write_dca() - Write DCA Training
3275 * @dev: DBSC5 device
3276 *
3277 * Get DCA Training CS0 Flip-0 training results for RANK0.
3278 * Get DCA Training CS1 Flip-0 training results for RANK0.
3279 * Calculate DRAMDCA settings from training results and write
3280 * them to registers. Set DRAM DCA in MR30. Ensure that the
3281 * training has been successfully completed. Clear CA status
3282 * to 0.
3283 */
3284static void dbsc5_write_dca(struct udevice *dev)
3285{
3286 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3287 const int retry_max = 0x10000;
3288 u32 phytrainingok = 0;
3289 u32 ch, reg;
3290 int retry;
3291
3292 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_DATA_DC_CAL_START, 0x1);
3293
3294 for (retry = 0; retry < retry_max; retry++) {
3295 r_foreach_vch(dev, ch) {
3296 reg = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_DATA_DC_CAL_START) |
3297 dbsc5_ddr_getval_slice(dev, ch, 1, PHY_DATA_DC_CAL_START);
3298 if (!reg)
3299 phytrainingok |= BIT(ch);
3300 }
3301
3302 if (phytrainingok == priv->ddr_phyvalid)
3303 break;
3304 }
3305}
3306
3307/**
3308 * dbsc5_dramdca_training() - DRAM DCA Training and Calculations
3309 * @dev: DBSC5 device
3310 *
3311 * Get DCA Training CS0 Flip-0 training results for RANK0.
3312 * Get DCA Training CS1 Flip-0 training results for RANK0.
3313 * Calculate DRAMDCA settings from training results and write
3314 * them to registers. Set DRAM DCA in MR30. Ensure that the
3315 * training has been successfully completed. Clear CA status
3316 * to 0.
3317 */
3318static u32 dbsc5_dramdca_training(struct udevice *dev)
3319{
3320 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3321 const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
3322 const u32 mr30_conv[16] = {
3323 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1,
3324 0x0, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
3325 };
3326 u32 dca_result_l_0[DRAM_CH_CNT][CS_CNT];
3327 u32 dca_result_u_0[DRAM_CH_CNT][CS_CNT];
3328 u32 dca_result_l_1[DRAM_CH_CNT][CS_CNT];
3329 u32 dca_result_u_1[DRAM_CH_CNT][CS_CNT];
3330 u32 ch, phytrainingok, reg;
3331 u32 tempu, templ;
3332
3333 /* Run DRAM DCA Training for Flip-0 */
3334 dbsc5_ddr_setval_all_ch(dev, PI_DCMLVL_CS_SW, rank);
3335
3336 /* DRAMDCA go */
3337 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_REQ, 0x1);
3338
3339 /* PI_INT_ACK assert */
3340 phytrainingok = dbsc5_pi_int_ack_0_assert(dev, 28);
3341 if (phytrainingok != priv->ddr_phyvalid)
3342 return phytrainingok;
3343
3344 /* Result for DRAMDCA flip-0 */
3345 r_foreach_vch(dev, ch) {
3346 reg = dbsc5_ddr_getval(dev, ch, PI_DARRAY3_20_CS0_F2);
3347 dca_result_u_0[ch][0] = mr30_conv[reg >> 4];
3348 dca_result_l_0[ch][0] = mr30_conv[reg & 0xF];
3349 if (!(rank & 0x2))
3350 continue;
3351
3352 reg = dbsc5_ddr_getval(dev, ch, PI_DARRAY3_20_CS1_F2);
3353 dca_result_u_0[ch][1] = mr30_conv[reg >> 4];
3354 dca_result_l_0[ch][1] = mr30_conv[reg & 0xF];
3355 }
3356
3357 /* Run DRAM DCA Training for Flip-1 */
3358 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_FLIP_MASK, 0x1);
3359 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_2, 0x0);
3360 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_3, 0x0);
3361 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_4, 0x0);
3362
3363 /* DRAMDCA go */
3364 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_REQ, 0x1);
3365
3366 /* PI_INT_ACK assert */
3367 phytrainingok = dbsc5_pi_int_ack_0_assert(dev, 28);
3368 if (phytrainingok != priv->ddr_phyvalid)
3369 return phytrainingok;
3370
3371 /* Result for DRAMDCA flip-1 */
3372 r_foreach_vch(dev, ch) {
3373 reg = dbsc5_ddr_getval(dev, ch, PI_DARRAY3_20_CS0_F2);
3374 dca_result_u_1[ch][0] = mr30_conv[reg >> 4];
3375 dca_result_l_1[ch][0] = mr30_conv[reg & 0xF];
3376 if (!(rank & 0x2))
3377 continue;
3378
3379 reg = dbsc5_ddr_getval(dev, ch, PI_DARRAY3_20_CS1_F2);
3380 dca_result_u_1[ch][1] = mr30_conv[reg >> 4];
3381 dca_result_l_1[ch][1] = mr30_conv[reg & 0xF];
3382 }
3383
3384 /* Calculate and set DRAMDCA value */
3385 r_foreach_vch(dev, ch) {
3386 /* CS0 */
3387 tempu = (dca_result_u_0[ch][0] + dca_result_u_1[ch][0]) / 2;
3388 templ = (dca_result_l_0[ch][0] + dca_result_l_1[ch][0]) / 2;
3389 reg = (mr30_conv[tempu] << 4) | mr30_conv[templ];
3390 dbsc5_ddr_setval(dev, ch, PI_DARRAY3_20_CS0_F2, reg);
3391 if (!(rank & 0x2))
3392 continue;
3393
3394 /* CS1 */
3395 tempu = (dca_result_u_0[ch][1] + dca_result_u_1[ch][1]) / 2;
3396 templ = (dca_result_l_0[ch][1] + dca_result_l_1[ch][1]) / 2;
3397 reg = (mr30_conv[tempu] << 4) | mr30_conv[templ];
3398 dbsc5_ddr_setval(dev, ch, PI_DARRAY3_20_CS1_F2, reg);
3399 }
3400
3401 /* Set DRAMDCA value in MR30 */
3402 dbsc5_ddr_setval_all_ch(dev, PI_SW_SEQ_0, 0x1A11E14);
3403 dbsc5_ddr_setval_all_ch(dev, PI_SW_SEQ_1, 0x1F0000);
3404 dbsc5_ddr_setval_all_ch(dev, PI_SEQ_DEC_SW_CS, rank);
3405 dbsc5_ddr_setval_all_ch(dev, PI_SW_SEQ_START, 0x1);
3406
3407 /* PI_INT_ACK assert */
3408 phytrainingok = dbsc5_pi_int_ack_0_assert(dev, 19);
3409 if (phytrainingok != priv->ddr_phyvalid)
3410 return phytrainingok;
3411
3412 dbsc5_ddr_setval_all_ch(dev, PI_SEQ_DEC_SW_CS, 0x0);
3413 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_FLIP_MASK, 0x2);
3414 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_2, 0x1101FC);
3415 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_3, 0x211A00);
3416 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_4, 0x51500);
3417
3418 return phytrainingok;
3419}
3420
3421/**
3422 * dbsc5_write_leveling() - Re-run Write Leveling
3423 * @dev: DBSC5 device
3424 *
3425 * CALVL training is set to OFF, WRDCM training is set to OFF, and DRAMDCA
3426 * training is set to OFF. Set the memory rank for the Write leveling target
3427 * and start leveling. Wait until leveling is complete.
3428 *
3429 * Check for Write leveling errors. If an error is confirmed to have occurred,
3430 * the result is returned as a return value. Clear the PI status bit.
3431 */
3432static u32 dbsc5_write_leveling(struct udevice *dev)
3433{
3434 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3435 const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
3436 const int retry_max = 0x10000;
3437 u32 wr_training_ng = 0;
3438 u32 phytrainingok = 0;
3439 u32 ch, reg;
3440 int retry;
3441
3442 dbsc5_ddr_setval_all_ch(dev, PI_CALVL_EN_F2, 0x0);
3443 dbsc5_ddr_setval_all_ch(dev, PI_WRDCM_LVL_EN_F2, 0x0);
3444 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_EN_F2, 0x0);
3445 dbsc5_ddr_setval_all_ch(dev, PI_WRLVL_CS_SW, rank);
3446 dbsc5_ddr_setval_all_ch(dev, PI_WRLVL_REQ, 0x1);
3447
3448 for (retry = 0; retry < retry_max; retry++) {
3449 r_foreach_vch(dev, ch)
3450 if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(29))
3451 phytrainingok |= BIT(ch);
3452
3453 if (phytrainingok == priv->ddr_phyvalid)
3454 break;
3455 }
3456
3457 /* Error check */
3458 r_foreach_vch(dev, ch) {
3459 /* Wrlvl Error Check */
3460 /* PI_WRLVL_ERROR_BIT */
3461 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(3);
3462 /* SLICE0 wrlvl error */
3463 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_STATUS_OBS) & BIT(12);
3464 /* SLICE1 wrlvl error */
3465 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_STATUS_OBS) & BIT(12);
3466 /* SLICE0 wrlvl error */
3467 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_ERROR_OBS);
3468 /* SLICE1 wrlvl error */
3469 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_ERROR_OBS);
3470 if (reg) {
3471 wr_training_ng |= BIT(ch);
3472 printf("%s write_leveling_error:1\n", __func__);
3473 }
3474 }
3475
3476 if (wr_training_ng)
3477 return ~wr_training_ng;
3478
3479 /* PI_INT_ACK assert */
3480 r_foreach_vch(dev, ch) {
3481 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
3482 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
3483 }
3484
3485 return phytrainingok;
3486}
3487
3488/**
3489 * dbsc5_manual_write_dca() - Manual Write DCA Training
3490 * @dev: DBSC5 device
3491 *
3492 * Write DCA training according to memory rank.
3493 */
3494static void dbsc5_manual_write_dca(struct udevice *dev)
3495{
3496 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3497 const u32 rank = priv->ch_have_this_cs[1] ? 0x2 : 0x1;
Marek Vasut021b08e2025-03-16 14:51:42 +01003498 u32 phy_slv_dly[DRAM_CH_CNT][CS_CNT][SLICE_CNT];
3499 u32 phy_slv_dly_avg[DRAM_CH_CNT][SLICE_CNT];
Marek Vasut1f7ba642024-12-12 14:34:30 +01003500 u32 slv_dly_min[DRAM_CH_CNT][SLICE_CNT];
3501 u32 slv_dly_max[DRAM_CH_CNT][SLICE_CNT];
Marek Vasut1f7ba642024-12-12 14:34:30 +01003502 u32 phy_dcc_code_min[DRAM_CH_CNT][SLICE_CNT];
3503 u32 phy_dcc_code_max[DRAM_CH_CNT][SLICE_CNT];
3504 u32 phy_dcc_code_mid;
3505 const int retry_max = 0x10000;
3506 const u8 ratio_min_div = 0xA;
3507 const u8 ratio_max_div = 0x2;
3508 const u8 ratio_min = 0x6;
3509 const u8 ratio_max = 0x3;
3510 u32 ch, cs, slice, tmp;
3511 u32 complete = 0;
3512 int i, retry;
3513
3514 r_foreach_vch(dev, ch) {
3515 for (slice = 0; slice < SLICE_CNT; slice++) {
3516 phy_dcc_code_min[ch][slice] = 0x7F;
3517 phy_dcc_code_max[ch][slice] = 0x0;
3518 }
3519 }
3520
3521 for (cs = 0; cs < rank; cs++) {
3522 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_INDEX, cs);
3523 r_foreach_vch(dev, ch) {
3524 for (slice = 0; slice < SLICE_CNT; slice++) {
Marek Vasut021b08e2025-03-16 14:51:42 +01003525 phy_slv_dly[ch][cs][slice] =
3526 dbsc5_ddr_getval_slice(dev, ch, slice,
3527 PHY_CLK_WRDQS_SLAVE_DELAY);
Marek Vasut1f7ba642024-12-12 14:34:30 +01003528 }
3529 }
3530 }
3531
3532 r_foreach_vch(dev, ch) {
3533 for (slice = 0; slice < SLICE_CNT; slice++) {
3534 if (rank == 0x2) {
Marek Vasut021b08e2025-03-16 14:51:42 +01003535 /* Calculate average between ranks */
3536 phy_slv_dly_avg[ch][slice] = (phy_slv_dly[ch][0][slice] +
3537 phy_slv_dly[ch][1][slice]) / 2;
Marek Vasut1f7ba642024-12-12 14:34:30 +01003538 } else {
Marek Vasut021b08e2025-03-16 14:51:42 +01003539 phy_slv_dly_avg[ch][slice] = phy_slv_dly[ch][0][slice];
Marek Vasut1f7ba642024-12-12 14:34:30 +01003540 }
Marek Vasut021b08e2025-03-16 14:51:42 +01003541 /* Determine the search range */
3542 slv_dly_min[ch][slice] = (phy_slv_dly_avg[ch][slice] & 0x07F) * ratio_min / ratio_min_div;
3543 slv_dly_max[ch][slice] = (phy_slv_dly_avg[ch][slice] & 0x07F) * ratio_max / ratio_max_div;
3544 if (slv_dly_max[ch][slice] > 0x7F)
3545 slv_dly_max[ch][slice] = 0x7F;
Marek Vasut1f7ba642024-12-12 14:34:30 +01003546 }
3547 }
3548
Marek Vasut021b08e2025-03-16 14:51:42 +01003549 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_SLV_DLY_CTRL_GATE_DISABLE, 0x1);
3550
Marek Vasut1f7ba642024-12-12 14:34:30 +01003551 for (i = 0; i <= 0x7F; i++) {
3552 r_foreach_vch(dev, ch) {
3553 for (slice = 0; slice < SLICE_CNT; slice++) {
3554 if (slv_dly_max[ch][slice] < (slv_dly_min[ch][slice] + i)) {
3555 complete |= BIT(ch) << (8 * slice);
3556 } else {
3557 /* CS0/1 same setting, Need masked write */
3558 dbsc5_ddr_setval_slice(dev, ch, slice,
3559 PHY_CLK_WRDQS_SLAVE_DELAY,
3560 slv_dly_min[ch][slice] + i);
3561 dbsc5_ddr_setval_slice(dev, ch, slice, SC_PHY_WCK_CALC, 0x1);
3562 dbsc5_ddr_setval(dev, ch, SC_PHY_MANUAL_UPDATE, 0x1);
3563 }
3564 }
3565 }
3566
3567 if (complete == (priv->ddr_phyvalid | (priv->ddr_phyvalid << 8)))
3568 break;
3569
3570 /* Execute write dca */
3571 r_foreach_vch(dev, ch)
3572 for (slice = 0; slice < SLICE_CNT; slice++)
3573 if (!(((complete >> (8 * slice)) >> ch) & 0x1))
3574 dbsc5_ddr_setval_slice(dev, ch, slice, PHY_DATA_DC_CAL_START, 0x1);
3575
3576 r_foreach_vch(dev, ch) {
3577 for (slice = 0; slice < SLICE_CNT; slice++) {
3578 if (!(((complete >> (8 * slice)) >> ch) & 0x1)) {
3579 for (retry = 0; retry < retry_max; retry++) {
3580 tmp = dbsc5_ddr_getval_slice(dev, ch, slice,
3581 PHY_DATA_DC_CAL_START);
3582 if (!tmp)
3583 break;
3584 }
3585 }
3586 }
3587 }
3588
3589 r_foreach_vch(dev, ch) {
3590 for (slice = 0; slice < SLICE_CNT; slice++) {
3591 if ((slv_dly_min[ch][slice] + i) > slv_dly_max[ch][slice])
3592 continue;
3593
3594 tmp = (dbsc5_ddr_getval_slice(dev, ch, slice, PHY_DATA_DC_DQS_CLK_ADJUST));
3595 if ((tmp >> 6) == 0x1)
3596 tmp = 0x0;
3597 else if ((tmp >> 6) == 0x2)
3598 tmp = 0x3F;
3599
3600 if (tmp < phy_dcc_code_min[ch][slice])
3601 phy_dcc_code_min[ch][slice] = tmp;
3602
3603 if (phy_dcc_code_max[ch][slice] < tmp)
3604 phy_dcc_code_max[ch][slice] = tmp;
3605 }
3606 }
3607 }
3608
3609 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_MULTICAST_EN, 0x0);
3610 for (cs = 0; cs < rank; cs++) {
3611 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_INDEX, cs);
3612 r_foreach_vch(dev, ch) {
3613 for (slice = 0; slice < SLICE_CNT; slice++) {
3614 dbsc5_ddr_setval_slice(dev, ch, slice,
3615 PHY_CLK_WRDQS_SLAVE_DELAY,
Marek Vasut021b08e2025-03-16 14:51:42 +01003616 phy_slv_dly[ch][cs][slice]);
Marek Vasut1f7ba642024-12-12 14:34:30 +01003617 dbsc5_ddr_setval_slice(dev, ch, slice,
3618 SC_PHY_WCK_CALC, 0x1);
3619 dbsc5_ddr_setval(dev, ch, SC_PHY_MANUAL_UPDATE, 0x1);
3620 }
3621 }
3622 }
Marek Vasut021b08e2025-03-16 14:51:42 +01003623
3624 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_SLV_DLY_CTRL_GATE_DISABLE, 0x0);
3625
Marek Vasut1f7ba642024-12-12 14:34:30 +01003626 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_MULTICAST_EN, 0x1);
3627
3628 r_foreach_vch(dev, ch) {
3629 for (slice = 0; slice < SLICE_CNT; slice++) {
3630 phy_dcc_code_mid = (phy_dcc_code_min[ch][slice] +
3631 phy_dcc_code_max[ch][slice]) / 2;
3632 dbsc5_ddr_setval_slice(dev, ch, slice,
3633 PHY_DATA_DC_DQS_CLK_ADJUST,
3634 phy_dcc_code_mid);
3635 }
3636 }
3637}
3638
3639/**
3640 * dbsc5_read_gate_training() - Re-run read gate training by PI
3641 * @dev: DBSC5 device
3642 *
3643 * Write leveling set to OFF, read gate leveling set to ON. Set memory rank
3644 * for leveling target, turn on read gate leveling. Wait for leveling to be
3645 * completed until the time limit. Check for errors during gate leveling.
3646 *
3647 * If an error is confirmed to have occurred, the result is returned as a
3648 * return value. Clear the PI status register.
3649 */
3650static u32 dbsc5_read_gate_training(struct udevice *dev)
3651{
3652 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3653 const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
3654 const int retry_max = 0x10000;
3655 u32 gt_training_ng = 0;
3656 u32 phytrainingok = 0;
3657 u32 ch, reg;
3658 int retry;
3659
3660 dbsc5_ddr_setval_all_ch(dev, PI_WRLVL_EN_F2, 0x0);
3661 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_EN_F2, 0x1);
3662 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_CS_SW, rank);
3663 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_REQ, 0x1);
3664
3665 for (retry = 0; retry < retry_max; retry++) {
3666 r_foreach_vch(dev, ch)
3667 if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(24))
3668 phytrainingok |= BIT(ch);
3669
3670 if (phytrainingok == priv->ddr_phyvalid)
3671 break;
3672 }
3673
3674 /* Error Check */
3675 r_foreach_vch(dev, ch) {
3676 /* Gtlvl Error Check */
3677 /* PI_RDLVL_GATE_ERROR_BIT */
3678 reg = (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(2));
3679 /* SLICE0 delay setup error */
3680 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_GTLVL_STATUS_OBS) & (0x3 << 7);
3681 /* SLICE1 delay setup error */
3682 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_GTLVL_STATUS_OBS) & (0x3 << 7);
3683 if (reg) {
3684 gt_training_ng |= BIT(ch);
3685 printf("%s read_gate_training_error\n", __func__);
3686 }
3687 }
3688
3689 if (gt_training_ng)
3690 return ~gt_training_ng;
3691
3692 /* PI_INT_ACK assert */
3693 r_foreach_vch(dev, ch) {
3694 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
3695 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
3696 }
3697
3698 return phytrainingok;
3699}
3700
3701/**
3702 * dbsc5_read_vref_training() - Read Data Training with VREF Training
3703 * @dev: DBSC5 device
3704 *
3705 * Set reading leveling to ON and Vref leveling of reading to OFF.
3706 * Set Vref reading training to OFF. Get start value, end value and
3707 * number of steps for Vref training. Determine the optimal VREFSEL
3708 * value while increasing the Vref training setpoint by the starting
3709 * value+step value.
3710 */
3711static u32 dbsc5_read_vref_training(struct udevice *dev)
3712{
3713 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3714 const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
3715 u32 best_dvw_min_byte0, best_dvw_min_byte1;
3716 u32 dvw_min_byte0_table[DRAM_CH_CNT][128];
3717 u32 dvw_min_byte1_table[DRAM_CH_CNT][128];
3718 u32 dvw_min_byte0[DRAM_CH_CNT] = { 0 };
3719 u32 dvw_min_byte1[DRAM_CH_CNT] = { 0 };
3720 u32 best_lower_vref, best_upper_vref;
3721 u32 best_vref_byte0, best_vref_byte1;
3722 u32 vref_start, vref_stop, vref_step;
3723 u32 best_vref_byte0_index = 0;
3724 u32 best_vref_byte1_index = 0;
3725 const int retry_max = 0x10000;
3726 u32 win_byte0, win_byte1;
3727 u32 phytrainingok = 0;
3728 u32 vref_stop_index;
3729 u32 temple, tempte;
3730 u32 best_thrshld;
3731 u32 vref_outlier;
3732 u32 outlier_cnt;
3733 u32 curr_rank;
3734 int i, retry;
3735 u32 obs_sel;
3736 u32 ch, reg;
3737
3738 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_EN_F2, 0x3);
3739 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_VREF_EN_F0, 0x0);
3740 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_VREF_EN_F1, 0x0);
3741 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_VREF_EN_F2, 0x0);
3742 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_VREF_TRAINING_CTRL, 0x0);
3743
3744 /* ch0 vref_point */
3745 vref_start = dbsc5_ddr_getval(dev, 0, PHY_VREF_INITIAL_START_POINT);
3746 vref_stop = dbsc5_ddr_getval(dev, 0, PHY_VREF_INITIAL_STOP_POINT);
3747 vref_step = dbsc5_ddr_getval(dev, 0, PHY_VREF_INITIAL_STEPSIZE);
3748 vref_stop_index = (vref_stop - vref_start) / vref_step;
3749
3750 if (vref_stop_index > 0x80)
3751 return 0;
3752
3753 for (i = 0; i <= vref_stop_index; i++) {
3754 r_foreach_vch(dev, ch) {
3755 reg = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_PAD_VREF_CTRL_DQ);
3756 reg &= 0xF << 10;
3757 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_PAD_VREF_CTRL_DQ,
3758 reg | BIT(9) | (vref_start + (vref_step * i)));
3759 reg = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_PAD_VREF_CTRL_DQ);
3760 reg &= 0xF << 10;
3761 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_PAD_VREF_CTRL_DQ,
3762 reg | BIT(9) | (vref_start + (vref_step * i)));
3763 }
3764
3765 for (curr_rank = 0; curr_rank < rank; curr_rank++) {
3766 /* All ch Read Training Start */
3767 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_CS_SW, BIT(curr_rank));
3768 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_REQ, 0x1);
3769
3770 phytrainingok = 0;
3771 for (retry = 0; retry < retry_max; retry++) {
3772 r_foreach_vch(dev, ch)
3773 if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(25))
3774 phytrainingok |= BIT(ch);
3775
3776 if (phytrainingok == priv->ddr_phyvalid)
3777 break;
3778 }
3779
3780 /* Read Training End */
3781 dbsc5_ddr_setval_all_ch(dev, PI_INT_ACK_0, BIT(25));
3782
3783 r_foreach_vch(dev, ch) {
3784 /* minimum Data Valid Window for each VREF */
3785 dvw_min_byte0[ch] = 0xFFFFFFFF;
3786 dvw_min_byte1[ch] = 0xFFFFFFFF;
3787 for (obs_sel = 0x0; obs_sel < 0x19; obs_sel++) {
3788 if (!((obs_sel < 0x11) || (obs_sel == 0x18)))
3789 continue;
3790
3791 dbsc5_ddr_setval_slice(dev, ch, 0,
3792 PHY_RDLVL_RDDQS_DQ_OBS_SELECT,
3793 obs_sel);
3794 dbsc5_ddr_setval_slice(dev, ch, 1,
3795 PHY_RDLVL_RDDQS_DQ_OBS_SELECT,
3796 obs_sel);
3797
3798 temple = dbsc5_ddr_getval_slice(dev, ch, 0,
3799 PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS);
3800 tempte = dbsc5_ddr_getval_slice(dev, ch, 0,
3801 PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS);
3802 if (tempte > temple)
3803 win_byte0 = tempte - temple;
3804 else
3805 win_byte0 = 0;
3806
3807 temple = dbsc5_ddr_getval_slice(dev, ch, 1,
3808 PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS);
3809 tempte = dbsc5_ddr_getval_slice(dev, ch, 1,
3810 PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS);
3811 if (tempte > temple)
3812 win_byte1 = tempte - temple;
3813 else
3814 win_byte1 = 0;
3815
3816 if (dvw_min_byte0[ch] > win_byte0)
3817 dvw_min_byte0[ch] = win_byte0;
3818
3819 if (dvw_min_byte1[ch] > win_byte1)
3820 dvw_min_byte1[ch] = win_byte1;
3821 }
3822 }
3823 }
3824
3825 r_foreach_vch(dev, ch) {
3826 dvw_min_byte0_table[ch][i] = dvw_min_byte0[ch];
3827 dvw_min_byte1_table[ch][i] = dvw_min_byte1[ch];
3828 }
3829 }
3830
3831 r_foreach_vch(dev, ch) {
3832 /* Search best VREF byte0 */
3833 best_vref_byte0 = vref_start;
3834 best_vref_byte0_index = 0;
3835 best_dvw_min_byte0 = dvw_min_byte0_table[ch][0];
3836
3837 for (i = 0; i <= vref_stop_index; i++) {
3838 if (best_dvw_min_byte0 >= dvw_min_byte0_table[ch][i])
3839 continue;
3840
3841 best_vref_byte0 = vref_start + (vref_step * i);
3842 best_vref_byte0_index = i;
3843 best_dvw_min_byte0 = dvw_min_byte0_table[ch][i];
3844 }
3845
3846 /* Search best_lower VREF byte0 */
3847 reg = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_RDLVL_DLY_STEP);
3848 if (reg == 0)
3849 reg = 1;
3850 best_thrshld = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_RDLVL_BEST_THRSHLD) * reg;
3851
3852 vref_outlier = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_RDLVL_VREF_OUTLIER);
3853 best_lower_vref = best_vref_byte0;
3854 outlier_cnt = vref_outlier;
3855 for (i = best_vref_byte0_index; i >= 0; i--) {
3856 if (dvw_min_byte0_table[ch][i] <= 0)
3857 break;
3858
3859 if (dvw_min_byte0_table[ch][i] >= (best_dvw_min_byte0 - best_thrshld)) {
3860 best_lower_vref = vref_start + (vref_step * i);
3861 } else {
3862 if (outlier_cnt > 0)
3863 outlier_cnt--;
3864 else
3865 break;
3866 }
3867
3868 if (i == 0)
3869 break;
3870 }
3871
3872 /* Search best_upper VREF byte0 */
3873 vref_outlier = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_RDLVL_VREF_OUTLIER);
3874 best_upper_vref = best_vref_byte0;
3875 outlier_cnt = vref_outlier;
3876 for (i = best_vref_byte0_index; i <= vref_stop_index; i++) {
3877 if (dvw_min_byte0_table[ch][i] <= 0)
3878 break;
3879
3880 if (dvw_min_byte0_table[ch][i] >= (best_dvw_min_byte0 - best_thrshld)) {
3881 best_upper_vref = vref_start + (vref_step * i);
3882 } else {
3883 if (outlier_cnt > 0)
3884 outlier_cnt--;
3885 else
3886 break;
3887 }
3888 }
3889
3890 /* Calculate center of best vref range byte0 */
3891 best_vref_byte0 = (best_lower_vref + best_upper_vref) / 2;
3892
3893 /* Search best VREF byte1 */
3894 best_vref_byte1 = vref_start;
3895 best_vref_byte1_index = 0;
3896 best_dvw_min_byte1 = dvw_min_byte1_table[ch][0];
3897 for (i = 0; i <= vref_stop_index; i++) {
3898 if (best_dvw_min_byte1 >= dvw_min_byte1_table[ch][i])
3899 continue;
3900
3901 best_vref_byte1 = vref_start + (vref_step * i);
3902 best_vref_byte1_index = i;
3903 best_dvw_min_byte1 = dvw_min_byte1_table[ch][i];
3904 }
3905
3906 /* Search best_lower VREF byte1 */
3907 reg = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_RDLVL_DLY_STEP);
3908 if (reg == 0)
3909 reg = 1;
3910 best_thrshld = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_RDLVL_BEST_THRSHLD) * reg;
3911
3912 vref_outlier = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_RDLVL_VREF_OUTLIER);
3913 best_lower_vref = best_vref_byte1;
3914 outlier_cnt = vref_outlier;
3915 for (i = best_vref_byte1_index; i >= 0; i--) {
3916 if (dvw_min_byte1_table[ch][i] <= 0)
3917 break;
3918
3919 if (dvw_min_byte1_table[ch][i] >= (best_dvw_min_byte1 - best_thrshld)) {
3920 best_lower_vref = vref_start + (vref_step * i);
3921 } else {
3922 if (outlier_cnt > 0)
3923 outlier_cnt--;
3924 else
3925 break;
3926 }
3927
3928 if (i == 0)
3929 break;
3930 }
3931
3932 /* Search best_upper VREF byte1 */
3933 vref_outlier = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_RDLVL_VREF_OUTLIER);
3934 best_upper_vref = best_vref_byte1;
3935 outlier_cnt = vref_outlier;
3936 for (i = best_vref_byte1_index; i <= vref_stop_index; i++) {
3937 if (dvw_min_byte1_table[ch][i] <= 0)
3938 break;
3939
3940 if (dvw_min_byte1_table[ch][i] >= (best_dvw_min_byte1 - best_thrshld)) {
3941 best_upper_vref = vref_start + (vref_step * i);
3942 } else {
3943 if (outlier_cnt > 0)
3944 outlier_cnt--;
3945 else
3946 break;
3947 }
3948 }
3949
3950 /* Calculate center of best vref range byte1 */
3951 best_vref_byte1 = (best_lower_vref + best_upper_vref) / 2;
3952
3953 reg = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_PAD_VREF_CTRL_DQ);
3954 reg &= 0xF << 10;
3955 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_PAD_VREF_CTRL_DQ,
3956 reg | BIT(9) | best_vref_byte0);
3957 reg = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_PAD_VREF_CTRL_DQ);
3958 reg &= 0xF << 10;
3959 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_PAD_VREF_CTRL_DQ,
3960 reg | BIT(9) | best_vref_byte1);
3961 }
3962
3963 return phytrainingok;
3964}
3965
3966/**
3967 * dbsc5_read_write_training() - Read Data & RDDQ Training with best VREF & Write DQ VREF Training
3968 * @dev: DBSC5 device
3969 *
3970 * Set read DQS/RDQS slave delay setting to 0. Write leveling set to OFF,
3971 * read gate leveling set to OFF. Turn on read and write leveling. Start
3972 * frequency training. Training in high-frequency mode. Wait until training
3973 * is complete. Check for errors in write dq leveling and read leveling.
3974
3975 * If an error is confirmed to have occurred, return the inverted result
3976 * value. Clear the PI status register.
3977 */
3978static u32 dbsc5_read_write_training(struct udevice *dev)
3979{
3980 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3981 const int retry_max = 0x10000;
3982 u32 wdq_training_ng = 0;
3983 u32 rd_training_ng = 0;
3984 u32 phytrainingok = 0;
3985 u32 complete_ng = 0;
3986 int retry, ret;
3987 u32 ch, reg;
3988
3989 /* RDDQ_SLAVE_DELAY Set 0x0050 -> 0x0000 */
3990 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ0_SLAVE_DELAY, 0x0);
3991 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ1_SLAVE_DELAY, 0x0);
3992 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ2_SLAVE_DELAY, 0x0);
3993 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ3_SLAVE_DELAY, 0x0);
3994 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ4_SLAVE_DELAY, 0x0);
3995 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ5_SLAVE_DELAY, 0x0);
3996 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ6_SLAVE_DELAY, 0x0);
3997 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ7_SLAVE_DELAY, 0x0);
3998 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDM_SLAVE_DELAY, 0x0);
3999
4000 dbsc5_ddr_setval_all_ch(dev, PI_WRLVL_EN_F2, 0x0);
4001 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_EN_F2, 0x0);
4002 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_EN_F2, 0x3);
4003 dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_EN_F2, 0x3);
4004
4005 dbsc5_ddr_setval_all_ch(dev, PI_TRAIN_ALL_FREQ_REQ, 0x1);
4006
4007 /* Freq Change High to High*/
4008 ret = dbsc5_clk_pll3_freq(dev);
4009 if (ret)
4010 return ret;
4011
4012 for (retry = 0; retry < retry_max; retry++) {
4013 r_foreach_vch(dev, ch)
4014 if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(0))
4015 phytrainingok |= BIT(ch);
4016
4017 if (phytrainingok == priv->ddr_phyvalid)
4018 break;
4019 }
4020
4021 /* Error Check */
4022 r_foreach_vch(dev, ch) {
4023 /* Rdlvl Error Check */
4024 /* PI_RDLVL_ERROR_BIT */
4025 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(1);
4026 if (reg) {
4027 rd_training_ng |= BIT(ch);
4028 printf("%s read_write_training_error:1\n", __func__);
4029 }
4030
4031 /* Wdqlvl Error Check */
4032 /* PI_WDQLVL_ERROR_BIT */
4033 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(5);
4034 /* SLICE0 wdqlvl_fail_dqZ */
4035 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WDQLVL_STATUS_OBS) & (0x1FF << 18);
4036 /* SLICE1 wdqlvl_fail_dqZ */
4037 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WDQLVL_STATUS_OBS) & (0x1FF << 18);
4038 if (reg) {
4039 wdq_training_ng |= BIT(ch);
4040 printf("%s read_write_training_error:2\n", __func__);
4041 }
4042 }
4043
4044 complete_ng = wdq_training_ng | rd_training_ng;
4045 if (complete_ng)
4046 return ~complete_ng;
4047
4048 /* PI_INT_ACK assert */
4049 r_foreach_vch(dev, ch) {
4050 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
4051 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
4052 }
4053
4054 return phytrainingok;
4055}
4056
4057/**
4058 * dbsc5_read_training() - Correct RDDQ Training result & Re-Run Read Data Training
4059 * @dev: DBSC5 device
4060 *
4061 * Set the Read DQ correction value and its upper limit from the board
4062 * settings. Check DDR memory ranks. Add the offset value to the current
4063 * Read DQ value and write it to the register. Write the setting value
4064 * to PI_RDLVL_TRAIN_SEQ_x. Start the Read training. PI_INT_ACK assert.
4065 * Execute the Rdlvl Error Check. Confirm that training has been successfully
4066 * completed. Return the result of the confirmation as the return value.
4067 */
4068static u32 dbsc5_read_training(struct udevice *dev)
4069{
4070 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
4071 const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
4072 const u32 rddq_delay_offset_ps = 0x19;
4073 const u32 rddq_delay_max_ps = 0x67;
4074 const u32 rddq_delay_addr[] = {
4075 PHY_RDDQ0_SLAVE_DELAY, PHY_RDDQ1_SLAVE_DELAY, PHY_RDDQ2_SLAVE_DELAY,
4076 PHY_RDDQ3_SLAVE_DELAY, PHY_RDDQ4_SLAVE_DELAY, PHY_RDDQ5_SLAVE_DELAY,
4077 PHY_RDDQ6_SLAVE_DELAY, PHY_RDDQ7_SLAVE_DELAY, PHY_RDDM_SLAVE_DELAY
4078 };
4079 const u32 rddq_delay_offset = rddq_delay_offset_ps * priv->ddr_mbps * 256 /
4080 (priv->ddr_mbpsdiv * 2 * 1000000);
4081 const u32 rddq_delay_max = rddq_delay_max_ps * priv->ddr_mbps * 256 /
4082 (priv->ddr_mbpsdiv * 2 * 1000000);
4083 u32 rd_training_ng = 0;
4084 u32 ch, reg, slice;
4085 u32 phytrainingok;
4086 int i;
4087
4088 r_foreach_vch(dev, ch) {
4089 for (slice = 0; slice < SLICE_CNT; slice++) {
4090 for (i = 0; i < 9; i++) {
4091 reg = dbsc5_ddr_getval_slice(dev, ch, slice,
4092 rddq_delay_addr[i]) +
4093 rddq_delay_offset;
4094 if (reg > rddq_delay_max)
4095 reg = rddq_delay_max;
4096 dbsc5_ddr_setval_slice(dev, ch, slice, rddq_delay_addr[i], reg);
4097 }
4098 }
4099 }
4100
4101 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_1, 0x89080);
4102 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_2, 0x811C0);
4103 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_3, 0x40811C0);
4104 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_4, 0x2000000);
4105 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_5, 0x0);
4106 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_CS_SW, rank);
4107
4108 /* Read training go */
4109 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_REQ, 0x1);
4110
4111 /* PI_INT_ACK assert */
4112 phytrainingok = dbsc5_pi_int_ack_0_assert(dev, 25);
4113 if (phytrainingok != priv->ddr_phyvalid)
4114 return phytrainingok;
4115
4116 /* Error Check */
4117 r_foreach_vch(dev, ch) {
4118 /* Rdlvl Error Check */
4119 /* PI_RDLVL_ERROR_BIT */
4120 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(1);
4121 if (reg) {
4122 rd_training_ng |= BIT(ch);
4123 printf("%s read_training_error\n", __func__);
4124 }
4125 }
4126
4127 if (rd_training_ng)
4128 return ~rd_training_ng;
4129
4130 return phytrainingok;
4131}
4132
4133/**
4134 * dbsc5_ddr_register_set() - DDR mode register setting
4135 * @dev: DBSC5 device
4136 *
4137 * Set the mode register 28 of the SDRAM.
4138 * ZQ Mode: Command-Based ZQ Calibration
4139 * ZQ interval: Background Cal Interval < 64ms
4140 */
4141static void dbsc5_ddr_register_set(struct udevice *dev)
4142{
4143 dbsc5_send_dbcmd2(dev, 0xE841C24);
4144}
4145
4146/**
4147 * dbsc5_ddr_register_read() - DDR mode register read
4148 * @dev: DBSC5 device
4149 *
4150 * Set the mode register 27 and 57 of the SDRAM.
4151 */
4152static void dbsc5_ddr_register_read(struct udevice *dev)
4153{
4154 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
4155
4156 if (!priv->dbsc5_board_config->bdcfg_rfm_chk)
4157 return;
4158
4159 /* MR27 rank0 */
4160 dbsc5_send_dbcmd2(dev, 0xF801B00);
4161 /* MR57 rank0 */
4162 dbsc5_send_dbcmd2(dev, 0xF803900);
4163
4164 if (!priv->ch_have_this_cs[1])
4165 return;
4166
4167 /* MR27 rank1 */
4168 dbsc5_send_dbcmd2(dev, 0xF811B00);
4169 /* MR57 rank1 */
4170 dbsc5_send_dbcmd2(dev, 0xF813900);
4171}
4172
4173/**
4174 * dbsc5_init_ddr() - Initialize DDR
4175 * @dev: DBSC5 device
4176 *
4177 * Status monitor and perform reset and software reset for DDR.
4178 * Disable DDRPHY software reset. Unprotect the DDRPHY register.
4179 * Perform pre-setting of DBSC registers. Configure the ddrphy
4180 * registers. Process ddr backup. Set DBSC registers.
4181 *
4182 * Initialize DFI and perform PI training. Setup DDR mode registers
4183 * pre-traning. Adjust number of write leveling cycles. Perform PI
4184 * training in manual mode. Perform DRAM DCA training. Perform write
4185 * leveling. Execute phydca training. Execute read gate training.
4186 *
4187 * Perform Vref training on read gate. Read DQ Write DQ Execute.
4188 * Frequency selection change (F1->F2). Disable the FREQ_SEL_MULTICAST &
4189 * PER_CS_TRAINING_MULTICAST. Start setting DDR mode registers. Set DBSC
4190 * registers after training is completed. Set write protection for PHY
4191 * registers.
4192 */
4193static u32 dbsc5_init_ddr(struct udevice *dev)
4194{
4195 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
4196 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
4197 u32 phytrainingok;
4198 u32 ch, val;
4199 int ret;
4200
4201 /* PLL3 initialization setting */
4202 /* Reset Status Monitor clear */
4203 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FSRCHKCLRR4, 0x600);
4204 /* Reset Status Monitor set */
4205 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FSRCHKSETR4, 0x600);
4206 /* ddrphy soft reset assert */
4207 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_SRCR4, readl(priv->cpg_regs + CPG_SRCR4) | 0x600);
4208 /* Wait reset FB */
4209 ret = readl_poll_timeout(priv->cpg_regs + CPG_FSRCHKRA4, val, ((val & 0x600) == 0), 1000000);
4210 if (ret < 0) {
4211 printf("%s CPG_FSRCHKRA4 Wait reset FB timeout\n", __func__);
4212 hang();
4213 }
4214 /* Reset Status Monitor clear */
4215 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FSRCHKCLRR4, 0x600);
4216
4217 /* Initialize PLL3 setting */
4218 dbsc5_clk_pll3_control(dev, PLL3_HIGH_FREQUENCY_MODE_LOAD_REGISTER);
4219
4220 /* DDRPHY soft reset negate */
4221 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_SRSTCLR4, 0x600);
4222 ret = readl_poll_timeout(priv->cpg_regs + CPG_SRCR4, val, ((val & 0x600) == 0), 1000000);
4223 if (ret < 0) {
4224 printf("%s CPG_SRCR4 DDRPHY soft reset negate timeout\n", __func__);
4225 hang();
4226 }
4227
4228 /* Unlock PHY */
4229 /* Unlock DDRPHY register */
4230 r_foreach_vch(dev, ch)
4231 writel(0xA55A, regs_dbsc_d + DBSC_DBPDLK(ch));
4232
4233 /* DBSC register pre-setting */
4234 dbsc5_dbsc_regset_pre(dev);
4235
4236 /* Load DDRPHY registers */
4237 dbsc5_ddrtbl_calc(priv);
4238 dbsc5_ddrtbl_load(dev);
4239
4240 /* Configure ddrphy registers */
4241 dbsc5_ddr_config(dev);
4242
4243 /* DDR backupmode end */
4244
4245 /* DBSC register set */
4246 dbsc5_dbsc_regset(dev);
4247
4248 /* Frequency selection change (F1->F2) */
4249 dbsc5_ddr_setval_all_ch(dev, PHY_FREQ_SEL_INDEX, 0x1);
4250 dbsc5_ddr_setval_all_ch(dev, PHY_FREQ_SEL_MULTICAST_EN, 0x0);
4251
4252 /* dfi_init_start (start ddrphy) & execute pi_training */
4253 phytrainingok = dbsc5_pi_training(dev);
4254 if (priv->ddr_phyvalid != phytrainingok) {
4255 printf("%s init_ddr_error:1\n", __func__);
4256 return phytrainingok;
4257 }
4258
4259 /* Write leveling cycle adjust */
4260 dbsc5_write_leveling_adjust(dev);
4261
4262 /* Execute write leveling & read gate training */
4263 phytrainingok = dbsc5_wl_gt_training(dev);
4264 if (priv->ddr_phyvalid != phytrainingok) {
4265 printf("%s init_ddr_error:2\n", __func__);
4266 return phytrainingok;
4267 }
4268
4269 /* Execute write dca training */
4270 dbsc5_write_dca(dev);
4271
4272 /* Execute dram dca training */
4273 phytrainingok = dbsc5_dramdca_training(dev);
4274
4275 if (priv->ddr_phyvalid != phytrainingok) {
4276 printf("%s init_ddr_error:3\n", __func__);
4277 return phytrainingok;
4278 }
4279
4280 /* Execute write leveling */
4281 phytrainingok = dbsc5_write_leveling(dev);
4282
4283 if (priv->ddr_phyvalid != phytrainingok) {
4284 printf("%s init_ddr_error:4\n", __func__);
4285 return phytrainingok;
4286 }
4287
4288 /* Execute manual write dca training */
4289 dbsc5_manual_write_dca(dev);
4290
4291 /* Execute read gate training */
4292 phytrainingok = dbsc5_read_gate_training(dev);
4293
4294 if (priv->ddr_phyvalid != phytrainingok) {
4295 printf("%s init_ddr_error:5\n", __func__);
4296 return phytrainingok;
4297 }
4298
4299 /* Execute read vref training */
4300 phytrainingok = dbsc5_read_vref_training(dev);
4301
4302 if (priv->ddr_phyvalid != phytrainingok) {
4303 printf("%s init_ddr_error:6\n", __func__);
4304 return phytrainingok;
4305 }
4306
4307 /* Execute read dq & write dq training with best vref */
4308 phytrainingok = dbsc5_read_write_training(dev);
4309 if (priv->ddr_phyvalid != phytrainingok) {
4310 printf("%s init_ddr_error:7\n", __func__);
4311 return phytrainingok;
4312 }
4313
4314 /* correct rddq training result & Execute read dq training */
4315 phytrainingok = dbsc5_read_training(dev);
4316
4317 if (priv->ddr_phyvalid != phytrainingok) {
4318 printf("%s init_ddr_error:8\n", __func__);
4319 return phytrainingok;
4320 }
4321
4322 /* PER_CS_TRAINING_MULTICAST SET (disable) */
4323 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_MULTICAST_EN, 0x0);
4324
4325 /* setup DDR mode registers */
4326 /* MRS */
4327 dbsc5_ddr_register_set(dev);
4328
4329 /* MRR */
4330 dbsc5_ddr_register_read(dev);
4331
4332 /* training complete, setup DBSC */
4333 dbsc5_dbsc_regset_post(dev);
4334
4335 /* Lock PHY */
4336 /* Lock DDRPHY register */
4337 r_foreach_vch(dev, ch)
4338 writel(0x0, regs_dbsc_d + DBSC_DBPDLK(ch));
4339
4340 return phytrainingok;
4341}
4342
4343/**
4344 * dbsc5_get_board_data() - Obtain board specific DRAM configuration
4345 *
4346 * Return board specific DRAM configuration structure pointer.
4347 */
4348__weak const struct renesas_dbsc5_board_config *dbsc5_get_board_data(void)
4349{
4350 return &renesas_v4h_dbsc5_board_config;
4351}
4352
4353/**
4354 * renesas_dbsc5_dram_probe() - DDR Initialize entry
4355 * @dev: DBSC5 device
4356 *
4357 * Remove write protection on DBSC register. Read DDR configuration
4358 * information from driver data. Calculate board clock frequency and
4359 * operating frequency from DDR configuration information. Call the
4360 * main function of DDR initialization. Perform DBSC write protection
4361 * after initialization is complete.
4362 */
4363static int renesas_dbsc5_dram_probe(struct udevice *dev)
4364{
4365#define RST_MODEMR0 0x0
4366#define RST_MODEMR1 0x4
4367 struct renesas_dbsc5_data *data = (struct renesas_dbsc5_data *)dev_get_driver_data(dev);
4368 ofnode cnode = ofnode_by_compatible(ofnode_null(), data->clock_node);
4369 ofnode rnode = ofnode_by_compatible(ofnode_null(), data->reset_node);
4370 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
4371 void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
4372 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
4373 phys_addr_t rregs = ofnode_get_addr(rnode);
4374 const u32 modemr0 = readl(rregs + RST_MODEMR0);
4375 const u32 modemr1 = readl(rregs + RST_MODEMR1);
4376 u32 breg, reg, md, sscg;
4377 u32 ch, cs;
4378
4379 /* Get board data */
4380 priv->dbsc5_board_config = dbsc5_get_board_data();
4381 priv->ddr_phyvalid = (u32)(priv->dbsc5_board_config->bdcfg_phyvalid);
4382 priv->max_density = 0;
4383 priv->cpg_regs = (void __iomem *)ofnode_get_addr(cnode);
4384
4385 for (cs = 0; cs < CS_CNT; cs++)
4386 priv->ch_have_this_cs[cs] = 0;
4387
4388 r_foreach_ech(ch)
4389 for (cs = 0; cs < CS_CNT; cs++)
4390 priv->ddr_density[ch][cs] = 0xFF;
4391
4392 r_foreach_vch(dev, ch) {
4393 for (cs = 0; cs < CS_CNT; cs++) {
4394 priv->ddr_density[ch][cs] = priv->dbsc5_board_config->ch[ch].bdcfg_ddr_density[cs];
4395
4396 if (priv->ddr_density[ch][cs] == 0xFF)
4397 continue;
4398
4399 if (priv->ddr_density[ch][cs] > priv->max_density)
4400 priv->max_density = priv->ddr_density[ch][cs];
4401
4402 priv->ch_have_this_cs[cs] |= BIT(ch);
4403 }
4404 }
4405
4406 /* Decode board clock frequency from MD[14:13] pins */
4407 priv->brd_clkdiv = 3;
4408
4409 breg = (modemr0 >> 13) & 0x3;
4410 if (breg == 0) {
4411 priv->brd_clk = 50; /* 16.66 MHz */
4412 priv->bus_clk = priv->brd_clk * 0x18;
4413 priv->bus_clkdiv = priv->brd_clkdiv;
4414 } else if (breg == 1) {
4415 priv->brd_clk = 60; /* 20 MHz */
4416 priv->bus_clk = priv->brd_clk * 0x14;
4417 priv->bus_clkdiv = priv->brd_clkdiv;
4418 } else if (breg == 3) {
4419 priv->brd_clk = 100; /* 33.33 MHz */
4420 priv->bus_clk = priv->brd_clk * 0x18;
4421 priv->bus_clkdiv = priv->brd_clkdiv * 2;
4422 } else {
4423 printf("MD[14:13] setting 0x%x not supported!", breg);
4424 hang();
4425 }
4426
4427 priv->brd_clkdiva = !!(modemr0 & BIT(14)); /* MD14 */
4428
4429 /* Decode DDR operating frequency from MD[37:36,19,17] pins */
4430 md = ((modemr0 & BIT(19)) >> 18) | ((modemr0 & BIT(17)) >> 17);
4431 sscg = (modemr1 >> 4) & 0x03;
4432 if (sscg == 2) {
4433 printf("MD[37:36] setting 0x%x not supported!", sscg);
4434 hang();
4435 }
4436
4437 if (md == 0) {
4438 if (sscg == 0) {
4439 priv->ddr_mbps = 6400;
4440 priv->ddr_mbpsdiv = 1;
4441 } else {
4442 priv->ddr_mbps = 19000;
4443 priv->ddr_mbpsdiv = 3;
4444 }
4445 } else if (md == 1) {
4446 priv->ddr_mbps = 6000;
4447 priv->ddr_mbpsdiv = 1;
Marek Vasutb12a20c2025-03-16 14:51:39 +01004448 } else if (md == 2) {
Marek Vasut1f7ba642024-12-12 14:34:30 +01004449 priv->ddr_mbps = 5500;
4450 priv->ddr_mbpsdiv = 1;
Marek Vasutb12a20c2025-03-16 14:51:39 +01004451 } else if (md == 3) {
Marek Vasut1f7ba642024-12-12 14:34:30 +01004452 priv->ddr_mbps = 4800;
4453 priv->ddr_mbpsdiv = 1;
4454 }
4455
4456 priv->ddr_mul = CLK_DIV(priv->ddr_mbps, priv->ddr_mbpsdiv * 2,
4457 priv->brd_clk, priv->brd_clkdiv * (priv->brd_clkdiva + 1));
4458 priv->ddr_mul_low = CLK_DIV(6400, 2, priv->brd_clk,
4459 priv->brd_clkdiv * (priv->brd_clkdiva + 1));
4460
4461 priv->ddr_mul_reg = priv->ddr_mul_low;
4462 if (sscg != 0)
4463 priv->ddr_mul_reg -= 2;
4464
4465 priv->ddr_mul_nf = ((8 * priv->ddr_mbps * priv->brd_clkdiv * (priv->brd_clkdiva + 1)) /
4466 (priv->ddr_mbpsdiv * priv->brd_clk * 2)) - (8 * (priv->ddr_mul / 2) * 2);
4467
4468 /* Adjust tccd */
4469 priv->ddr_tccd = 2;
4470
4471 /* Initialize DDR */
4472 dbsc5_reg_write(regs_dbsc_d + DBSC_DBSYSCNT0, 0x1234);
4473 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCNT0A, 0x1234);
4474
4475 reg = dbsc5_init_ddr(dev);
4476
4477 dbsc5_reg_write(regs_dbsc_d + DBSC_DBSYSCNT0, 0x0);
4478 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCNT0A, 0x0);
4479
4480 return reg != priv->ddr_phyvalid;
4481}
4482
4483/**
4484 * renesas_dbsc5_dram_of_to_plat() - Convert OF data to plat data
4485 * @dev: DBSC5 device
4486 *
4487 * Extract DBSC5 address from DT and store it in driver data.
4488 */
4489static int renesas_dbsc5_dram_of_to_plat(struct udevice *dev)
4490{
4491 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
4492
4493 priv->regs = dev_read_addr_ptr(dev);
4494 if (!priv->regs)
4495 return -EINVAL;
4496
4497 return 0;
4498}
4499
4500/**
4501 * renesas_dbsc5_dram_get_info() - Return RAM size
4502 * @dev: DBSC5 device
4503 * @info: Output RAM info
4504 *
4505 * Return size of the RAM managed by this RAM driver.
4506 */
4507static int renesas_dbsc5_dram_get_info(struct udevice *dev,
4508 struct ram_info *info)
4509{
4510 info->base = 0x40000000;
4511 info->size = 0;
4512
4513 return 0;
4514}
4515
4516static const struct ram_ops renesas_dbsc5_dram_ops = {
4517 .get_info = renesas_dbsc5_dram_get_info,
4518};
4519
4520U_BOOT_DRIVER(renesas_dbsc5_dram) = {
4521 .name = "dbsc5_dram",
4522 .id = UCLASS_RAM,
4523 .of_to_plat = renesas_dbsc5_dram_of_to_plat,
4524 .ops = &renesas_dbsc5_dram_ops,
4525 .probe = renesas_dbsc5_dram_probe,
4526 .priv_auto = sizeof(struct renesas_dbsc5_dram_priv),
4527};