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