blob: 461c862ea27fab63c9bb55ffe5e4da695a2dd025 [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 Vasute68e9152025-03-25 23:43:31 +01001744 * dbsc5_send_dbcmd2() - DRAM Command Write Access
Marek Vasut1f7ba642024-12-12 14:34:30 +01001745 * @dev: DBSC5 device
Marek Vasute68e9152025-03-25 23:43:31 +01001746 * @opcode DRAM controller opcode
1747 * @channel DRAM controller channel (0..3)
1748 * @rank DRAM controller rank (0..1)
1749 * @arg Command and argument bits (command specific encoding)
Marek Vasut1f7ba642024-12-12 14:34:30 +01001750 *
1751 * First, execute the dummy read to DBSC_DBCMD.
1752 * Confirm that no DBSC command operation is in progress 0.
1753 * Write the contents of the command to be sent to DRAM.
1754 */
Marek Vasute68e9152025-03-25 23:43:31 +01001755static void dbsc5_send_dbcmd2(struct udevice *dev, const u8 opcode,
1756 const u8 channel, const u8 rank,
1757 const u16 arg)
Marek Vasut1f7ba642024-12-12 14:34:30 +01001758{
Marek Vasute68e9152025-03-25 23:43:31 +01001759 const u32 cmd = (opcode << 24) | (channel << 20) | (rank << 16) | arg;
Marek Vasut1f7ba642024-12-12 14:34:30 +01001760 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1761 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
1762 u32 val;
1763 int ret;
1764
1765 /* dummy read */
1766 readl(regs_dbsc_d + DBSC_DBCMD);
1767
1768 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBWAIT, val, ((val & BIT(0)) == 0), 1000000);
1769 if (ret < 0) {
1770 printf("%s DBWAIT bit 0 timeout\n", __func__);
1771 hang();
1772 }
1773
1774 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBWAIT + 0x4000, val, ((val & BIT(0)) == 0), 1000000);
1775 if (ret < 0) {
1776 printf("%s DBWAIT + 0x4000 bit 0 timeout\n", __func__);
1777 hang();
1778 }
1779
1780 dbsc5_reg_write(regs_dbsc_d + DBSC_DBCMD, cmd);
1781}
1782
1783/**
1784 * dbsc5_reg_ddrphy_read() - Read setting from DDR PHY register
1785 * @dev: DBSC5 device
1786 * @ch: Target channel
1787 * @regadd: Destination address
1788 *
1789 * Write matching values to DBPDRGA register and read value out of DBSC_DBPDRGD.
1790 * Wait until the write process completed in each step.
1791 */
1792static u32 dbsc5_reg_ddrphy_read(struct udevice *dev, u32 ch, u32 regadd)
1793{
1794 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1795 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
1796 u32 val;
1797 int ret;
1798
1799 writel(regadd | BIT(14), regs_dbsc_d + DBSC_DBPDRGA(ch));
1800 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == (regadd | BIT(15) | BIT(14))), 1000000);
1801 if (ret < 0) {
1802 printf("%s regs_dbsc_d + DBSC_DBPDRGA timeout\n", __func__);
1803 hang();
1804 }
1805
1806 val = readl(regs_dbsc_d + DBSC_DBPDRGA(ch));
1807
1808 writel(regadd | BIT(15), regs_dbsc_d + DBSC_DBPDRGA(ch));
1809 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == regadd), 1000000);
1810 if (ret < 0) {
1811 printf("%s regs_dbsc_d + DBSC_DBPDRGA | BIT(15) timeout\n", __func__);
1812 hang();
1813 }
1814
1815 writel(regadd | BIT(15), regs_dbsc_d + DBSC_DBPDRGA(ch));
1816 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == regadd), 1000000);
1817 if (ret < 0) {
1818 printf("%s regs_dbsc_d + DBSC_DBPDRGA | BIT(15) again timeout\n", __func__);
1819 hang();
1820 }
1821
1822 return readl(regs_dbsc_d + DBSC_DBPDRGD(ch));
1823}
1824
1825/**
1826 * dbsc5_reg_ddrphy_write(dev, ) - Write setting to DDR PHY register
1827 * @dev: DBSC5 device
1828 * @ch: Target channel
1829 * @regadd: Destination address
1830 * @regdata: Value to be written
1831 *
1832 * Write matching values to DBPDRGA, DBPDRGD, DBPDRGA, DBPDRGA registers.
1833 * Wait until the write process completed in each step.
1834 */
1835static void dbsc5_reg_ddrphy_write(struct udevice *dev, u32 ch, u32 regadd, u32 regdata)
1836{
1837 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1838 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
1839 u32 val;
1840 int ret;
1841
1842 writel(regadd, regs_dbsc_d + DBSC_DBPDRGA(ch));
1843 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == regadd), 1000000);
1844 if (ret < 0) {
1845 printf("%s regs_dbsc_d + DBSC_DBPDRGA timeout\n", __func__);
1846 hang();
1847 }
1848
1849 writel(regdata, regs_dbsc_d + DBSC_DBPDRGD(ch));
1850 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == (regadd | BIT(15))), 1000000);
1851 if (ret < 0) {
1852 printf("%s regs_dbsc_d + DBSC_DBPDRGD timeout\n", __func__);
1853 hang();
1854 }
1855
1856 writel(regadd | BIT(15), regs_dbsc_d + DBSC_DBPDRGA(ch));
1857 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGA(ch), val, (val == regadd), 1000000);
1858 if (ret < 0) {
1859 printf("%s regs_dbsc_d + DBSC_DBPDRGA | BIT(15) timeout\n", __func__);
1860 hang();
1861 }
1862
1863 writel(regadd, regs_dbsc_d + DBSC_DBPDRGA(ch));
1864}
1865
1866/*
1867 * dbsc5_reg_ddrphy_write_all() - Write setting from DDR PHY register for all channels
1868 * @dev: DBSC5 device
1869 * @regadd: Destination address
1870 * @regdata: Value to be written
1871 *
1872 * Wrapper around dbsc5_reg_ddrphy_write() for all channels.
1873 */
1874static void dbsc5_reg_ddrphy_write_all(struct udevice *dev, u32 regadd, u32 regdata)
1875{
1876 u32 ch;
1877
1878 r_foreach_vch(dev, ch)
1879 dbsc5_reg_ddrphy_write(dev, ch, regadd, regdata);
1880}
1881
1882/**
1883 * dbsc5_reg_ddrphy_masked_write() - Write setting to DDR PHY register with mask
1884 * @dev: DBSC5 device
1885 * @ch: Target channel
1886 * @regadd: Destination address
1887 * @regdata: Value to be written
1888 * @msk: Register mask
1889 *
1890 * Wrapper around dbsc5_reg_ddrphy_write() with DBPDRGM set.
1891 */
1892static void dbsc5_reg_ddrphy_masked_write(struct udevice *dev, u32 ch, u32 regadd, u32 regdata, u32 msk)
1893{
1894 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
1895 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
1896 u32 val;
1897 int ret;
1898
1899 writel(msk, regs_dbsc_d + DBSC_DBPDRGM(ch));
1900 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGM(ch), val, (val == msk), 1000000);
1901 if (ret < 0) {
1902 printf("%s regs_dbsc_d + DBSC_DBPDRGM timeout\n", __func__);
1903 hang();
1904 }
1905
1906 dbsc5_reg_ddrphy_write(dev, ch, regadd, regdata);
1907
1908 writel(0, regs_dbsc_d + DBSC_DBPDRGM(ch));
1909 ret = readl_poll_timeout(regs_dbsc_d + DBSC_DBPDRGM(ch), val, (val == 0), 1000000);
1910 if (ret < 0) {
1911 printf("%s regs_dbsc_d + DBSC_DBPDRGM != 0 timeout\n", __func__);
1912 hang();
1913 }
1914}
1915
1916/**
1917 * dbsc5_ddr_setval_slice() - Write setting to DDR PHY hardware
1918 * @dev: DBSC5 device
1919 * @ch: Target channel
1920 * @slice: Target slice
1921 * @regdef: Encoded PHY/PI register and bitfield
1922 * @val: Value to be written
1923 *
1924 * Calculate the bit field in which to write the setting value
1925 * from encoded register and bitfield @regdef parameter. Call
1926 * dbsc5_reg_ddrphy_masked_write() to write the value to hardware.
1927 */
1928static void dbsc5_ddr_setval_slice(struct udevice *dev, u32 ch, u32 slice, u32 regdef, u32 val)
1929{
1930 const u32 adr = DDR_REGDEF_ADR(regdef) + (0x100 * slice);
1931 const u32 len = DDR_REGDEF_LEN(regdef);
1932 const u32 lsb = DDR_REGDEF_LSB(regdef);
1933 const u32 msk = (len == 32) ? 0xffffffff : ((BIT(len) - 1) << lsb);
1934 const u32 dms = ~((!!(msk & BIT(24)) << 3) | (!!(msk & BIT(16)) << 2) |
1935 (!!(msk & BIT(8)) << 1) | !!(msk & BIT(0))) & 0xf;
1936
1937 dbsc5_reg_ddrphy_masked_write(dev, ch, adr, val << lsb, dms);
1938}
1939
1940/*
1941 * dbsc5_ddr_setval() - Write setting from DDR PHY hardware slice 0
1942 * @dev: DBSC5 device
1943 * @ch: Target channel
1944 * @regdef: Encoded PHY/PI register and bitfield
1945 * @val: Value to be written
1946 *
1947 * Wrapper around dbsc5_ddr_setval_slice() for slice 0.
1948 */
1949static void dbsc5_ddr_setval(struct udevice *dev, u32 ch, u32 regdef, u32 val)
1950{
1951 dbsc5_ddr_setval_slice(dev, ch, 0, regdef, val);
1952}
1953
1954/*
1955 * dbsc5_ddr_setval_all_ch_slice() - Write setting from DDR PHY hardware for all channels and one slice
1956 * @dev: DBSC5 device
1957 * @slice: Target slice
1958 * @regdef: Encoded PHY/PI register and bitfield
1959 * @val: Value to be written
1960 *
1961 * Wrapper around dbsc5_ddr_setval_slice() for slice 0.
1962 */
1963static void dbsc5_ddr_setval_all_ch_slice(struct udevice *dev, u32 slice, u32 regdef, u32 val)
1964{
1965 u32 ch;
1966
1967 r_foreach_vch(dev, ch)
1968 dbsc5_ddr_setval_slice(dev, ch, slice, regdef, val);
1969}
1970
1971/*
1972 * dbsc5_ddr_setval_all_ch() - Write setting from DDR PHY hardware for all channels and slice 0
1973 * @dev: DBSC5 device
1974 * @regdef: Encoded PHY/PI register and bitfield
1975 * @val: Value to be written
1976 *
1977 * Wrapper around dbsc5_ddr_setval_all_ch_slice() for slice 0.
1978 */
1979static void dbsc5_ddr_setval_all_ch(struct udevice *dev, u32 regdef, u32 val)
1980{
1981 dbsc5_ddr_setval_all_ch_slice(dev, 0, regdef, val);
1982}
1983
1984/*
1985 * dbsc5_ddr_setval_all_ch_all_slice() - Write setting from DDR PHY hardware for all channels and all slices
1986 * @dev: DBSC5 device
1987 * @regdef: Encoded PHY/PI register and bitfield
1988 * @val: Value to be written
1989 *
1990 * Wrapper around dbsc5_ddr_setval_all_ch_slice() for slice 0.
1991 */
1992static void dbsc5_ddr_setval_all_ch_all_slice(struct udevice *dev, u32 regdef, u32 val)
1993{
1994 u32 slice;
1995
1996 for (slice = 0; slice < SLICE_CNT; slice++)
1997 dbsc5_ddr_setval_all_ch_slice(dev, slice, regdef, val);
1998}
1999
2000/**
2001 * dbsc5_ddr_getval_slice() - Read setting from DDR PHY/PI hardware
2002 * @dev: DBSC5 device
2003 * @ch: Target channel
2004 * @slice: Target slice
2005 * @regdef: Encoded PHY/PI register and bitfield
2006 *
2007 * Calculate the address and the bit-field from "regdef" value.
2008 * Call dbsc5_reg_ddrphy_read() to read value from the target address.
2009 */
2010static u32 dbsc5_ddr_getval_slice(struct udevice *dev, u32 ch, u32 slice, u32 regdef)
2011{
2012 const u32 adr = DDR_REGDEF_ADR(regdef) + (0x100 * slice);
2013 const u32 len = DDR_REGDEF_LEN(regdef);
2014 const u32 lsb = DDR_REGDEF_LSB(regdef);
2015 const u32 msk = (len == 32) ? 0xffffffff : (BIT(len) - 1);
2016
2017 return (dbsc5_reg_ddrphy_read(dev, ch, adr) >> lsb) & msk;
2018}
2019
2020/**
2021 * dbsc5_ddr_getval() - Read setting from DDR PHY/PI hardware slice 0
2022 * @dev: DBSC5 device
2023 * @ch: Target channel
2024 * @regdef: Encoded PHY/PI register and bitfield
2025 *
2026 * Wrapper around dbsc5_ddr_getval_slice() for slice 0.
2027 */
2028static u32 dbsc5_ddr_getval(struct udevice *dev, u32 ch, u32 regdef)
2029{
2030 return dbsc5_ddr_getval_slice(dev, ch, 0, regdef);
2031}
2032
2033/**
2034 * dbsc5_table_patch_set() - Modify DDR PHY/PI settings table
2035 * @tbl: DDR PHY/PI setting table pointer
2036 * @adrmsk_pi: Use wider address mask for PI register
2037 * @patch: List of modifications to the settings table
2038 * @patchlen: Length of the list of modifications to the settings table
2039 *
2040 * Calculate the target index of settings table, calculate the bit-field
2041 * to write the setting value, and write the setting value to the target
2042 * bit-field in the index.
2043 */
2044static void dbsc5_table_patch_set(u32 *tbl, const bool adrmsk_pi,
2045 const struct dbsc5_table_patch *patch,
2046 int patchlen)
2047{
2048 const u32 adrmsk = adrmsk_pi ? 0x7FF : 0xFF;
2049 u32 adr, len, lsb, msk;
2050 int i;
2051
2052 for (i = 0; i < patchlen; i++) {
2053 adr = DDR_REGDEF_ADR(patch[i].reg);
2054 len = DDR_REGDEF_LEN(patch[i].reg);
2055 lsb = DDR_REGDEF_LSB(patch[i].reg);
2056 msk = (len == 32) ? 0xffffffff : ((BIT(len) - 1) << lsb);
2057
2058 tbl[adr & adrmsk] &= ~msk;
2059 tbl[adr & adrmsk] |= (patch[i].val << lsb) & msk;
2060 }
2061}
2062
2063/**
2064 * dbsc5_ddrtbl_getval() - Read setting from DDR PHY/PI settings table
2065 * @tbl: DDR PHY/PI setting table pointer
2066 * @regdef: Encoded PHY/PI register and bitfield
2067 * @adrmsk_pi: Use wider address mask for PI register
2068 *
2069 * Calculate the target index of *tbl and the bit-field to read the
2070 * setting value and read and return the setting value from the target
2071 * bit-field in the index.
2072 */
2073static u32 dbsc5_ddrtbl_getval(const u32 *tbl, u32 regdef, bool adrmsk_pi)
2074{
2075 const u32 adrmsk = adrmsk_pi ? 0x7FF : 0xFF;
2076 const u32 adr = DDR_REGDEF_ADR(regdef);
2077 const u32 len = DDR_REGDEF_LEN(regdef);
2078 const u32 lsb = DDR_REGDEF_LSB(regdef);
2079 const u32 msk = (len == 32) ? 0xffffffff : (BIT(len) - 1);
2080
2081 return (tbl[adr & adrmsk] >> lsb) & msk;
2082}
2083
2084/**
2085 * dbsc5_f_scale() - Calculate the best value for DBSC timing setting
2086 * @priv: Driver private data
2087 * @frac: Perform fractional rounding
2088 * @ps Optimal setting value in pico second
2089 * @cyc Optimal setting value in cycle count
2090 *
2091 * Convert the optimal value in pico second to in cycle count. Optionally, if @frac is true,
2092 * perform fractional rounding. Compare the value of the result of the conversion with the
2093 * value of the argument @cyc and return the larger value.
2094 */
2095static u32 dbsc5_f_scale(struct renesas_dbsc5_dram_priv *priv, const bool frac, u32 ps, u32 cyc)
2096{
2097 const u32 mul = frac ? 8 : 800000;
2098 const u32 tmp = DIV_ROUND_UP(ps, 10UL) * priv->ddr_mbps;
2099 const u32 f_scale_div = DIV_ROUND_UP(tmp, mul * priv->ddr_mbpsdiv);
2100
2101 return (f_scale_div > cyc) ? f_scale_div : cyc;
2102}
2103
2104/**
2105 * dbsc5_f_scale_js2() - Select optimal settings based on jedec_spec2
2106 * @priv: Driver private data
2107 *
2108 * Calculate and assign each setting value of jedec_spec2 by "dbsc5_f_scale" function.
2109 * Only the following array elements are calculated using different formulas from those
2110 * described above -- JS2_tRRD/JS2_tFAW/JS2_tZQCALns/JS2_tRCpb/JS2_tRCab.
2111 */
2112static void dbsc5_f_scale_js2(struct renesas_dbsc5_dram_priv *priv)
2113{
2114 const int derate = 0;
2115 int i;
2116
2117 for (i = 0; i < JS2_TBLCNT; i++) {
2118 priv->js2[i] = dbsc5_f_scale(priv, false,
2119 jedec_spec2[derate][i].ps,
2120 jedec_spec2[derate][i].cyc);
2121 }
2122
2123 priv->js2[JS2_tZQCALns] = dbsc5_f_scale(priv, false,
2124 jedec_spec2[derate][JS2_tZQCALns].ps * 1000UL, 0);
2125 priv->js2[JS2_tDQ72DQns] = dbsc5_f_scale(priv, false,
2126 jedec_spec2[derate][JS2_tDQ72DQns].ps * 1000UL, 0);
2127 priv->js2[JS2_tCAENTns] = dbsc5_f_scale(priv, false,
2128 jedec_spec2[derate][JS2_tCAENTns].ps * 1000UL, 0);
2129 priv->js2[JS2_tRCpb] = priv->js2[JS2_tRAS] + priv->js2[JS2_tRPpb];
2130 priv->js2[JS2_tRCab] = priv->js2[JS2_tRAS] + priv->js2[JS2_tRPab];
2131 priv->js2[JS2_tRFCab] = dbsc5_f_scale(priv, false,
2132 jedec_spec2_tRFC_ab[priv->max_density] * 1000UL, 0);
2133
2134 priv->js2[JS2_tRBTP] = dbsc5_f_scale(priv, false, 7500, 2) - 2;
2135 priv->js2[JS2_tXSR] = priv->js2[JS2_tRFCab] +
2136 dbsc5_f_scale(priv, false, 7500, 2);
2137 priv->js2[JS2_tPDN] = dbsc5_f_scale(priv, false, 10000, 0) + 1;
2138 priv->js2[JS2_tPDN_DSM] = dbsc5_f_scale(priv, true,
2139 jedec_spec2[derate][JS2_tPDN_DSM].ps * 10UL, 0);
2140 priv->js2[JS2_tXSR_DSM] = dbsc5_f_scale(priv, true,
2141 jedec_spec2[derate][JS2_tXSR_DSM].ps * 10UL, 0);
2142 priv->js2[JS2_tXDSM_XP] = dbsc5_f_scale(priv, true,
2143 jedec_spec2[derate][JS2_tXDSM_XP].ps * 10UL, 0);
2144 priv->js2[JS2_tWLWCKOFF] = dbsc5_f_scale(priv, false, 14000, 5);
2145}
2146
2147/**
2148 * dbsc5_ddrtbl_calc() - Calculate JS1/JS2
2149 * @priv: Driver private data
2150 *
2151 * Determine jedec_spec1 configuration table based on priv->ddr_mbps
2152 * and priv->ddr_mbpsdiv. Calculate the value of the jedec_spec2
2153 * configuration table from priv->ddr_mbps and priv->ddr_mbpsdiv.
2154 */
2155static void dbsc5_ddrtbl_calc(struct renesas_dbsc5_dram_priv *priv)
2156{
2157 int i;
2158
2159 /* Search jedec_spec1 index */
2160 for (i = JS1_USABLEC_SPEC_LO; i < JS1_FREQ_TBL_NUM - 1; i++)
2161 if (js1[i].fx3 * 2 * priv->ddr_mbpsdiv >= priv->ddr_mbps * 3)
2162 break;
2163
Marek Vasutbc90b9c2025-03-16 14:51:40 +01002164 priv->js1_ind = clamp(i, 0, JS1_USABLEC_SPEC_HI);
Marek Vasut1f7ba642024-12-12 14:34:30 +01002165
2166 priv->RL = js1[priv->js1_ind].RLset1;
2167 priv->WL = js1[priv->js1_ind].WLsetA;
2168
2169 /* Calculate jedec_spec2 */
2170 dbsc5_f_scale_js2(priv);
2171};
2172
2173/**
2174 * dbsc5_ddrtbl_load() Load table data into DDR registers
2175 * @dev: DBSC5 device
2176 *
2177 * Copy the base configuration table to a local array. Change PI register table
2178 * settings to match priv->ddr_mbps and priv->ddr_mbpsdiv.
2179 *
2180 * If the set value vref_r is not 0, change the "Read Vref (SoC side) Training range"
2181 * setting in the configuration table.
2182 *
2183 * If the set value vref_w is not 0, change the "Write Vref (MR14, MR15) Training range"
2184 * setting in the configuration table.
2185 *
2186 * If the set value vref_ca is not 0, change the "CA Vref (MR12) Training range"
2187 * setting in the configuration table.
2188 *
2189 * If priv->ddr_mbps/priv->ddr_mbpsdiv is less than 5120,
2190 * change the contents of the PHY register setting table.
2191 * If priv->ddr_mbps/priv->ddr_mbpsdiv is less than 4576,
2192 * change the contents of the PHY register setting table.
2193 *
2194 * Reflect the contents of the configuration table in the register.
2195 */
2196static void dbsc5_ddrtbl_load(struct udevice *dev)
2197{
2198 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
2199 const struct dbsc5_table_patch dbsc5_table_patch_adr_g_mbps = {
2200 PHY_CAL_INTERVAL_COUNT_0, 10000 * priv->ddr_mbps / priv->ddr_mbpsdiv / 8 / 256,
2201 };
2202
2203 const struct dbsc5_table_patch dbsc5_table_patch_pi_js[] = {
2204 { PI_WRLAT_F2, priv->WL },
2205 { PI_TWCKENL_WR_ADJ_F2, (js1[priv->js1_ind].WCKENLW * 4) + 4 },
2206 { PI_TWCKENL_RD_ADJ_F2, (js1[priv->js1_ind].WCKENLR * 4) + 4 },
2207 { PI_TWCKPRE_STATIC_F2, (js1[priv->js1_ind].WCKPRESTA * 4) },
2208 { PI_TWCKPRE_TOGGLE_RD_F2, (js1[priv->js1_ind].WCKPRETGLR) * 4 },
2209 { PI_CASLAT_F2, priv->RL },
2210 { PI_TWCKENL_FS_ADJ_F2, (js1[priv->js1_ind].WCKENLF * 4) + 4 },
2211 { PI_TRFC_F2, priv->js2[JS2_tRFCab] },
2212 { PI_WRLVL_WCKOFF_F2, (priv->js2[JS2_tWLWCKOFF]) + 3 },
2213 { PI_WRLAT_ADJ_F2, (priv->WL * 4) + 2 },
2214 { PI_TCAENT_F2, priv->js2[JS2_tCAENTns] },
2215 { PI_TVREF_LONG_F2, (priv->js2[JS2_tCAENTns]) + 1 },
2216 { PI_TVREF_SHORT_F2, (priv->js2[JS2_tCAENTns]) + 1 },
2217 { PI_TRCD_F2, priv->js2[JS2_tRCD] },
2218 { PI_TRP_F2, priv->js2[JS2_tRPab] },
2219 { PI_TRTP_F2, js1[priv->js1_ind].nRBTP },
2220 { PI_TRAS_MIN_F2, priv->js2[JS2_tRAS] },
2221 { PI_TMRD_F2, (priv->js2[JS2_tMRD]) + 1 },
2222 { PI_TSR_F2, priv->js2[JS2_tSR] },
2223 { PI_TZQCAL_F2, priv->js2[JS2_tZQCALns] },
2224 { PI_TZQLAT_F2, priv->js2[JS2_tZQLAT] },
2225 { PI_TDQ72DQ_F2, priv->js2[JS2_tDQ72DQns] },
2226 { PI_MC_TRFC_F2, priv->js2[JS2_tRFCab] },
2227 };
2228
2229 const u32 vref_r = priv->dbsc5_board_config->bdcfg_vref_r;
2230 const struct dbsc5_table_patch dbsc5_table_patch_slice_vref_r[] = {
2231 { PHY_VREF_INITIAL_START_POINT, vref_r & 0xFF },
2232 { PHY_VREF_INITIAL_STOP_POINT, (vref_r & 0xFF00) >> 8 },
2233 { PHY_VREF_INITIAL_STEPSIZE, (vref_r & 0xFF0000) >> 16 }
2234 };
2235
2236 const u32 vref_w = priv->dbsc5_board_config->bdcfg_vref_w;
2237 const struct dbsc5_table_patch dbsc5_table_patch_pi_vref_w[] = {
2238 { PI_WDQLVL_VREF_INITIAL_START_POINT_F0, vref_w & 0xff },
2239 { PI_WDQLVL_VREF_INITIAL_START_POINT_F1, vref_w & 0xff },
2240 { PI_WDQLVL_VREF_INITIAL_START_POINT_F2, vref_w & 0xff },
2241 { PI_WDQLVL_VREF_INITIAL_STOP_POINT_F0, (vref_w & 0xff00) >> 8 },
2242 { PI_WDQLVL_VREF_INITIAL_STOP_POINT_F1, (vref_w & 0xff00) >> 8 },
2243 { PI_WDQLVL_VREF_INITIAL_STOP_POINT_F2, (vref_w & 0xff00) >> 8 }
2244 };
2245
2246 const u32 vref_ca = priv->dbsc5_board_config->bdcfg_vref_ca;
2247 const struct dbsc5_table_patch dbsc5_table_patch_pi_vref_ca[] = {
2248 { PI_CALVL_VREF_INITIAL_START_POINT_F0, vref_ca & 0xff },
2249 { PI_CALVL_VREF_INITIAL_START_POINT_F1, vref_ca & 0xff },
2250 { PI_CALVL_VREF_INITIAL_START_POINT_F2, vref_ca & 0xff },
2251 { PI_CALVL_VREF_INITIAL_STOP_POINT_F0, (vref_ca & 0xff00) >> 8 },
2252 { PI_CALVL_VREF_INITIAL_STOP_POINT_F1, (vref_ca & 0xff00) >> 8 },
2253 { PI_CALVL_VREF_INITIAL_STOP_POINT_F2, (vref_ca & 0xff00) >> 8 }
2254 };
2255
2256 int i, cs, slice;
2257 u32 adr;
2258
2259 /* Prepare register tables */
2260 memcpy(priv->DDR_PHY_SLICE_REGSET, DDR_PHY_SLICE_REGSET_V4H, sizeof(DDR_PHY_SLICE_REGSET_V4H));
2261 memcpy(priv->DDR_PHY_ADR_V_REGSET, DDR_PHY_ADR_V_REGSET_V4H, sizeof(DDR_PHY_ADR_V_REGSET_V4H));
2262 memcpy(priv->DDR_PHY_ADR_G_REGSET, DDR_PHY_ADR_G_REGSET_V4H, sizeof(DDR_PHY_ADR_G_REGSET_V4H));
2263 memcpy(priv->DDR_PI_REGSET, DDR_PI_REGSET_V4H, sizeof(DDR_PI_REGSET_V4H));
2264
2265 /* Adjust PI parameters */
2266 dbsc5_table_patch_set(priv->DDR_PHY_ADR_G_REGSET, false,
2267 &dbsc5_table_patch_adr_g_mbps, 1);
2268 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2269 dbsc5_table_patch_pi_js,
2270 ARRAY_SIZE(dbsc5_table_patch_pi_js));
2271
2272 if (priv->ddr_mbps < (3201 * priv->ddr_mbpsdiv)) {
2273 /* 2751-3200 */
2274 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2275 dbsc5_table_patch_slice_3200,
2276 ARRAY_SIZE(dbsc5_table_patch_slice_3200));
2277 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2278 dbsc5_table_patch_adr_v_3200,
2279 ARRAY_SIZE(dbsc5_table_patch_adr_v_3200));
2280 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2281 dbsc5_table_patch_pi_3200,
2282 ARRAY_SIZE(dbsc5_table_patch_pi_3200));
2283 } else if (priv->ddr_mbps < (3734 * priv->ddr_mbpsdiv)) {
2284 /* 3201-3733 */
2285 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2286 dbsc5_table_patch_slice_3733,
2287 ARRAY_SIZE(dbsc5_table_patch_slice_3733));
2288 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2289 dbsc5_table_patch_adr_v_3733,
2290 ARRAY_SIZE(dbsc5_table_patch_adr_v_3733));
2291 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2292 dbsc5_table_patch_pi_3733,
2293 ARRAY_SIZE(dbsc5_table_patch_pi_3733));
2294 } else if (priv->ddr_mbps < (4268 * priv->ddr_mbpsdiv)) {
2295 /* 3734-4267 */
2296 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2297 dbsc5_table_patch_slice_4266,
2298 ARRAY_SIZE(dbsc5_table_patch_slice_4266));
2299 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2300 dbsc5_table_patch_adr_v_4266,
2301 ARRAY_SIZE(dbsc5_table_patch_adr_v_4266));
2302 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2303 dbsc5_table_patch_pi_4266,
2304 ARRAY_SIZE(dbsc5_table_patch_pi_4266));
2305 } else if (priv->ddr_mbps < (4801 * priv->ddr_mbpsdiv)) {
2306 /* 4269-4800 */
2307 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2308 dbsc5_table_patch_slice_4800,
2309 ARRAY_SIZE(dbsc5_table_patch_slice_4800));
2310 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2311 dbsc5_table_patch_adr_v_4800,
2312 ARRAY_SIZE(dbsc5_table_patch_adr_v_4800));
2313 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2314 dbsc5_table_patch_pi_4800,
2315 ARRAY_SIZE(dbsc5_table_patch_pi_4800));
2316 } else if (priv->ddr_mbps < (5501 * priv->ddr_mbpsdiv)) {
2317 /* 4801 - 5500 */
2318 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2319 dbsc5_table_patch_slice_5500,
2320 ARRAY_SIZE(dbsc5_table_patch_slice_5500));
2321 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2322 dbsc5_table_patch_adr_v_5500,
2323 ARRAY_SIZE(dbsc5_table_patch_adr_v_5500));
2324 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2325 dbsc5_table_patch_pi_5500,
2326 ARRAY_SIZE(dbsc5_table_patch_pi_5500));
2327 } else if (priv->ddr_mbps < (6001 * priv->ddr_mbpsdiv)) {
2328 /* 5501 - 6000 */
2329 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2330 dbsc5_table_patch_slice_6000,
2331 ARRAY_SIZE(dbsc5_table_patch_slice_6000));
2332 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2333 dbsc5_table_patch_adr_v_6000,
2334 ARRAY_SIZE(dbsc5_table_patch_adr_v_6000));
2335 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2336 dbsc5_table_patch_pi_6000,
2337 ARRAY_SIZE(dbsc5_table_patch_pi_6000));
2338 }
2339
2340 for (cs = 0; cs < CS_CNT; cs++) {
2341 struct dbsc5_table_patch dbsc5_table_patch_pi_mr12[] = {
2342 { PI_DARRAY3_0_CSx_Fx[cs][2], js1[priv->js1_ind].MR1 },
2343 { PI_DARRAY3_1_CSx_Fx[cs][2], js1[priv->js1_ind].MR2 },
2344 };
2345
2346 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2347 dbsc5_table_patch_pi_mr12,
2348 ARRAY_SIZE(dbsc5_table_patch_pi_mr12));
2349 }
2350
2351 /* Read Vref (SoC side) Training range */
2352 if (priv->dbsc5_board_config->bdcfg_vref_r) {
2353 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2354 dbsc5_table_patch_slice_vref_r,
2355 ARRAY_SIZE(dbsc5_table_patch_slice_vref_r));
2356 }
2357
2358 /* Write Vref (MR14, MR15) Training range */
2359 if (priv->dbsc5_board_config->bdcfg_vref_w) {
2360 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2361 dbsc5_table_patch_pi_vref_w,
2362 ARRAY_SIZE(dbsc5_table_patch_pi_vref_w));
2363 }
2364
2365 /* CA Vref (MR12) Training range */
2366 if (priv->dbsc5_board_config->bdcfg_vref_ca) {
2367 dbsc5_table_patch_set(priv->DDR_PI_REGSET, true,
2368 dbsc5_table_patch_pi_vref_ca,
2369 ARRAY_SIZE(dbsc5_table_patch_pi_vref_ca));
2370 }
2371
2372 /* Low Freq setting */
2373 if (priv->ddr_mbps < (8 * 640 * priv->ddr_mbpsdiv)) {
2374 /* CAL_CLK(10-20MHz) */
2375 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2376 &dbsc5_table_patch_slice_mbpsdiv_640, 1);
2377 dbsc5_table_patch_set(priv->DDR_PHY_ADR_V_REGSET, false,
2378 &dbsc5_table_patch_adr_v_mbpsdiv_640, 1);
2379 dbsc5_table_patch_set(priv->DDR_PHY_ADR_G_REGSET, false,
2380 &dbsc5_table_patch_adr_g_mbpsdiv_640, 1);
2381 }
2382
2383 if (priv->ddr_mbps < (8 * 572 * priv->ddr_mbpsdiv)) {
2384 /* CAL_CLK(10-20MHz) */
2385 dbsc5_table_patch_set(priv->DDR_PHY_SLICE_REGSET, false,
2386 &dbsc5_table_patch_slice_mbpsdiv_572, 1);
2387 dbsc5_table_patch_set(priv->DDR_PHY_ADR_G_REGSET, false,
2388 &dbsc5_table_patch_adr_g_mbpsdiv_572, 1);
2389 }
2390
2391 if (priv->ddr_mbps < (8 * 401 * priv->ddr_mbpsdiv)) {
2392 dbsc5_table_patch_set(priv->DDR_PHY_ADR_G_REGSET, false,
2393 dbsc5_table_patch_adr_g_mbpsdiv_400,
2394 ARRAY_SIZE(dbsc5_table_patch_adr_g_mbpsdiv_400));
2395 }
2396
2397 /* SET DATA SLICE TABLE */
2398 for (slice = 0; slice < SLICE_CNT; slice++) {
2399 adr = DDR_PHY_SLICE_REGSET_OFS_V4H + (DDR_PHY_SLICE_REGSET_SIZE_V4H * slice);
2400 for (i = 0; i < DDR_PHY_SLICE_REGSET_NUM_V4H; i++)
2401 dbsc5_reg_ddrphy_write_all(dev, adr + i, priv->DDR_PHY_SLICE_REGSET[i]);
2402 }
2403
2404 /* SET ADR SLICE TABLE */
2405 for (i = 0; i < DDR_PHY_ADR_V_REGSET_NUM_V4H; i++)
2406 dbsc5_reg_ddrphy_write_all(dev, DDR_PHY_ADR_V_REGSET_OFS_V4H + i, priv->DDR_PHY_ADR_V_REGSET[i]);
2407
2408 /* SET ADRCTRL SLICE TABLE */
2409 for (i = 0; i < DDR_PHY_ADR_G_REGSET_NUM_V4H; i++)
2410 dbsc5_reg_ddrphy_write_all(dev, DDR_PHY_ADR_G_REGSET_OFS_V4H + i, priv->DDR_PHY_ADR_G_REGSET[i]);
2411
2412 /* SET PI REGISTERS */
2413 for (i = 0; i < DDR_PI_REGSET_NUM_V4H; i++)
2414 dbsc5_reg_ddrphy_write_all(dev, DDR_PI_REGSET_OFS_V4H + i, priv->DDR_PI_REGSET[i]);
2415}
2416
2417/**
2418 * dbsc5_ddr_config() - Configure DDR registers
2419 * @dev: DBSC5 device
2420 *
2421 * Set up wiring for DQ and DM pins and VREF_DRIVING. Set the CA pin wiring
2422 * and ADR_CALVL_SWIZZLE settings. Make wiring settings for the CS pin. When
2423 * memory rank is 1, set RANK setting to 1 to disable CS training. Configure
2424 * the DATA_BYTE_SWAP setting.
2425 */
2426static void dbsc5_ddr_config(struct udevice *dev)
2427{
2428 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
2429 u32 ca_swap, cs_swap, dqs_swap;
2430 u32 ch, slice;
2431
2432 r_foreach_vch(dev, ch) {
2433 /* Board settings (DQ, DM, VREF_DRIVING) */
2434 dqs_swap = priv->dbsc5_board_config->ch[ch].bdcfg_dqs_swap;
2435 for (slice = 0; slice < SLICE_CNT; slice++) {
2436 dbsc5_ddr_setval_slice(dev, ch, slice, PHY_DQ_DM_SWIZZLE0,
2437 priv->dbsc5_board_config->ch[ch].bdcfg_dq_swap[slice]);
2438 dbsc5_ddr_setval_slice(dev, ch, slice, PHY_DQ_DM_SWIZZLE1,
2439 priv->dbsc5_board_config->ch[ch].bdcfg_dm_swap[slice]);
2440 dbsc5_ddr_setval_slice(dev, ch, slice, PHY_CALVL_VREF_DRIVING_SLICE,
2441 !((dqs_swap >> (4 * slice)) & 1));
2442 }
2443 dbsc5_ddr_setval(dev, ch, PHY_DATA_BYTE_ORDER_SEL,
2444 priv->dbsc5_board_config->ch[ch].bdcfg_dqs_swap | 0x76543200);
2445
2446 /* Board settings (CA, ADDR_MUX) */
2447 ca_swap = priv->dbsc5_board_config->ch[ch].bdcfg_ca_swap;
2448
2449 /* ADDR_MUX */
2450 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_0, ca_swap & 0xf);
2451 ca_swap >>= 4;
2452 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_1, ca_swap & 0xf);
2453 ca_swap >>= 4;
2454 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_2, ca_swap & 0xf);
2455 ca_swap >>= 4;
2456 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_3, ca_swap & 0xf);
2457 ca_swap >>= 4;
2458 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_4, ca_swap & 0xf);
2459 ca_swap >>= 4;
2460 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_5, ca_swap & 0xf);
2461 ca_swap >>= 4;
2462 dbsc5_ddr_setval(dev, ch, PI_ADDR_MUX_6, ca_swap & 0xf);
2463 ca_swap >>= 4;
2464
2465 /* ADR_CALVL_SWIZZLE */
2466 ca_swap = priv->dbsc5_board_config->ch[ch].bdcfg_ca_swap;
2467 dbsc5_ddr_setval(dev, ch, PHY_ADR_CALVL_SWIZZLE0, ca_swap & 0x0fffffff);
2468
2469 /* Board settings (CS) */
2470 /* CKE_MUX */
2471 /* SoC CKE -> DRAM CS */
2472 cs_swap = priv->dbsc5_board_config->ch[ch].bdcfg_cs_swap;
2473 dbsc5_ddr_setval(dev, ch, PI_CKE_MUX_0, (cs_swap & 0xf) + 2);
2474 dbsc5_ddr_setval(dev, ch, PI_CKE_MUX_1, ((cs_swap >> 4) & 0xf) + 2);
2475 dbsc5_ddr_setval(dev, ch, PHY_CS_ACS_ALLOCATION_BIT2_2, (cs_swap & 0xf) + 1);
2476 dbsc5_ddr_setval(dev, ch, PHY_CS_ACS_ALLOCATION_BIT3_2, ((cs_swap >> 4) & 0xf) + 1);
2477
2478 /* Mask CS_MAP if RANK1 is not found */
2479 if (!(priv->ch_have_this_cs[1] & BIT(ch))) {
2480 dbsc5_ddr_setval(dev, ch, PHY_ADR_CALVL_RANK_CTRL, 0x0);
2481 for (slice = 0; slice < SLICE_CNT; slice++)
2482 dbsc5_ddr_setval_slice(dev, ch, slice, PHY_PER_CS_TRAINING_EN, 0x0);
2483 }
2484 }
2485
2486 r_foreach_vch(dev, ch) {
2487 /* DATA_BYTE_SWAP */
2488 dqs_swap = priv->dbsc5_board_config->ch[ch].bdcfg_dqs_swap;
2489
2490 dbsc5_ddr_setval(dev, ch, PI_DATA_BYTE_SWAP_EN, 0x1);
2491 dbsc5_ddr_setval(dev, ch, PI_DATA_BYTE_SWAP_SLICE0, dqs_swap & 0xf);
2492 dbsc5_ddr_setval(dev, ch, PI_DATA_BYTE_SWAP_SLICE1, (dqs_swap >> 4) & 0xf);
2493
2494 if (!(priv->ch_have_this_cs[1] & BIT(ch)))
2495 dbsc5_ddr_setval(dev, ch, PI_CS_MAP, 0x1);
2496 }
2497}
2498
2499/**
2500 * dbsc5_dbsc_regset_pre() - Configure primary DDR registers
2501 * @dev: DBSC5 device
2502 *
2503 * Set SDRAM type, Burst length, and PHY type. Frequency mode setting.
2504 * Write SDRAM configuration contents to registers.
2505 */
2506static void dbsc5_dbsc_regset_pre(struct udevice *dev)
2507{
2508#define DBMEMCONF_REG(d3, row, bg, bank, col, dw) \
2509 (((d3) << 30) | ((row) << 24) | ((bg) << 20) | ((bank) << 16) | ((col) << 8) | (dw))
2510#define DBMEMCONF_REGD(density) /* 16bit */ \
2511 DBMEMCONF_REG(((density) % 2), ((((density) + 1) / 2) + (28 - 2 - 2 - 10 - 1)), 2, 2, 10, 1)
2512
2513 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
2514 void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
2515 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
2516 u32 density;
2517 u32 ch, cs;
2518
2519 /* Primary settings */
2520 /* LPDDR5, BL=16, DFI interface */
2521 dbsc5_reg_write(regs_dbsc_d + DBSC_DBMEMKIND, 0xC);
2522 dbsc5_reg_write(regs_dbsc_a + DBSC_DBMEMKINDA, 0xC);
2523 dbsc5_reg_write(regs_dbsc_d + DBSC_DBBL, 0x2);
2524 dbsc5_reg_write(regs_dbsc_a + DBSC_DBBLA, 0x2);
2525 dbsc5_reg_write(regs_dbsc_d + DBSC_DBPHYCONF0, 0x1);
2526
2527 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCONF0, 0x1);
2528
2529 /* FREQRATIO=2 */
2530 dbsc5_reg_write(regs_dbsc_d + DBSC_DBSYSCONF1, 0x20000);
2531 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCONF1A, 0x0);
2532
2533 dbsc5_reg_write(regs_dbsc_d + DBSC_DBSYSCONF2, 0x1);
2534 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCONF2A, 0x241);
2535
2536 r_foreach_ech(ch) {
2537 for (cs = 0; cs < CS_CNT; cs++) {
2538 if (priv->ddr_density[ch][cs] == 0xFF) {
2539 writel(0x00, regs_dbsc_d + DBSC_DBMEMCONF(ch, cs));
2540 writel(0x00, regs_dbsc_a + DBSC_DBMEMCONFA(ch, cs));
2541 } else {
2542 density = priv->ddr_density[ch][cs];
2543 writel(DBMEMCONF_REGD(density),
2544 regs_dbsc_d + DBSC_DBMEMCONF(ch, cs));
2545 writel(DBMEMCONF_REGD(density),
2546 regs_dbsc_a + DBSC_DBMEMCONFA(ch, cs));
2547 }
2548 }
2549 }
2550}
2551
2552/**
2553 * dbsc5_dbsc_regset() - Set DBSC timing parameters
2554 * @dev: DBSC5 device
2555 *
2556 * Set the timing registers of the DBSC.
2557 * Configure Scheduler settings.
2558 */
2559static void dbsc5_dbsc_regset(struct udevice *dev)
2560{
2561 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
2562 void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
2563 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
2564 u32 tmp[4];
2565
2566 /* DBTR0.CL : RL */
2567 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(0), priv->RL);
2568
2569 /* DBTR1.CWL : WL */
2570 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(1), priv->WL);
2571
2572 /* DBTR2.AL = 0 */
2573 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(2), 0x0);
2574
2575 /* DBTR3.TRCD: tRCD */
2576 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(3), priv->js2[JS2_tRCD]);
2577
2578 /* DBTR4.TRPA,TRP: tRPab,tRPpb */
2579 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(4), (priv->js2[JS2_tRPab] << 16) |
2580 priv->js2[JS2_tRPpb]);
2581
2582 /* DBTR5.TRC : tRCpb */
2583 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(5), priv->js2[JS2_tRCpb]);
2584
2585 /* DBTR6.TRAS : tRAS */
2586 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(6), priv->js2[JS2_tRAS]);
2587
2588 /* DBTR7.TRRD : tRRD */
2589 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(7), ((priv->js2[JS2_tRRD] - 1) << 16) |
2590 (priv->js2[JS2_tRRD] - 1));
2591
2592 /* DBTR8.TFAW : tFAW */
2593 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(8), priv->js2[JS2_tFAW] - 1);
2594
2595 /* DBTR9.TRDPR: nRBTP */
2596 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(9), js1[priv->js1_ind].nRBTP);
2597
2598 /* DBTR10.TWR : nWR */
2599 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(10), js1[priv->js1_ind].nWR);
2600
2601 /*
2602 * DBTR11.TRDWR : RL + BL/n_max + RU(tWCK2DQO(max)/tCK) +
2603 * RD(tRPST/tCK) - ODTLon - RD(tODTon(min)/tCK) + 1 + feature
2604 */
2605 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(11),
2606 priv->RL + 4 + priv->js2[JS2_tWCK2DQO_HF] -
Marek Vasut0da0bd22025-03-16 14:51:41 +01002607 js1[priv->js1_ind].ODTLon - priv->js2[JS2_tODTon_min] + 2);
Marek Vasut1f7ba642024-12-12 14:34:30 +01002608
2609 /* DBTR12.TWRRD_S : WL + BL/2 + tWTR_S, TWRRD_L : WL + BL + tWTR_L */
2610 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(12),
2611 ((priv->WL + 2 + priv->js2[JS2_tWTR_S]) << 16) |
2612 (priv->WL + 4 + priv->js2[JS2_tWTR_L]));
2613
2614 /* DBTR13.TRFCAB : tRFCab */
2615 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(13), priv->js2[JS2_tRFCab]);
2616
2617 /* DBTR14.TCSCAL,TCKEHDLL,tCKEH : tCSCAL,tXP,tXP */
2618 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(14), (priv->js2[JS2_tCSCAL] << 24) |
2619 (priv->js2[JS2_tXP] << 16) |
2620 priv->js2[JS2_tXP]);
2621
2622 /* DBTR15.TESPD,TCKESR,TCKEL : tESPD = 2,tSR,tSR */
2623 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(15), (0x02 << 24) |
2624 (priv->js2[JS2_tSR] << 16) |
2625 priv->js2[JS2_tSR]);
2626
2627 /* DBTR16 */
2628 /* wdql(tphy_wrlat + tphy_wrdata) */
2629 tmp[0] = (priv->WL * 4) - 1 + 5;
2630 /* dqenltcy(tphy_wrlat) */
2631 tmp[1] = (priv->WL * 4) - 2 - 2 + 5;
2632 /* dql(tphy_rdlat + trddata_en) RL * 4 + phy_rptr_update + phy_rddqs_latency_adjust + 39 */
2633 tmp[2] = (priv->RL * 4) +
2634 dbsc5_ddrtbl_getval(priv->DDR_PHY_SLICE_REGSET, PHY_RPTR_UPDATE, false) +
2635 dbsc5_ddrtbl_getval(priv->DDR_PHY_SLICE_REGSET, PHY_RDDQS_LATENCY_ADJUST, false) +
2636 39;
2637 /* dqienltncy(trddata_en) RL * 4 - phy_rddata_en_dly_X + 4 * phy_wck_freq_ratio_X */
2638 tmp[3] = (priv->RL * 4) + 4 -
2639 dbsc5_ddrtbl_getval(priv->DDR_PHY_SLICE_REGSET, PHY_RDDATA_EN_DLY, false);
2640 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(16), (tmp[3] << 24) | (tmp[2] << 16) |
2641 (tmp[1] << 8) | tmp[0]);
2642
2643 /* DBTR17.TMODRD,TMOD: tMRR,tMRW */
2644 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(17), (priv->js2[JS2_tMRR] << 24) |
2645 (priv->js2[JS2_tMRW] << 16));
2646
2647 /* DBTR18. RODTL, RODTA = 0 */
2648 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(18), 0x0);
2649
2650 /* DBTR19. TZQCL, TZQCS = 0 */
2651 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(19), 0x0);
2652
2653 /* DBTR20.TXSDLL, TXS : tXSR,tXSR */
2654 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(20), ((priv->js2[JS2_tXSR]) << 16) |
2655 priv->js2[JS2_tXSR]);
2656
2657 /* DBTR21.TCCD */
2658 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(21), (priv->ddr_tccd << 16) |
2659 (priv->ddr_tccd * 2));
2660
2661 /* DBTR22.TZQCAL,TZQLAT : tZQCAL,tZQLAT */
2662 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(22), (priv->js2[JS2_tZQCALns] << 16) | priv->js2[JS2_tZQLAT]);
2663
2664 /* DBTR23. RRSPC = 0 */
2665 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(23), 0x0);
2666
2667 /* DBTR24 */
2668 /* WRCSLAT(tphy_wrcslat) */
2669 tmp[0] = (priv->WL * 4) - 2;
2670 /* WRCSGAP(tphy_wrcsgap) */
2671 tmp[1] = 0x0C;
2672 /* RDCSLAT(tphy_rdcslat) */
2673 tmp[2] = priv->RL * 4;
2674 /* RDCSGAP(tphy_rdcsgap) */
2675 tmp[3] = 0x0C;
2676 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(24), (tmp[3] << 24) | (tmp[2] << 16) |
2677 (tmp[1] << 8) | tmp[0]);
2678
2679 /* DBTR25. TWDQLVLDIS = 0 */
2680 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(25), 0x0);
2681
2682 /* DBTR26. TWCK2DQOOSC,TDQSOSC : WCK2DQI interval timer run time, WCK2DQO interval timer run time */
2683 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(26), 0x0);
2684
2685 /* DBTR27.TPDN : tPDN */
2686 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(27), priv->js2[JS2_tPDN]);
2687
2688 /* DBTR28.txsrdsm : tXSR_DSM */
2689 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(28), priv->js2[JS2_tXSR_DSM]);
2690
2691 /* DBTR29.tdsmxp : tXDSM_XP */
2692 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(29), priv->js2[JS2_tXDSM_XP]);
2693
2694 /* DBTR30.TCMDPD : tCMDPD = 3 */
2695 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(30), 0x3);
2696
2697 /* DBTR31.TWCK2DQOMAX,TWCK2DQIMAX : tWCK2DQI/O_HF/LF */
2698 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(31), (priv->js2[JS2_tWCK2DQO_HF] << 4) |
2699 priv->js2[JS2_tWCK2DQI_HF]);
2700
2701 /* DBTR32 */
2702 /* twckenr */
2703 tmp[0] = (js1[priv->js1_ind].WCKENLR * 4) + 4 - 1;
2704 /* twckenw */
2705 tmp[1] = (js1[priv->js1_ind].WCKENLW * 4) + 4 - 1;
2706 /* twckenlf */
2707 tmp[2] = (js1[priv->js1_ind].WCKENLF * 4) + 4;
2708 /* twckpresta */
2709 tmp[3] = js1[priv->js1_ind].WCKPRESTA * 4;
2710 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(32), (tmp[3] << 24) | (tmp[2] << 16) |
2711 (tmp[1] << 8) | tmp[0]);
2712
2713 /* DBTR33 */
2714 /* TWCKTGL */
2715 tmp[0] = 4;
2716 /* TWCKDIS (RL+ bl/n_max) * 4 + RU(tWCKPST/tWCK) : tWCKPST = 2.5(MR10[3:2]) */
2717 tmp[1] = ((priv->RL + 4) * 4) + 3;
2718 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(33), (tmp[1] << 8) | tmp[0]);
2719
2720 /* DBTR34 */
2721 /* TWCKSUS = 4 */
2722 tmp[0] = 4;
2723 /* TWCKPST RU(tWCKPST/tCK) : tWCKPST=2.5(MR10[3:2]) */
2724 tmp[1] = 1;
2725 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(34), (tmp[1] << 8) | tmp[0]);
2726
2727 /* DBTR35 */
2728 /* TRD2WCKOFF RL + BL/n_max + RD(tWCKPST/tCK) + 1 */
2729 tmp[0] = priv->RL + 4 + 0 + 1;
2730 /* TWR2WCKOFF WL + BL/n_max + RD(tWCKPST/tCK) + 1 */
2731 tmp[1] = priv->WL + 4 + 0 + 1;
2732 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(35), (tmp[1] << 16) | tmp[0]);
2733
2734 /* DBTR36 */
2735 /* TWSSUSWRX : CAS(WCKSUS)WRX */
2736 tmp[0] = 3;
2737 /* TWSOFFWRX : CAS(WS_OFF)WRX */
2738 tmp[1] = 3;
2739 /* TWSFSWRX : CAS(WS_FS)WRX */
2740 tmp[2] = 2;
2741 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(36), (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]);
2742
2743 /* DBTR37 */
2744 /* tOSCO */
2745 dbsc5_reg_write(regs_dbsc_d + DBSC_DBTR(37), priv->js2[JS2_tOSCODQI]);
2746
2747 /* DBRNK2 */
2748 /* RNKRR = 12 */
2749 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRNK(2), 0xCC);
2750
2751 /* DBRNK3 */
2752 /* RNKRW = 6 */
2753 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRNK(3), 0x66);
2754
2755 /* DBRNK4 */
2756 /* RNKWR = 6 */
2757 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRNK(4), 0x66);
2758
2759 /* DBRNK5 */
2760 /* RNKWW = 14 */
2761 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRNK(5), 0xEE);
2762
2763 /* Timing registers for Scheduler */
2764 /* SCFCTST0 */
2765 /* SCPREACT */
2766 tmp[0] = priv->js2[JS2_tRPpb] * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2767 priv->ddr_mbps / priv->bus_clkdiv;
2768 /* SCACTRDWR */
2769 tmp[1] = (priv->WL + 2 + 1 + js1[priv->js1_ind].nWR + priv->js2[JS2_tRPpb]) *
2770 priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2771 priv->ddr_mbps / priv->bus_clkdiv;
2772 /* SCRDACRT */
2773 tmp[2] = ((js1[priv->js1_ind].nRBTP + 2) + priv->js2[JS2_tRPpb]) *
2774 priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2775 priv->ddr_mbps / priv->bus_clkdiv;
2776 /* SCACTACT */
2777 tmp[3] = priv->js2[JS2_tRCpb] * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2778 priv->ddr_mbps / priv->bus_clkdiv;
2779 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSCHFCTST0, (tmp[3] << 24) | (tmp[2] << 16) |
2780 (tmp[1] << 8) | tmp[0]);
2781
2782 /* SCFCTST1 */
2783 /* SCASYNCOFS */
2784 tmp[0] = 12;
2785 /* SCACTRDWR */
2786 tmp[1] = priv->js2[JS2_tRCD] * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2787 priv->ddr_mbps / priv->bus_clkdiv;
2788 /* SCWRRD */
2789 tmp[2] = (readl(regs_dbsc_d + DBSC_DBTR(12)) & 0xFF) * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2790 priv->ddr_mbps / priv->bus_clkdiv;
2791 /* SCRDWR */
2792 tmp[3] = (readl(regs_dbsc_d + DBSC_DBTR(11)) & 0xFF) * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2793 priv->ddr_mbps / priv->bus_clkdiv;
2794 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSCHFCTST1, (tmp[3] << 24) | (tmp[2] << 16) |
2795 (tmp[1] << 8) | tmp[0]);
2796
2797 /* DBSCHRW1 */
2798 /* SCTRFCAB */
2799 tmp[0] = (priv->js2[JS2_tRFCab] + priv->js2[JS2_tZQLAT]) *
2800 priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2801 priv->ddr_mbps / priv->bus_clkdiv;
2802 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSCHRW1, tmp[0]);
2803
2804 /* DBSCHTR0 */
2805 /* SCDT0 */
2806 tmp[0] = (4 * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2807 priv->ddr_mbps / priv->bus_clkdiv) - 1;
2808 /* SCDT1 */
2809 tmp[1] = (8 * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2810 priv->ddr_mbps / priv->bus_clkdiv) - 1;
2811 /* SCDT2 */
2812 tmp[2] = (12 * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2813 priv->ddr_mbps / priv->bus_clkdiv) - 1;
2814 /* SCDT3 */
2815 tmp[3] = (16 * priv->bus_clk * priv->ddr_mbpsdiv * 8UL /
2816 priv->ddr_mbps / priv->bus_clkdiv) - 1;
2817 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSCHTR0, (tmp[3] << 24) | (tmp[2] << 16) |
2818 (tmp[1] << 8) | tmp[0]);
2819
2820 /* QOS and CAM */
2821 dbsc5_reg_write(regs_dbsc_a + DBSC_DBBCAMDIS, 0x1);
2822}
2823
2824/**
2825 * dbsc5_dbsc_regset_post() - Set DBSC registers
2826 * @dev: DBSC5 device
2827 *
2828 * If memory rank is 2, CS_TRAINING_EN is set to the other side.
2829 * Configure DBI read/write settings. Execute DRAM refresh settings.
2830 * Set WTmode of DFI PHY to OFF. Set up PHY Periodic Write DQ training.
2831 * Set WTmode of DFI PHY to ON. Calibration settings for PHY PAD.
2832 * Set SDRAM calibration. Make DFI Control Update Setting settings.
2833 * In the case of WARM_BOOT, cancel the self-refresh setting.
2834 * Enable SDRAM auto refresh. Set up PHY Periodic Write DQ training.
2835 * Enable access to SDRAM.
2836 */
2837static void dbsc5_dbsc_regset_post(struct udevice *dev)
2838{
2839 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
2840 void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
2841 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
2842 /* Average periodic refresh interval/Average Refresh Interval [ns] */
2843 const u32 dbsc_refint = 1920;
2844 /* 0: Average interval is REFINT, 1: Average interval is 1/2 REFINT */
2845 const u32 dbsc_refints = 0;
2846 /* Periodic-WriteDQ/ReadDQ Training Interval [us] */
2847 const u32 periodic_training_interval = 20000;
2848 u32 phymster_req_interval;
2849 u32 ch, slice;
2850 u32 clk_count;
2851 u32 refcycle;
2852 u32 ctrl_clk;
2853 u32 reg;
2854
2855 if ((renesas_get_cpu_rev_integer() < 3) && priv->ch_have_this_cs[1]) {
2856 r_foreach_vch(dev, ch) {
2857 for (slice = 0; slice < SLICE_CNT; slice++) {
2858 dbsc5_ddr_setval_slice(dev, ch, slice,
2859 PHY_PER_CS_TRAINING_EN,
2860 0x0);
2861 }
2862 }
2863 }
2864
2865 dbsc5_reg_write(regs_dbsc_d + DBSC_DBDBICNT, 0x3);
2866
2867 /* set REFCYCLE */
2868 refcycle = dbsc_refint * priv->ddr_mbps / 8000 / priv->ddr_mbpsdiv;
2869 /* refpmax=8 */
2870 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRFCNF1, (refcycle & 0xFFFF) | BIT(19));
2871 /* refpmin=1 */
2872 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRFCNF2, dbsc_refints | BIT(16));
2873
2874 dbsc5_reg_write(regs_dbsc_d + DBSC_DBDFIPMSTRCNF, 0x0);
2875
2876 /* Periodic-WriteDQ Training setting */
2877 dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_EN_F2, 0x3);
2878 dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_VREF_EN, 0x0);
2879 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_DATA_DC_WDQLVL_ENABLE, 0x0);
2880 dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_PERIODIC, 0x1);
2881
2882 /* Periodic-ReadDQ Training setting */
2883 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_EN_F2, 0x3);
2884 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_VREF_EN_F2, 0x0);
2885 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDLVL_DLY_STEP, 0x4);
2886 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_PERIODIC, 0x1);
2887
2888 /* DFI_PHYMSTR_ACK , WTmode = b'01 */
2889 dbsc5_reg_write(regs_dbsc_d + DBSC_DBDFIPMSTRCNF, 0x11);
2890
2891 /* periodic SoC zqcal enable */
2892 reg = dbsc5_ddrtbl_getval(priv->DDR_PHY_ADR_G_REGSET, PHY_CAL_MODE_0, false);
2893 dbsc5_ddr_setval_all_ch(dev, PHY_CAL_MODE_0, reg | BIT(1));
2894
2895 /* Periodic dram zqcal enable */
2896 dbsc5_reg_write(regs_dbsc_d + DBSC_DBCALCNF, 0x1000010);
2897
2898 /* Periodic phy ctrl update enable */
2899 dbsc5_reg_write(regs_dbsc_d + DBSC_DBDFICUPDCNF, 0x504C0001);
2900
2901 /* Set Auto Refresh */
2902 dbsc5_reg_write(regs_dbsc_d + DBSC_DBRFEN, 0x1);
2903
2904 /* Periodic-WriteDQ/ReadDQ Training Interval setting */
2905 phymster_req_interval = periodic_training_interval - 3000;
2906 clk_count = 1024 - (dbsc5_ddrtbl_getval(priv->DDR_PI_REGSET, PI_LONG_COUNT_MASK, true) * 32);
2907 ctrl_clk = priv->ddr_mbps / priv->ddr_mbpsdiv / 8;
2908 reg = phymster_req_interval * ctrl_clk / clk_count;
2909
2910 dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_INTERVAL, reg);
2911
2912 /* DRAM access enable */
2913 dbsc5_reg_write(regs_dbsc_a + DBSC_DBACEN, 0x1);
2914}
2915
2916/**
2917 * dbsc5_pi_training() - Training by PI
2918 * @dev: DBSC5 device
2919 *
2920 * Enable WCK signal training and read gate training. Start PI training.
2921 * After DFI initialization for all channels is once turned off, turned
2922 * on all chennels of it. Power down the DRAM device once and then release
2923 * the power down mode. Perform training in low frequency mode and training
2924 * in high frequency mode. Wait for the DFI training completion status
2925 * bit to stand until the time limit. Turn off DFI initialization for all
2926 * channels. Turn off WTMODE of DFI PHY. Check if CA/CS Training has failed.
2927 * Check if Wrlvl training is in error. If an error can be confirmed from
2928 * the check result, the result is returned as a return value. Clear the
2929 * status register for PI training.
2930 */
2931static u32 dbsc5_pi_training(struct udevice *dev)
2932{
2933 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
2934 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
2935 const int retry_max = 0x10000;
2936 u32 ca_training_ng = 0;
2937 u32 wr_training_ng = 0;
2938 u32 phytrainingok = 0;
2939 u32 complete_ng = 0;
2940 bool frqchg_req;
2941 u32 ch, reg;
2942 int retry;
2943 int ret;
2944
2945 /* Init start */
2946 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_EN_F2, 0x0);
2947 dbsc5_ddr_setval_all_ch(dev, PI_WRDCM_LVL_EN_F2, 0x0);
2948 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_EN_F2, 0x0);
2949 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_EN_F2, 0x0);
2950 dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_EN_F2, 0x0);
2951 dbsc5_ddr_setval_all_ch(dev, PI_DFS_INITIALIZATION_SEQ_9, 0x0);
2952 dbsc5_ddr_setval_all_ch(dev, PI_DFS_INITIALIZATION_SEQ_10, 0x0);
2953
2954 /* PI_START */
2955 dbsc5_ddr_setval_all_ch(dev, PI_START, 0x1);
2956
2957 r_foreach_vch(dev, ch)
2958 writel(0x20, regs_dbsc_d + DBSC_DBDFICNT(ch));
2959
2960 r_foreach_vch(dev, ch)
2961 writel(0x21, regs_dbsc_d + DBSC_DBDFICNT(ch));
2962
2963 /* Dummy PDE */
Marek Vasute68e9152025-03-25 23:43:31 +01002964 dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_PD,
2965 DBSC_DBCMD_CMD_CHANNEL_ALL,
2966 DBSC_DBCMD_CMD_RANK_ALL, 0);
Marek Vasut1f7ba642024-12-12 14:34:30 +01002967
2968 /* PDX */
Marek Vasute68e9152025-03-25 23:43:31 +01002969 dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_PD,
2970 DBSC_DBCMD_CMD_CHANNEL_ALL,
2971 DBSC_DBCMD_CMD_RANK_ALL, 1);
Marek Vasut1f7ba642024-12-12 14:34:30 +01002972
2973 /* Wait init_complete */
2974 for (retry = 0; retry < retry_max; retry++) {
2975 frqchg_req = false;
2976 for (ch = 0; ch < DRAM_CH_CNT; ch++) {
2977 if (!((~phytrainingok & priv->ddr_phyvalid) & BIT(ch)))
2978 continue;
2979
2980 if (!(readl(regs_dbsc_d + DBSC_DBPDSTAT0(ch)) & BIT(0)))
2981 continue;
2982
2983 frqchg_req = true;
2984 break;
2985 }
2986
2987 if (frqchg_req) {
2988 ret = dbsc5_clk_pll3_freq(dev);
2989 if (ret)
2990 break;
2991 } else {
2992 r_foreach_vch(dev, ch) {
2993 if (readl(regs_dbsc_d + DBSC_DBDFISTAT(ch)) & BIT(0))
2994 phytrainingok |= BIT(ch);
2995 }
2996
2997 if (phytrainingok == priv->ddr_phyvalid)
2998 break;
2999 }
3000 }
3001
3002 /*
3003 * dbdficnt0:
3004 * dfi_dram_clk_disable=0
3005 * dfi_frequency = 0
3006 * freq_ratio = 10 (4:1)
3007 * init_start =0
3008 */
3009 r_foreach_vch(dev, ch)
3010 writel(0x20, regs_dbsc_d + DBSC_DBDFICNT(ch));
3011
3012 /* DFI_PHYMSTR_ACK */
3013 dbsc5_reg_write(regs_dbsc_d + DBSC_DBDFIPMSTRCNF, 0x1);
3014
3015 /* Error check */
3016 r_foreach_vch(dev, ch) {
3017 /* CA/CS Training Error Check */
3018 /* PI_CALVL_ERROR_BIT */
3019 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(4);
3020 /* Error on decrement/increment pass */
3021 reg |= dbsc5_ddr_getval(dev, ch, PHY_ADR_CALVL_OBS1) & (0x3 << 30);
3022 /* Start outside of initial search range */
3023 reg |= dbsc5_ddr_getval(dev, ch, PHY_ADR_CALVL_OBS2) & (0x3 << 24);
3024 /* CSlvl error */
3025 reg |= dbsc5_ddr_getval(dev, ch, PHY_CSLVL_OBS1) & (0xF << 28);
3026 if (reg) {
3027 ca_training_ng |= BIT(ch);
3028 printf("%s pi_training_error:1\n", __func__);
3029 }
3030
3031 /* Wrlvl Error Check */
3032 /* PI_WRLVL_ERROR_BIT */
3033 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(3);
3034 /* SLICE0 wrlvl error */
3035 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_STATUS_OBS) & BIT(12);
3036 /* SLICE1 wrlvl error */
3037 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_STATUS_OBS) & BIT(12);
3038 /* SLICE0 wrlvl error */
3039 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_ERROR_OBS);
3040 /* SLICE1 wrlvl error */
3041 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_ERROR_OBS);
3042 if (reg) {
3043 wr_training_ng |= BIT(ch);
3044 printf("%s pi_training_error:2\n", __func__);
3045 }
3046 }
3047
3048 complete_ng = (wr_training_ng | ca_training_ng);
3049 if (complete_ng)
3050 return ~complete_ng;
3051
3052 /* PI_INT_ACK assert */
3053 r_foreach_vch(dev, ch) {
3054 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
3055 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
3056 }
3057
3058 return phytrainingok;
3059}
3060
3061/**
3062 * dbsc5_write_leveling_adjust() - Write Leveling Cycle Adjust
3063 * @dev: DBSC5 device
3064 *
3065 * Get delay value from the result write leveling of slice 0 and 1.
3066 * Calculate latency of dfi_wrdata_en / dfi_wrdata / dfi_wrdata_mask
3067 * signals based on delay values.
3068 */
3069static void dbsc5_write_leveling_adjust(struct udevice *dev)
3070{
3071 u32 result_hard0, result_hard1;
3072 u32 avg, avg_frac, avg_cycle;
3073 u32 ch;
3074
3075 r_foreach_vch(dev, ch) {
3076 /* SLICE0 */
3077 result_hard0 = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_HARD0_DELAY_OBS);
3078 result_hard1 = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_HARD1_DELAY_OBS);
3079
3080 avg = result_hard0 + result_hard1;
3081 if (result_hard0 > result_hard1)
3082 avg += 0x400;
3083 avg /= 2;
3084
3085 avg_frac = avg & 0xFF;
3086 avg_cycle = (avg >> 8) & 0x3;
3087
3088 if (avg_cycle == 0x3) {
3089 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_DEC, 0x1);
3090 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_ADD, 0x0);
3091 } else {
3092 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_DEC, 0x0);
3093 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_ADD, avg_cycle);
3094 }
3095 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_WRITE_PATH_LAT_FRAC, avg_frac);
3096
3097 /* SLICE1 */
3098 result_hard0 = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_HARD0_DELAY_OBS);
3099 result_hard1 = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_HARD1_DELAY_OBS);
3100
3101 avg = result_hard0 + result_hard1;
3102 if (result_hard0 >= result_hard1)
3103 avg += 0x400;
3104 avg /= 2;
3105 avg_frac = avg & 0xFF;
3106 avg_cycle = (avg >> 8) & 0x3;
3107
3108 if (avg_cycle == 0x3) {
3109 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_DEC, 0x1);
3110 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_ADD, 0x0);
3111 } else {
3112 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_DEC, 0x0);
3113 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_ADD, avg_cycle);
3114 }
3115 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_WRITE_PATH_LAT_FRAC, avg_frac);
3116 }
3117
3118 dbsc5_ddr_setval_all_ch_all_slice(dev, SC_PHY_WCK_CALC, 0x1);
3119}
3120
3121/**
3122 * dbsc5_wl_gt_training() - Re-run Write Leveling & Read Gate Training
3123 * @dev: DBSC5 device
3124 *
3125 * Set CA leveling OFF, read gate leveling ON, write gate leveling ON,
3126 * PI dram wck training ON. Perform PI_DFS configuration. Start PI
3127 * frequency training in manual mode. Perform training in high-frequency
3128 * mode. Check for Write leveling Error and Gate leveling Error. If an
3129 * error is identified, the resulting value is inverted and returned.
3130 * Clear the PI status register.
3131 */
3132static u32 dbsc5_wl_gt_training(struct udevice *dev)
3133{
3134 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3135 const int retry_max = 0x10000;
3136 u32 gt_training_ng = 0;
3137 u32 wr_training_ng = 0;
3138 u32 phytrainingok = 0;
3139 u32 complete_ng = 0;
3140 int retry, ret;
3141 u32 ch, reg;
3142
3143 dbsc5_ddr_setval_all_ch(dev, PI_CALVL_EN_F2, 0x0);
3144 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_EN_F2, 0x1);
3145
3146 dbsc5_ddr_setval_all_ch(dev, PI_DFS_ENTRY_SEQ_0, 0x181F0000);
3147 dbsc5_ddr_setval_all_ch(dev, PI_DFS_INITIALIZATION_SEQ_1, 0x0);
3148 dbsc5_ddr_setval_all_ch(dev, PI_TRAIN_ALL_FREQ_REQ, 0x1);
3149
3150 /* Freq Change High to High*/
3151 ret = dbsc5_clk_pll3_freq(dev);
3152 if (ret)
3153 return ret;
3154
3155 for (retry = 0; retry < retry_max; retry++) {
3156 r_foreach_vch(dev, ch)
3157 if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(0))
3158 phytrainingok |= BIT(ch);
3159
3160 if (phytrainingok == priv->ddr_phyvalid)
3161 break;
3162 }
3163
3164 /* Error Check */
3165 r_foreach_vch(dev, ch) {
3166 /* Wrlvl Error Check */
3167 /* PI_WRLVL_ERROR_BIT */
3168 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(3);
3169 /* SLICE0 wrlvl error */
3170 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_STATUS_OBS) & BIT(12);
3171 /* SLICE1 wrlvl error */
3172 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_STATUS_OBS) & BIT(12);
3173 /* SLICE0 wrlvl error */
3174 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_ERROR_OBS);
3175 /* SLICE1 wrlvl error */
3176 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_ERROR_OBS);
3177 if (reg) {
3178 wr_training_ng |= BIT(ch);
3179 printf("%s wl_gt_training_error:1\n", __func__);
3180 }
3181
3182 /* Gtlvl Error Check */
3183 /* PI_RDLVL_GATE_ERROR_BIT */
3184 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(2);
3185 /* SLICE0 delay setup error */
3186 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_GTLVL_STATUS_OBS) & (0x3 << 7);
3187 /* SLICE1 delay setup error */
3188 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_GTLVL_STATUS_OBS) & (0x3 << 7);
3189 if (reg) {
3190 gt_training_ng |= BIT(ch);
3191 printf("%s wl_gt_training_error:2\n", __func__);
3192 }
3193 }
3194
3195 complete_ng = (wr_training_ng | gt_training_ng);
3196 if (complete_ng)
3197 return ~complete_ng;
3198
3199 /* PI_INT_ACK assert */
3200 r_foreach_vch(dev, ch) {
3201 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
3202 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
3203 }
3204
3205 return phytrainingok;
3206}
3207
3208/**
3209 * dbsc5_pi_int_ack_0_assert() - Training handshake functions
3210 * @dev: DBSC5 device
3211 * @bit: Status bit to poll
3212 *
3213 * Wait for the status bit specified in the argument to become 1 until the
3214 * time limit. After checking status bits on all channels, clear the target
3215 * status bits and returns the result of the check as the return value.
3216 */
3217static u32 dbsc5_pi_int_ack_0_assert(struct udevice *dev, u32 bit)
3218{
3219 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3220 const int retry_max = 0x10000;
3221 u32 ch, phytrainingok = 0;
3222 int retry;
3223
3224 for (retry = 0; retry < retry_max; retry++) {
3225 r_foreach_vch(dev, ch)
3226 if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(bit))
3227 phytrainingok |= BIT(ch);
3228
3229 if (phytrainingok == priv->ddr_phyvalid)
3230 break;
3231 }
3232
3233 if (phytrainingok != priv->ddr_phyvalid)
3234 return phytrainingok;
3235
3236 r_foreach_vch(dev, ch)
3237 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, BIT(bit));
3238
3239 return phytrainingok;
3240}
3241
3242/**
3243 * dbsc5_write_dca() - Write DCA Training
3244 * @dev: DBSC5 device
3245 *
3246 * Get DCA Training CS0 Flip-0 training results for RANK0.
3247 * Get DCA Training CS1 Flip-0 training results for RANK0.
3248 * Calculate DRAMDCA settings from training results and write
3249 * them to registers. Set DRAM DCA in MR30. Ensure that the
3250 * training has been successfully completed. Clear CA status
3251 * to 0.
3252 */
3253static void dbsc5_write_dca(struct udevice *dev)
3254{
3255 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3256 const int retry_max = 0x10000;
3257 u32 phytrainingok = 0;
3258 u32 ch, reg;
3259 int retry;
3260
3261 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_DATA_DC_CAL_START, 0x1);
3262
3263 for (retry = 0; retry < retry_max; retry++) {
3264 r_foreach_vch(dev, ch) {
3265 reg = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_DATA_DC_CAL_START) |
3266 dbsc5_ddr_getval_slice(dev, ch, 1, PHY_DATA_DC_CAL_START);
3267 if (!reg)
3268 phytrainingok |= BIT(ch);
3269 }
3270
3271 if (phytrainingok == priv->ddr_phyvalid)
3272 break;
3273 }
3274}
3275
3276/**
3277 * dbsc5_dramdca_training() - DRAM DCA Training and Calculations
3278 * @dev: DBSC5 device
3279 *
3280 * Get DCA Training CS0 Flip-0 training results for RANK0.
3281 * Get DCA Training CS1 Flip-0 training results for RANK0.
3282 * Calculate DRAMDCA settings from training results and write
3283 * them to registers. Set DRAM DCA in MR30. Ensure that the
3284 * training has been successfully completed. Clear CA status
3285 * to 0.
3286 */
3287static u32 dbsc5_dramdca_training(struct udevice *dev)
3288{
3289 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3290 const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
3291 const u32 mr30_conv[16] = {
3292 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1,
3293 0x0, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
3294 };
3295 u32 dca_result_l_0[DRAM_CH_CNT][CS_CNT];
3296 u32 dca_result_u_0[DRAM_CH_CNT][CS_CNT];
3297 u32 dca_result_l_1[DRAM_CH_CNT][CS_CNT];
3298 u32 dca_result_u_1[DRAM_CH_CNT][CS_CNT];
3299 u32 ch, phytrainingok, reg;
3300 u32 tempu, templ;
3301
3302 /* Run DRAM DCA Training for Flip-0 */
3303 dbsc5_ddr_setval_all_ch(dev, PI_DCMLVL_CS_SW, rank);
3304
3305 /* DRAMDCA go */
3306 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_REQ, 0x1);
3307
3308 /* PI_INT_ACK assert */
3309 phytrainingok = dbsc5_pi_int_ack_0_assert(dev, 28);
3310 if (phytrainingok != priv->ddr_phyvalid)
3311 return phytrainingok;
3312
3313 /* Result for DRAMDCA flip-0 */
3314 r_foreach_vch(dev, ch) {
3315 reg = dbsc5_ddr_getval(dev, ch, PI_DARRAY3_20_CS0_F2);
3316 dca_result_u_0[ch][0] = mr30_conv[reg >> 4];
3317 dca_result_l_0[ch][0] = mr30_conv[reg & 0xF];
3318 if (!(rank & 0x2))
3319 continue;
3320
3321 reg = dbsc5_ddr_getval(dev, ch, PI_DARRAY3_20_CS1_F2);
3322 dca_result_u_0[ch][1] = mr30_conv[reg >> 4];
3323 dca_result_l_0[ch][1] = mr30_conv[reg & 0xF];
3324 }
3325
3326 /* Run DRAM DCA Training for Flip-1 */
3327 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_FLIP_MASK, 0x1);
3328 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_2, 0x0);
3329 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_3, 0x0);
3330 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_4, 0x0);
3331
3332 /* DRAMDCA go */
3333 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_REQ, 0x1);
3334
3335 /* PI_INT_ACK assert */
3336 phytrainingok = dbsc5_pi_int_ack_0_assert(dev, 28);
3337 if (phytrainingok != priv->ddr_phyvalid)
3338 return phytrainingok;
3339
3340 /* Result for DRAMDCA flip-1 */
3341 r_foreach_vch(dev, ch) {
3342 reg = dbsc5_ddr_getval(dev, ch, PI_DARRAY3_20_CS0_F2);
3343 dca_result_u_1[ch][0] = mr30_conv[reg >> 4];
3344 dca_result_l_1[ch][0] = mr30_conv[reg & 0xF];
3345 if (!(rank & 0x2))
3346 continue;
3347
3348 reg = dbsc5_ddr_getval(dev, ch, PI_DARRAY3_20_CS1_F2);
3349 dca_result_u_1[ch][1] = mr30_conv[reg >> 4];
3350 dca_result_l_1[ch][1] = mr30_conv[reg & 0xF];
3351 }
3352
3353 /* Calculate and set DRAMDCA value */
3354 r_foreach_vch(dev, ch) {
3355 /* CS0 */
3356 tempu = (dca_result_u_0[ch][0] + dca_result_u_1[ch][0]) / 2;
3357 templ = (dca_result_l_0[ch][0] + dca_result_l_1[ch][0]) / 2;
3358 reg = (mr30_conv[tempu] << 4) | mr30_conv[templ];
3359 dbsc5_ddr_setval(dev, ch, PI_DARRAY3_20_CS0_F2, reg);
3360 if (!(rank & 0x2))
3361 continue;
3362
3363 /* CS1 */
3364 tempu = (dca_result_u_0[ch][1] + dca_result_u_1[ch][1]) / 2;
3365 templ = (dca_result_l_0[ch][1] + dca_result_l_1[ch][1]) / 2;
3366 reg = (mr30_conv[tempu] << 4) | mr30_conv[templ];
3367 dbsc5_ddr_setval(dev, ch, PI_DARRAY3_20_CS1_F2, reg);
3368 }
3369
3370 /* Set DRAMDCA value in MR30 */
3371 dbsc5_ddr_setval_all_ch(dev, PI_SW_SEQ_0, 0x1A11E14);
3372 dbsc5_ddr_setval_all_ch(dev, PI_SW_SEQ_1, 0x1F0000);
3373 dbsc5_ddr_setval_all_ch(dev, PI_SEQ_DEC_SW_CS, rank);
3374 dbsc5_ddr_setval_all_ch(dev, PI_SW_SEQ_START, 0x1);
3375
3376 /* PI_INT_ACK assert */
3377 phytrainingok = dbsc5_pi_int_ack_0_assert(dev, 19);
3378 if (phytrainingok != priv->ddr_phyvalid)
3379 return phytrainingok;
3380
3381 dbsc5_ddr_setval_all_ch(dev, PI_SEQ_DEC_SW_CS, 0x0);
3382 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_FLIP_MASK, 0x2);
3383 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_2, 0x1101FC);
3384 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_3, 0x211A00);
3385 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_ACTIVE_SEQ_4, 0x51500);
3386
3387 return phytrainingok;
3388}
3389
3390/**
3391 * dbsc5_write_leveling() - Re-run Write Leveling
3392 * @dev: DBSC5 device
3393 *
3394 * CALVL training is set to OFF, WRDCM training is set to OFF, and DRAMDCA
3395 * training is set to OFF. Set the memory rank for the Write leveling target
3396 * and start leveling. Wait until leveling is complete.
3397 *
3398 * Check for Write leveling errors. If an error is confirmed to have occurred,
3399 * the result is returned as a return value. Clear the PI status bit.
3400 */
3401static u32 dbsc5_write_leveling(struct udevice *dev)
3402{
3403 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3404 const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
3405 const int retry_max = 0x10000;
3406 u32 wr_training_ng = 0;
3407 u32 phytrainingok = 0;
3408 u32 ch, reg;
3409 int retry;
3410
3411 dbsc5_ddr_setval_all_ch(dev, PI_CALVL_EN_F2, 0x0);
3412 dbsc5_ddr_setval_all_ch(dev, PI_WRDCM_LVL_EN_F2, 0x0);
3413 dbsc5_ddr_setval_all_ch(dev, PI_DRAMDCA_LVL_EN_F2, 0x0);
3414 dbsc5_ddr_setval_all_ch(dev, PI_WRLVL_CS_SW, rank);
3415 dbsc5_ddr_setval_all_ch(dev, PI_WRLVL_REQ, 0x1);
3416
3417 for (retry = 0; retry < retry_max; retry++) {
3418 r_foreach_vch(dev, ch)
3419 if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(29))
3420 phytrainingok |= BIT(ch);
3421
3422 if (phytrainingok == priv->ddr_phyvalid)
3423 break;
3424 }
3425
3426 /* Error check */
3427 r_foreach_vch(dev, ch) {
3428 /* Wrlvl Error Check */
3429 /* PI_WRLVL_ERROR_BIT */
3430 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(3);
3431 /* SLICE0 wrlvl error */
3432 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_STATUS_OBS) & BIT(12);
3433 /* SLICE1 wrlvl error */
3434 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_STATUS_OBS) & BIT(12);
3435 /* SLICE0 wrlvl error */
3436 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WRLVL_ERROR_OBS);
3437 /* SLICE1 wrlvl error */
3438 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WRLVL_ERROR_OBS);
3439 if (reg) {
3440 wr_training_ng |= BIT(ch);
3441 printf("%s write_leveling_error:1\n", __func__);
3442 }
3443 }
3444
3445 if (wr_training_ng)
3446 return ~wr_training_ng;
3447
3448 /* PI_INT_ACK assert */
3449 r_foreach_vch(dev, ch) {
3450 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
3451 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
3452 }
3453
3454 return phytrainingok;
3455}
3456
3457/**
3458 * dbsc5_manual_write_dca() - Manual Write DCA Training
3459 * @dev: DBSC5 device
3460 *
3461 * Write DCA training according to memory rank.
3462 */
3463static void dbsc5_manual_write_dca(struct udevice *dev)
3464{
3465 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3466 const u32 rank = priv->ch_have_this_cs[1] ? 0x2 : 0x1;
Marek Vasut021b08e2025-03-16 14:51:42 +01003467 u32 phy_slv_dly[DRAM_CH_CNT][CS_CNT][SLICE_CNT];
3468 u32 phy_slv_dly_avg[DRAM_CH_CNT][SLICE_CNT];
Marek Vasut1f7ba642024-12-12 14:34:30 +01003469 u32 slv_dly_min[DRAM_CH_CNT][SLICE_CNT];
3470 u32 slv_dly_max[DRAM_CH_CNT][SLICE_CNT];
Marek Vasut1f7ba642024-12-12 14:34:30 +01003471 u32 phy_dcc_code_min[DRAM_CH_CNT][SLICE_CNT];
3472 u32 phy_dcc_code_max[DRAM_CH_CNT][SLICE_CNT];
3473 u32 phy_dcc_code_mid;
3474 const int retry_max = 0x10000;
3475 const u8 ratio_min_div = 0xA;
3476 const u8 ratio_max_div = 0x2;
3477 const u8 ratio_min = 0x6;
3478 const u8 ratio_max = 0x3;
3479 u32 ch, cs, slice, tmp;
3480 u32 complete = 0;
3481 int i, retry;
3482
3483 r_foreach_vch(dev, ch) {
3484 for (slice = 0; slice < SLICE_CNT; slice++) {
3485 phy_dcc_code_min[ch][slice] = 0x7F;
3486 phy_dcc_code_max[ch][slice] = 0x0;
3487 }
3488 }
3489
3490 for (cs = 0; cs < rank; cs++) {
3491 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_INDEX, cs);
3492 r_foreach_vch(dev, ch) {
3493 for (slice = 0; slice < SLICE_CNT; slice++) {
Marek Vasut021b08e2025-03-16 14:51:42 +01003494 phy_slv_dly[ch][cs][slice] =
3495 dbsc5_ddr_getval_slice(dev, ch, slice,
3496 PHY_CLK_WRDQS_SLAVE_DELAY);
Marek Vasut1f7ba642024-12-12 14:34:30 +01003497 }
3498 }
3499 }
3500
3501 r_foreach_vch(dev, ch) {
3502 for (slice = 0; slice < SLICE_CNT; slice++) {
3503 if (rank == 0x2) {
Marek Vasut021b08e2025-03-16 14:51:42 +01003504 /* Calculate average between ranks */
3505 phy_slv_dly_avg[ch][slice] = (phy_slv_dly[ch][0][slice] +
3506 phy_slv_dly[ch][1][slice]) / 2;
Marek Vasut1f7ba642024-12-12 14:34:30 +01003507 } else {
Marek Vasut021b08e2025-03-16 14:51:42 +01003508 phy_slv_dly_avg[ch][slice] = phy_slv_dly[ch][0][slice];
Marek Vasut1f7ba642024-12-12 14:34:30 +01003509 }
Marek Vasut021b08e2025-03-16 14:51:42 +01003510 /* Determine the search range */
3511 slv_dly_min[ch][slice] = (phy_slv_dly_avg[ch][slice] & 0x07F) * ratio_min / ratio_min_div;
3512 slv_dly_max[ch][slice] = (phy_slv_dly_avg[ch][slice] & 0x07F) * ratio_max / ratio_max_div;
3513 if (slv_dly_max[ch][slice] > 0x7F)
3514 slv_dly_max[ch][slice] = 0x7F;
Marek Vasut1f7ba642024-12-12 14:34:30 +01003515 }
3516 }
3517
Marek Vasut021b08e2025-03-16 14:51:42 +01003518 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_SLV_DLY_CTRL_GATE_DISABLE, 0x1);
3519
Marek Vasut1f7ba642024-12-12 14:34:30 +01003520 for (i = 0; i <= 0x7F; i++) {
3521 r_foreach_vch(dev, ch) {
3522 for (slice = 0; slice < SLICE_CNT; slice++) {
3523 if (slv_dly_max[ch][slice] < (slv_dly_min[ch][slice] + i)) {
3524 complete |= BIT(ch) << (8 * slice);
3525 } else {
3526 /* CS0/1 same setting, Need masked write */
3527 dbsc5_ddr_setval_slice(dev, ch, slice,
3528 PHY_CLK_WRDQS_SLAVE_DELAY,
3529 slv_dly_min[ch][slice] + i);
3530 dbsc5_ddr_setval_slice(dev, ch, slice, SC_PHY_WCK_CALC, 0x1);
3531 dbsc5_ddr_setval(dev, ch, SC_PHY_MANUAL_UPDATE, 0x1);
3532 }
3533 }
3534 }
3535
3536 if (complete == (priv->ddr_phyvalid | (priv->ddr_phyvalid << 8)))
3537 break;
3538
3539 /* Execute write dca */
3540 r_foreach_vch(dev, ch)
3541 for (slice = 0; slice < SLICE_CNT; slice++)
3542 if (!(((complete >> (8 * slice)) >> ch) & 0x1))
3543 dbsc5_ddr_setval_slice(dev, ch, slice, PHY_DATA_DC_CAL_START, 0x1);
3544
3545 r_foreach_vch(dev, ch) {
3546 for (slice = 0; slice < SLICE_CNT; slice++) {
3547 if (!(((complete >> (8 * slice)) >> ch) & 0x1)) {
3548 for (retry = 0; retry < retry_max; retry++) {
3549 tmp = dbsc5_ddr_getval_slice(dev, ch, slice,
3550 PHY_DATA_DC_CAL_START);
3551 if (!tmp)
3552 break;
3553 }
3554 }
3555 }
3556 }
3557
3558 r_foreach_vch(dev, ch) {
3559 for (slice = 0; slice < SLICE_CNT; slice++) {
3560 if ((slv_dly_min[ch][slice] + i) > slv_dly_max[ch][slice])
3561 continue;
3562
3563 tmp = (dbsc5_ddr_getval_slice(dev, ch, slice, PHY_DATA_DC_DQS_CLK_ADJUST));
3564 if ((tmp >> 6) == 0x1)
3565 tmp = 0x0;
3566 else if ((tmp >> 6) == 0x2)
3567 tmp = 0x3F;
3568
3569 if (tmp < phy_dcc_code_min[ch][slice])
3570 phy_dcc_code_min[ch][slice] = tmp;
3571
3572 if (phy_dcc_code_max[ch][slice] < tmp)
3573 phy_dcc_code_max[ch][slice] = tmp;
3574 }
3575 }
3576 }
3577
3578 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_MULTICAST_EN, 0x0);
3579 for (cs = 0; cs < rank; cs++) {
3580 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_INDEX, cs);
3581 r_foreach_vch(dev, ch) {
3582 for (slice = 0; slice < SLICE_CNT; slice++) {
3583 dbsc5_ddr_setval_slice(dev, ch, slice,
3584 PHY_CLK_WRDQS_SLAVE_DELAY,
Marek Vasut021b08e2025-03-16 14:51:42 +01003585 phy_slv_dly[ch][cs][slice]);
Marek Vasut1f7ba642024-12-12 14:34:30 +01003586 dbsc5_ddr_setval_slice(dev, ch, slice,
3587 SC_PHY_WCK_CALC, 0x1);
3588 dbsc5_ddr_setval(dev, ch, SC_PHY_MANUAL_UPDATE, 0x1);
3589 }
3590 }
3591 }
Marek Vasut021b08e2025-03-16 14:51:42 +01003592
3593 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_SLV_DLY_CTRL_GATE_DISABLE, 0x0);
3594
Marek Vasut1f7ba642024-12-12 14:34:30 +01003595 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_MULTICAST_EN, 0x1);
3596
3597 r_foreach_vch(dev, ch) {
3598 for (slice = 0; slice < SLICE_CNT; slice++) {
3599 phy_dcc_code_mid = (phy_dcc_code_min[ch][slice] +
3600 phy_dcc_code_max[ch][slice]) / 2;
3601 dbsc5_ddr_setval_slice(dev, ch, slice,
3602 PHY_DATA_DC_DQS_CLK_ADJUST,
3603 phy_dcc_code_mid);
3604 }
3605 }
3606}
3607
3608/**
3609 * dbsc5_read_gate_training() - Re-run read gate training by PI
3610 * @dev: DBSC5 device
3611 *
3612 * Write leveling set to OFF, read gate leveling set to ON. Set memory rank
3613 * for leveling target, turn on read gate leveling. Wait for leveling to be
3614 * completed until the time limit. Check for errors during gate leveling.
3615 *
3616 * If an error is confirmed to have occurred, the result is returned as a
3617 * return value. Clear the PI status register.
3618 */
3619static u32 dbsc5_read_gate_training(struct udevice *dev)
3620{
3621 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3622 const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
3623 const int retry_max = 0x10000;
3624 u32 gt_training_ng = 0;
3625 u32 phytrainingok = 0;
3626 u32 ch, reg;
3627 int retry;
3628
3629 dbsc5_ddr_setval_all_ch(dev, PI_WRLVL_EN_F2, 0x0);
3630 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_EN_F2, 0x1);
3631 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_CS_SW, rank);
3632 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_REQ, 0x1);
3633
3634 for (retry = 0; retry < retry_max; retry++) {
3635 r_foreach_vch(dev, ch)
3636 if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(24))
3637 phytrainingok |= BIT(ch);
3638
3639 if (phytrainingok == priv->ddr_phyvalid)
3640 break;
3641 }
3642
3643 /* Error Check */
3644 r_foreach_vch(dev, ch) {
3645 /* Gtlvl Error Check */
3646 /* PI_RDLVL_GATE_ERROR_BIT */
3647 reg = (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(2));
3648 /* SLICE0 delay setup error */
3649 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_GTLVL_STATUS_OBS) & (0x3 << 7);
3650 /* SLICE1 delay setup error */
3651 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_GTLVL_STATUS_OBS) & (0x3 << 7);
3652 if (reg) {
3653 gt_training_ng |= BIT(ch);
3654 printf("%s read_gate_training_error\n", __func__);
3655 }
3656 }
3657
3658 if (gt_training_ng)
3659 return ~gt_training_ng;
3660
3661 /* PI_INT_ACK assert */
3662 r_foreach_vch(dev, ch) {
3663 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
3664 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
3665 }
3666
3667 return phytrainingok;
3668}
3669
3670/**
3671 * dbsc5_read_vref_training() - Read Data Training with VREF Training
3672 * @dev: DBSC5 device
3673 *
3674 * Set reading leveling to ON and Vref leveling of reading to OFF.
3675 * Set Vref reading training to OFF. Get start value, end value and
3676 * number of steps for Vref training. Determine the optimal VREFSEL
3677 * value while increasing the Vref training setpoint by the starting
3678 * value+step value.
3679 */
3680static u32 dbsc5_read_vref_training(struct udevice *dev)
3681{
3682 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3683 const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
3684 u32 best_dvw_min_byte0, best_dvw_min_byte1;
3685 u32 dvw_min_byte0_table[DRAM_CH_CNT][128];
3686 u32 dvw_min_byte1_table[DRAM_CH_CNT][128];
3687 u32 dvw_min_byte0[DRAM_CH_CNT] = { 0 };
3688 u32 dvw_min_byte1[DRAM_CH_CNT] = { 0 };
3689 u32 best_lower_vref, best_upper_vref;
3690 u32 best_vref_byte0, best_vref_byte1;
3691 u32 vref_start, vref_stop, vref_step;
3692 u32 best_vref_byte0_index = 0;
3693 u32 best_vref_byte1_index = 0;
3694 const int retry_max = 0x10000;
3695 u32 win_byte0, win_byte1;
3696 u32 phytrainingok = 0;
3697 u32 vref_stop_index;
3698 u32 temple, tempte;
3699 u32 best_thrshld;
3700 u32 vref_outlier;
3701 u32 outlier_cnt;
3702 u32 curr_rank;
3703 int i, retry;
3704 u32 obs_sel;
3705 u32 ch, reg;
3706
3707 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_EN_F2, 0x3);
3708 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_VREF_EN_F0, 0x0);
3709 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_VREF_EN_F1, 0x0);
3710 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_VREF_EN_F2, 0x0);
3711 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_VREF_TRAINING_CTRL, 0x0);
3712
3713 /* ch0 vref_point */
3714 vref_start = dbsc5_ddr_getval(dev, 0, PHY_VREF_INITIAL_START_POINT);
3715 vref_stop = dbsc5_ddr_getval(dev, 0, PHY_VREF_INITIAL_STOP_POINT);
3716 vref_step = dbsc5_ddr_getval(dev, 0, PHY_VREF_INITIAL_STEPSIZE);
3717 vref_stop_index = (vref_stop - vref_start) / vref_step;
3718
3719 if (vref_stop_index > 0x80)
3720 return 0;
3721
3722 for (i = 0; i <= vref_stop_index; i++) {
3723 r_foreach_vch(dev, ch) {
3724 reg = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_PAD_VREF_CTRL_DQ);
3725 reg &= 0xF << 10;
3726 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_PAD_VREF_CTRL_DQ,
3727 reg | BIT(9) | (vref_start + (vref_step * i)));
3728 reg = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_PAD_VREF_CTRL_DQ);
3729 reg &= 0xF << 10;
3730 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_PAD_VREF_CTRL_DQ,
3731 reg | BIT(9) | (vref_start + (vref_step * i)));
3732 }
3733
3734 for (curr_rank = 0; curr_rank < rank; curr_rank++) {
3735 /* All ch Read Training Start */
3736 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_CS_SW, BIT(curr_rank));
3737 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_REQ, 0x1);
3738
3739 phytrainingok = 0;
3740 for (retry = 0; retry < retry_max; retry++) {
3741 r_foreach_vch(dev, ch)
3742 if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(25))
3743 phytrainingok |= BIT(ch);
3744
3745 if (phytrainingok == priv->ddr_phyvalid)
3746 break;
3747 }
3748
3749 /* Read Training End */
3750 dbsc5_ddr_setval_all_ch(dev, PI_INT_ACK_0, BIT(25));
3751
3752 r_foreach_vch(dev, ch) {
3753 /* minimum Data Valid Window for each VREF */
3754 dvw_min_byte0[ch] = 0xFFFFFFFF;
3755 dvw_min_byte1[ch] = 0xFFFFFFFF;
3756 for (obs_sel = 0x0; obs_sel < 0x19; obs_sel++) {
3757 if (!((obs_sel < 0x11) || (obs_sel == 0x18)))
3758 continue;
3759
3760 dbsc5_ddr_setval_slice(dev, ch, 0,
3761 PHY_RDLVL_RDDQS_DQ_OBS_SELECT,
3762 obs_sel);
3763 dbsc5_ddr_setval_slice(dev, ch, 1,
3764 PHY_RDLVL_RDDQS_DQ_OBS_SELECT,
3765 obs_sel);
3766
3767 temple = dbsc5_ddr_getval_slice(dev, ch, 0,
3768 PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS);
3769 tempte = dbsc5_ddr_getval_slice(dev, ch, 0,
3770 PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS);
3771 if (tempte > temple)
3772 win_byte0 = tempte - temple;
3773 else
3774 win_byte0 = 0;
3775
3776 temple = dbsc5_ddr_getval_slice(dev, ch, 1,
3777 PHY_RDLVL_RDDQS_DQ_LE_DLY_OBS);
3778 tempte = dbsc5_ddr_getval_slice(dev, ch, 1,
3779 PHY_RDLVL_RDDQS_DQ_TE_DLY_OBS);
3780 if (tempte > temple)
3781 win_byte1 = tempte - temple;
3782 else
3783 win_byte1 = 0;
3784
3785 if (dvw_min_byte0[ch] > win_byte0)
3786 dvw_min_byte0[ch] = win_byte0;
3787
3788 if (dvw_min_byte1[ch] > win_byte1)
3789 dvw_min_byte1[ch] = win_byte1;
3790 }
3791 }
3792 }
3793
3794 r_foreach_vch(dev, ch) {
3795 dvw_min_byte0_table[ch][i] = dvw_min_byte0[ch];
3796 dvw_min_byte1_table[ch][i] = dvw_min_byte1[ch];
3797 }
3798 }
3799
3800 r_foreach_vch(dev, ch) {
3801 /* Search best VREF byte0 */
3802 best_vref_byte0 = vref_start;
3803 best_vref_byte0_index = 0;
3804 best_dvw_min_byte0 = dvw_min_byte0_table[ch][0];
3805
3806 for (i = 0; i <= vref_stop_index; i++) {
3807 if (best_dvw_min_byte0 >= dvw_min_byte0_table[ch][i])
3808 continue;
3809
3810 best_vref_byte0 = vref_start + (vref_step * i);
3811 best_vref_byte0_index = i;
3812 best_dvw_min_byte0 = dvw_min_byte0_table[ch][i];
3813 }
3814
3815 /* Search best_lower VREF byte0 */
3816 reg = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_RDLVL_DLY_STEP);
3817 if (reg == 0)
3818 reg = 1;
3819 best_thrshld = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_RDLVL_BEST_THRSHLD) * reg;
3820
3821 vref_outlier = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_RDLVL_VREF_OUTLIER);
3822 best_lower_vref = best_vref_byte0;
3823 outlier_cnt = vref_outlier;
3824 for (i = best_vref_byte0_index; i >= 0; i--) {
3825 if (dvw_min_byte0_table[ch][i] <= 0)
3826 break;
3827
3828 if (dvw_min_byte0_table[ch][i] >= (best_dvw_min_byte0 - best_thrshld)) {
3829 best_lower_vref = vref_start + (vref_step * i);
3830 } else {
3831 if (outlier_cnt > 0)
3832 outlier_cnt--;
3833 else
3834 break;
3835 }
3836
3837 if (i == 0)
3838 break;
3839 }
3840
3841 /* Search best_upper VREF byte0 */
3842 vref_outlier = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_RDLVL_VREF_OUTLIER);
3843 best_upper_vref = best_vref_byte0;
3844 outlier_cnt = vref_outlier;
3845 for (i = best_vref_byte0_index; i <= vref_stop_index; i++) {
3846 if (dvw_min_byte0_table[ch][i] <= 0)
3847 break;
3848
3849 if (dvw_min_byte0_table[ch][i] >= (best_dvw_min_byte0 - best_thrshld)) {
3850 best_upper_vref = vref_start + (vref_step * i);
3851 } else {
3852 if (outlier_cnt > 0)
3853 outlier_cnt--;
3854 else
3855 break;
3856 }
3857 }
3858
3859 /* Calculate center of best vref range byte0 */
3860 best_vref_byte0 = (best_lower_vref + best_upper_vref) / 2;
3861
3862 /* Search best VREF byte1 */
3863 best_vref_byte1 = vref_start;
3864 best_vref_byte1_index = 0;
3865 best_dvw_min_byte1 = dvw_min_byte1_table[ch][0];
3866 for (i = 0; i <= vref_stop_index; i++) {
3867 if (best_dvw_min_byte1 >= dvw_min_byte1_table[ch][i])
3868 continue;
3869
3870 best_vref_byte1 = vref_start + (vref_step * i);
3871 best_vref_byte1_index = i;
3872 best_dvw_min_byte1 = dvw_min_byte1_table[ch][i];
3873 }
3874
3875 /* Search best_lower VREF byte1 */
3876 reg = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_RDLVL_DLY_STEP);
3877 if (reg == 0)
3878 reg = 1;
3879 best_thrshld = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_RDLVL_BEST_THRSHLD) * reg;
3880
3881 vref_outlier = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_RDLVL_VREF_OUTLIER);
3882 best_lower_vref = best_vref_byte1;
3883 outlier_cnt = vref_outlier;
3884 for (i = best_vref_byte1_index; i >= 0; i--) {
3885 if (dvw_min_byte1_table[ch][i] <= 0)
3886 break;
3887
3888 if (dvw_min_byte1_table[ch][i] >= (best_dvw_min_byte1 - best_thrshld)) {
3889 best_lower_vref = vref_start + (vref_step * i);
3890 } else {
3891 if (outlier_cnt > 0)
3892 outlier_cnt--;
3893 else
3894 break;
3895 }
3896
3897 if (i == 0)
3898 break;
3899 }
3900
3901 /* Search best_upper VREF byte1 */
3902 vref_outlier = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_RDLVL_VREF_OUTLIER);
3903 best_upper_vref = best_vref_byte1;
3904 outlier_cnt = vref_outlier;
3905 for (i = best_vref_byte1_index; i <= vref_stop_index; i++) {
3906 if (dvw_min_byte1_table[ch][i] <= 0)
3907 break;
3908
3909 if (dvw_min_byte1_table[ch][i] >= (best_dvw_min_byte1 - best_thrshld)) {
3910 best_upper_vref = vref_start + (vref_step * i);
3911 } else {
3912 if (outlier_cnt > 0)
3913 outlier_cnt--;
3914 else
3915 break;
3916 }
3917 }
3918
3919 /* Calculate center of best vref range byte1 */
3920 best_vref_byte1 = (best_lower_vref + best_upper_vref) / 2;
3921
3922 reg = dbsc5_ddr_getval_slice(dev, ch, 0, PHY_PAD_VREF_CTRL_DQ);
3923 reg &= 0xF << 10;
3924 dbsc5_ddr_setval_slice(dev, ch, 0, PHY_PAD_VREF_CTRL_DQ,
3925 reg | BIT(9) | best_vref_byte0);
3926 reg = dbsc5_ddr_getval_slice(dev, ch, 1, PHY_PAD_VREF_CTRL_DQ);
3927 reg &= 0xF << 10;
3928 dbsc5_ddr_setval_slice(dev, ch, 1, PHY_PAD_VREF_CTRL_DQ,
3929 reg | BIT(9) | best_vref_byte1);
3930 }
3931
3932 return phytrainingok;
3933}
3934
3935/**
3936 * dbsc5_read_write_training() - Read Data & RDDQ Training with best VREF & Write DQ VREF Training
3937 * @dev: DBSC5 device
3938 *
3939 * Set read DQS/RDQS slave delay setting to 0. Write leveling set to OFF,
3940 * read gate leveling set to OFF. Turn on read and write leveling. Start
3941 * frequency training. Training in high-frequency mode. Wait until training
3942 * is complete. Check for errors in write dq leveling and read leveling.
3943
3944 * If an error is confirmed to have occurred, return the inverted result
3945 * value. Clear the PI status register.
3946 */
3947static u32 dbsc5_read_write_training(struct udevice *dev)
3948{
3949 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
3950 const int retry_max = 0x10000;
3951 u32 wdq_training_ng = 0;
3952 u32 rd_training_ng = 0;
3953 u32 phytrainingok = 0;
3954 u32 complete_ng = 0;
3955 int retry, ret;
3956 u32 ch, reg;
3957
3958 /* RDDQ_SLAVE_DELAY Set 0x0050 -> 0x0000 */
3959 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ0_SLAVE_DELAY, 0x0);
3960 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ1_SLAVE_DELAY, 0x0);
3961 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ2_SLAVE_DELAY, 0x0);
3962 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ3_SLAVE_DELAY, 0x0);
3963 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ4_SLAVE_DELAY, 0x0);
3964 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ5_SLAVE_DELAY, 0x0);
3965 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ6_SLAVE_DELAY, 0x0);
3966 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDQ7_SLAVE_DELAY, 0x0);
3967 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_RDDM_SLAVE_DELAY, 0x0);
3968
3969 dbsc5_ddr_setval_all_ch(dev, PI_WRLVL_EN_F2, 0x0);
3970 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_GATE_EN_F2, 0x0);
3971 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_EN_F2, 0x3);
3972 dbsc5_ddr_setval_all_ch(dev, PI_WDQLVL_EN_F2, 0x3);
3973
3974 dbsc5_ddr_setval_all_ch(dev, PI_TRAIN_ALL_FREQ_REQ, 0x1);
3975
3976 /* Freq Change High to High*/
3977 ret = dbsc5_clk_pll3_freq(dev);
3978 if (ret)
3979 return ret;
3980
3981 for (retry = 0; retry < retry_max; retry++) {
3982 r_foreach_vch(dev, ch)
3983 if (dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(0))
3984 phytrainingok |= BIT(ch);
3985
3986 if (phytrainingok == priv->ddr_phyvalid)
3987 break;
3988 }
3989
3990 /* Error Check */
3991 r_foreach_vch(dev, ch) {
3992 /* Rdlvl Error Check */
3993 /* PI_RDLVL_ERROR_BIT */
3994 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(1);
3995 if (reg) {
3996 rd_training_ng |= BIT(ch);
3997 printf("%s read_write_training_error:1\n", __func__);
3998 }
3999
4000 /* Wdqlvl Error Check */
4001 /* PI_WDQLVL_ERROR_BIT */
4002 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(5);
4003 /* SLICE0 wdqlvl_fail_dqZ */
4004 reg |= dbsc5_ddr_getval_slice(dev, ch, 0, PHY_WDQLVL_STATUS_OBS) & (0x1FF << 18);
4005 /* SLICE1 wdqlvl_fail_dqZ */
4006 reg |= dbsc5_ddr_getval_slice(dev, ch, 1, PHY_WDQLVL_STATUS_OBS) & (0x1FF << 18);
4007 if (reg) {
4008 wdq_training_ng |= BIT(ch);
4009 printf("%s read_write_training_error:2\n", __func__);
4010 }
4011 }
4012
4013 complete_ng = wdq_training_ng | rd_training_ng;
4014 if (complete_ng)
4015 return ~complete_ng;
4016
4017 /* PI_INT_ACK assert */
4018 r_foreach_vch(dev, ch) {
4019 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_0, 0xFFFFFFFF);
4020 dbsc5_ddr_setval(dev, ch, PI_INT_ACK_1, 0x7);
4021 }
4022
4023 return phytrainingok;
4024}
4025
4026/**
4027 * dbsc5_read_training() - Correct RDDQ Training result & Re-Run Read Data Training
4028 * @dev: DBSC5 device
4029 *
4030 * Set the Read DQ correction value and its upper limit from the board
4031 * settings. Check DDR memory ranks. Add the offset value to the current
4032 * Read DQ value and write it to the register. Write the setting value
4033 * to PI_RDLVL_TRAIN_SEQ_x. Start the Read training. PI_INT_ACK assert.
4034 * Execute the Rdlvl Error Check. Confirm that training has been successfully
4035 * completed. Return the result of the confirmation as the return value.
4036 */
4037static u32 dbsc5_read_training(struct udevice *dev)
4038{
4039 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
4040 const u32 rank = priv->ch_have_this_cs[1] ? 0x3 : 0x1;
4041 const u32 rddq_delay_offset_ps = 0x19;
4042 const u32 rddq_delay_max_ps = 0x67;
4043 const u32 rddq_delay_addr[] = {
4044 PHY_RDDQ0_SLAVE_DELAY, PHY_RDDQ1_SLAVE_DELAY, PHY_RDDQ2_SLAVE_DELAY,
4045 PHY_RDDQ3_SLAVE_DELAY, PHY_RDDQ4_SLAVE_DELAY, PHY_RDDQ5_SLAVE_DELAY,
4046 PHY_RDDQ6_SLAVE_DELAY, PHY_RDDQ7_SLAVE_DELAY, PHY_RDDM_SLAVE_DELAY
4047 };
4048 const u32 rddq_delay_offset = rddq_delay_offset_ps * priv->ddr_mbps * 256 /
4049 (priv->ddr_mbpsdiv * 2 * 1000000);
4050 const u32 rddq_delay_max = rddq_delay_max_ps * priv->ddr_mbps * 256 /
4051 (priv->ddr_mbpsdiv * 2 * 1000000);
4052 u32 rd_training_ng = 0;
4053 u32 ch, reg, slice;
4054 u32 phytrainingok;
4055 int i;
4056
4057 r_foreach_vch(dev, ch) {
4058 for (slice = 0; slice < SLICE_CNT; slice++) {
4059 for (i = 0; i < 9; i++) {
4060 reg = dbsc5_ddr_getval_slice(dev, ch, slice,
4061 rddq_delay_addr[i]) +
4062 rddq_delay_offset;
4063 if (reg > rddq_delay_max)
4064 reg = rddq_delay_max;
4065 dbsc5_ddr_setval_slice(dev, ch, slice, rddq_delay_addr[i], reg);
4066 }
4067 }
4068 }
4069
4070 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_1, 0x89080);
4071 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_2, 0x811C0);
4072 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_3, 0x40811C0);
4073 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_4, 0x2000000);
4074 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_TRAIN_SEQ_5, 0x0);
4075 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_CS_SW, rank);
4076
4077 /* Read training go */
4078 dbsc5_ddr_setval_all_ch(dev, PI_RDLVL_REQ, 0x1);
4079
4080 /* PI_INT_ACK assert */
4081 phytrainingok = dbsc5_pi_int_ack_0_assert(dev, 25);
4082 if (phytrainingok != priv->ddr_phyvalid)
4083 return phytrainingok;
4084
4085 /* Error Check */
4086 r_foreach_vch(dev, ch) {
4087 /* Rdlvl Error Check */
4088 /* PI_RDLVL_ERROR_BIT */
4089 reg = dbsc5_ddr_getval(dev, ch, PI_INT_STATUS) & BIT(1);
4090 if (reg) {
4091 rd_training_ng |= BIT(ch);
4092 printf("%s read_training_error\n", __func__);
4093 }
4094 }
4095
4096 if (rd_training_ng)
4097 return ~rd_training_ng;
4098
4099 return phytrainingok;
4100}
4101
4102/**
Marek Vasut13653192025-03-25 23:43:29 +01004103 * dbsc5_ddr_register_mr28_set() - DDR mode register MR28 set
Marek Vasut1f7ba642024-12-12 14:34:30 +01004104 * @dev: DBSC5 device
4105 *
4106 * Set the mode register 28 of the SDRAM.
4107 * ZQ Mode: Command-Based ZQ Calibration
4108 * ZQ interval: Background Cal Interval < 64ms
4109 */
Marek Vasut13653192025-03-25 23:43:29 +01004110static void dbsc5_ddr_register_mr28_set(struct udevice *dev)
Marek Vasut1f7ba642024-12-12 14:34:30 +01004111{
Marek Vasute68e9152025-03-25 23:43:31 +01004112 dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_MRW,
4113 DBSC_DBCMD_CMD_CHANNEL_ALL,
4114 DBSC_DBCMD_CMD_RANK_ALL, (28 << 8) | 0x24);
Marek Vasut1f7ba642024-12-12 14:34:30 +01004115}
4116
4117/**
Marek Vasut13653192025-03-25 23:43:29 +01004118 * dbsc5_ddr_register_mr27_mr57_read() - DDR mode register MR27/MR57 read
Marek Vasut1f7ba642024-12-12 14:34:30 +01004119 * @dev: DBSC5 device
4120 *
4121 * Set the mode register 27 and 57 of the SDRAM.
4122 */
Marek Vasut13653192025-03-25 23:43:29 +01004123static void dbsc5_ddr_register_mr27_mr57_read(struct udevice *dev)
Marek Vasut1f7ba642024-12-12 14:34:30 +01004124{
4125 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
4126
4127 if (!priv->dbsc5_board_config->bdcfg_rfm_chk)
4128 return;
4129
4130 /* MR27 rank0 */
Marek Vasute68e9152025-03-25 23:43:31 +01004131 dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_MRR,
4132 DBSC_DBCMD_CMD_CHANNEL_ALL, 0, 27 << 8);
Marek Vasut1f7ba642024-12-12 14:34:30 +01004133 /* MR57 rank0 */
Marek Vasute68e9152025-03-25 23:43:31 +01004134 dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_MRR,
4135 DBSC_DBCMD_CMD_CHANNEL_ALL, 0, 57 << 8);
Marek Vasut1f7ba642024-12-12 14:34:30 +01004136
4137 if (!priv->ch_have_this_cs[1])
4138 return;
4139
4140 /* MR27 rank1 */
Marek Vasute68e9152025-03-25 23:43:31 +01004141 dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_MRR,
4142 DBSC_DBCMD_CMD_CHANNEL_ALL, 1, 27 << 8);
Marek Vasut1f7ba642024-12-12 14:34:30 +01004143 /* MR57 rank1 */
Marek Vasute68e9152025-03-25 23:43:31 +01004144 dbsc5_send_dbcmd2(dev, DBSC_DBCMD_CMD_OPCODE_MRR,
4145 DBSC_DBCMD_CMD_CHANNEL_ALL, 1, 57 << 8);
Marek Vasut1f7ba642024-12-12 14:34:30 +01004146}
4147
4148/**
4149 * dbsc5_init_ddr() - Initialize DDR
4150 * @dev: DBSC5 device
4151 *
4152 * Status monitor and perform reset and software reset for DDR.
4153 * Disable DDRPHY software reset. Unprotect the DDRPHY register.
4154 * Perform pre-setting of DBSC registers. Configure the ddrphy
4155 * registers. Process ddr backup. Set DBSC registers.
4156 *
4157 * Initialize DFI and perform PI training. Setup DDR mode registers
4158 * pre-traning. Adjust number of write leveling cycles. Perform PI
4159 * training in manual mode. Perform DRAM DCA training. Perform write
4160 * leveling. Execute phydca training. Execute read gate training.
4161 *
4162 * Perform Vref training on read gate. Read DQ Write DQ Execute.
4163 * Frequency selection change (F1->F2). Disable the FREQ_SEL_MULTICAST &
4164 * PER_CS_TRAINING_MULTICAST. Start setting DDR mode registers. Set DBSC
4165 * registers after training is completed. Set write protection for PHY
4166 * registers.
4167 */
4168static u32 dbsc5_init_ddr(struct udevice *dev)
4169{
4170 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
4171 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
4172 u32 phytrainingok;
4173 u32 ch, val;
4174 int ret;
4175
4176 /* PLL3 initialization setting */
4177 /* Reset Status Monitor clear */
4178 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FSRCHKCLRR4, 0x600);
4179 /* Reset Status Monitor set */
4180 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FSRCHKSETR4, 0x600);
4181 /* ddrphy soft reset assert */
4182 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_SRCR4, readl(priv->cpg_regs + CPG_SRCR4) | 0x600);
4183 /* Wait reset FB */
4184 ret = readl_poll_timeout(priv->cpg_regs + CPG_FSRCHKRA4, val, ((val & 0x600) == 0), 1000000);
4185 if (ret < 0) {
4186 printf("%s CPG_FSRCHKRA4 Wait reset FB timeout\n", __func__);
4187 hang();
4188 }
4189 /* Reset Status Monitor clear */
4190 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_FSRCHKCLRR4, 0x600);
4191
4192 /* Initialize PLL3 setting */
4193 dbsc5_clk_pll3_control(dev, PLL3_HIGH_FREQUENCY_MODE_LOAD_REGISTER);
4194
4195 /* DDRPHY soft reset negate */
4196 dbsc5_clk_cpg_write_32(dev, priv->cpg_regs + CPG_SRSTCLR4, 0x600);
4197 ret = readl_poll_timeout(priv->cpg_regs + CPG_SRCR4, val, ((val & 0x600) == 0), 1000000);
4198 if (ret < 0) {
4199 printf("%s CPG_SRCR4 DDRPHY soft reset negate timeout\n", __func__);
4200 hang();
4201 }
4202
4203 /* Unlock PHY */
4204 /* Unlock DDRPHY register */
4205 r_foreach_vch(dev, ch)
4206 writel(0xA55A, regs_dbsc_d + DBSC_DBPDLK(ch));
4207
4208 /* DBSC register pre-setting */
4209 dbsc5_dbsc_regset_pre(dev);
4210
4211 /* Load DDRPHY registers */
4212 dbsc5_ddrtbl_calc(priv);
4213 dbsc5_ddrtbl_load(dev);
4214
4215 /* Configure ddrphy registers */
4216 dbsc5_ddr_config(dev);
4217
4218 /* DDR backupmode end */
4219
4220 /* DBSC register set */
4221 dbsc5_dbsc_regset(dev);
4222
4223 /* Frequency selection change (F1->F2) */
Marek Vasutf1bb2a92025-03-25 23:43:30 +01004224 dbsc5_ddr_setval_all_ch(dev, PHY_FREQ_SEL_INDEX, 0x1);
4225 dbsc5_ddr_setval_all_ch(dev, PHY_FREQ_SEL_MULTICAST_EN, 0x0);
Marek Vasut1f7ba642024-12-12 14:34:30 +01004226
4227 /* dfi_init_start (start ddrphy) & execute pi_training */
4228 phytrainingok = dbsc5_pi_training(dev);
4229 if (priv->ddr_phyvalid != phytrainingok) {
4230 printf("%s init_ddr_error:1\n", __func__);
4231 return phytrainingok;
4232 }
4233
4234 /* Write leveling cycle adjust */
4235 dbsc5_write_leveling_adjust(dev);
4236
4237 /* Execute write leveling & read gate training */
4238 phytrainingok = dbsc5_wl_gt_training(dev);
4239 if (priv->ddr_phyvalid != phytrainingok) {
4240 printf("%s init_ddr_error:2\n", __func__);
4241 return phytrainingok;
4242 }
4243
4244 /* Execute write dca training */
4245 dbsc5_write_dca(dev);
4246
4247 /* Execute dram dca training */
4248 phytrainingok = dbsc5_dramdca_training(dev);
4249
4250 if (priv->ddr_phyvalid != phytrainingok) {
4251 printf("%s init_ddr_error:3\n", __func__);
4252 return phytrainingok;
4253 }
4254
4255 /* Execute write leveling */
4256 phytrainingok = dbsc5_write_leveling(dev);
4257
4258 if (priv->ddr_phyvalid != phytrainingok) {
4259 printf("%s init_ddr_error:4\n", __func__);
4260 return phytrainingok;
4261 }
4262
4263 /* Execute manual write dca training */
4264 dbsc5_manual_write_dca(dev);
4265
4266 /* Execute read gate training */
4267 phytrainingok = dbsc5_read_gate_training(dev);
4268
4269 if (priv->ddr_phyvalid != phytrainingok) {
4270 printf("%s init_ddr_error:5\n", __func__);
4271 return phytrainingok;
4272 }
4273
4274 /* Execute read vref training */
4275 phytrainingok = dbsc5_read_vref_training(dev);
4276
4277 if (priv->ddr_phyvalid != phytrainingok) {
4278 printf("%s init_ddr_error:6\n", __func__);
4279 return phytrainingok;
4280 }
4281
4282 /* Execute read dq & write dq training with best vref */
4283 phytrainingok = dbsc5_read_write_training(dev);
4284 if (priv->ddr_phyvalid != phytrainingok) {
4285 printf("%s init_ddr_error:7\n", __func__);
4286 return phytrainingok;
4287 }
4288
4289 /* correct rddq training result & Execute read dq training */
4290 phytrainingok = dbsc5_read_training(dev);
4291
4292 if (priv->ddr_phyvalid != phytrainingok) {
4293 printf("%s init_ddr_error:8\n", __func__);
4294 return phytrainingok;
4295 }
4296
4297 /* PER_CS_TRAINING_MULTICAST SET (disable) */
4298 dbsc5_ddr_setval_all_ch_all_slice(dev, PHY_PER_CS_TRAINING_MULTICAST_EN, 0x0);
4299
4300 /* setup DDR mode registers */
4301 /* MRS */
Marek Vasut13653192025-03-25 23:43:29 +01004302 dbsc5_ddr_register_mr28_set(dev);
Marek Vasut1f7ba642024-12-12 14:34:30 +01004303
4304 /* MRR */
Marek Vasut13653192025-03-25 23:43:29 +01004305 dbsc5_ddr_register_mr27_mr57_read(dev);
Marek Vasut1f7ba642024-12-12 14:34:30 +01004306
4307 /* training complete, setup DBSC */
4308 dbsc5_dbsc_regset_post(dev);
4309
4310 /* Lock PHY */
4311 /* Lock DDRPHY register */
4312 r_foreach_vch(dev, ch)
4313 writel(0x0, regs_dbsc_d + DBSC_DBPDLK(ch));
4314
4315 return phytrainingok;
4316}
4317
4318/**
4319 * dbsc5_get_board_data() - Obtain board specific DRAM configuration
4320 *
4321 * Return board specific DRAM configuration structure pointer.
4322 */
4323__weak const struct renesas_dbsc5_board_config *dbsc5_get_board_data(void)
4324{
4325 return &renesas_v4h_dbsc5_board_config;
4326}
4327
4328/**
4329 * renesas_dbsc5_dram_probe() - DDR Initialize entry
4330 * @dev: DBSC5 device
4331 *
4332 * Remove write protection on DBSC register. Read DDR configuration
4333 * information from driver data. Calculate board clock frequency and
4334 * operating frequency from DDR configuration information. Call the
4335 * main function of DDR initialization. Perform DBSC write protection
4336 * after initialization is complete.
4337 */
4338static int renesas_dbsc5_dram_probe(struct udevice *dev)
4339{
4340#define RST_MODEMR0 0x0
4341#define RST_MODEMR1 0x4
Marek Vasut884e8142025-03-16 14:51:43 +01004342#define OTP_MONITOR17 0x1144
Marek Vasut1f7ba642024-12-12 14:34:30 +01004343 struct renesas_dbsc5_data *data = (struct renesas_dbsc5_data *)dev_get_driver_data(dev);
4344 ofnode cnode = ofnode_by_compatible(ofnode_null(), data->clock_node);
4345 ofnode rnode = ofnode_by_compatible(ofnode_null(), data->reset_node);
Marek Vasut884e8142025-03-16 14:51:43 +01004346 ofnode onode = ofnode_by_compatible(ofnode_null(), data->otp_node);
Marek Vasut1f7ba642024-12-12 14:34:30 +01004347 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
4348 void __iomem *regs_dbsc_a = priv->regs + DBSC5_DBSC_A_OFFSET;
4349 void __iomem *regs_dbsc_d = priv->regs + DBSC5_DBSC_D_OFFSET;
4350 phys_addr_t rregs = ofnode_get_addr(rnode);
4351 const u32 modemr0 = readl(rregs + RST_MODEMR0);
4352 const u32 modemr1 = readl(rregs + RST_MODEMR1);
Marek Vasut884e8142025-03-16 14:51:43 +01004353 phys_addr_t oregs = ofnode_get_addr(onode);
4354 const u32 otpmon17 = readl(oregs + OTP_MONITOR17);
4355 u32 breg, reg, md, sscg, product;
Marek Vasut1f7ba642024-12-12 14:34:30 +01004356 u32 ch, cs;
4357
4358 /* Get board data */
4359 priv->dbsc5_board_config = dbsc5_get_board_data();
4360 priv->ddr_phyvalid = (u32)(priv->dbsc5_board_config->bdcfg_phyvalid);
4361 priv->max_density = 0;
4362 priv->cpg_regs = (void __iomem *)ofnode_get_addr(cnode);
4363
4364 for (cs = 0; cs < CS_CNT; cs++)
4365 priv->ch_have_this_cs[cs] = 0;
4366
4367 r_foreach_ech(ch)
4368 for (cs = 0; cs < CS_CNT; cs++)
4369 priv->ddr_density[ch][cs] = 0xFF;
4370
4371 r_foreach_vch(dev, ch) {
4372 for (cs = 0; cs < CS_CNT; cs++) {
4373 priv->ddr_density[ch][cs] = priv->dbsc5_board_config->ch[ch].bdcfg_ddr_density[cs];
4374
4375 if (priv->ddr_density[ch][cs] == 0xFF)
4376 continue;
4377
4378 if (priv->ddr_density[ch][cs] > priv->max_density)
4379 priv->max_density = priv->ddr_density[ch][cs];
4380
4381 priv->ch_have_this_cs[cs] |= BIT(ch);
4382 }
4383 }
4384
4385 /* Decode board clock frequency from MD[14:13] pins */
4386 priv->brd_clkdiv = 3;
4387
4388 breg = (modemr0 >> 13) & 0x3;
4389 if (breg == 0) {
4390 priv->brd_clk = 50; /* 16.66 MHz */
4391 priv->bus_clk = priv->brd_clk * 0x18;
4392 priv->bus_clkdiv = priv->brd_clkdiv;
4393 } else if (breg == 1) {
4394 priv->brd_clk = 60; /* 20 MHz */
4395 priv->bus_clk = priv->brd_clk * 0x14;
4396 priv->bus_clkdiv = priv->brd_clkdiv;
4397 } else if (breg == 3) {
4398 priv->brd_clk = 100; /* 33.33 MHz */
4399 priv->bus_clk = priv->brd_clk * 0x18;
4400 priv->bus_clkdiv = priv->brd_clkdiv * 2;
4401 } else {
4402 printf("MD[14:13] setting 0x%x not supported!", breg);
4403 hang();
4404 }
4405
4406 priv->brd_clkdiva = !!(modemr0 & BIT(14)); /* MD14 */
4407
4408 /* Decode DDR operating frequency from MD[37:36,19,17] pins */
4409 md = ((modemr0 & BIT(19)) >> 18) | ((modemr0 & BIT(17)) >> 17);
Marek Vasut884e8142025-03-16 14:51:43 +01004410 product = otpmon17 & 0xff;
Marek Vasut1f7ba642024-12-12 14:34:30 +01004411 sscg = (modemr1 >> 4) & 0x03;
4412 if (sscg == 2) {
4413 printf("MD[37:36] setting 0x%x not supported!", sscg);
4414 hang();
4415 }
4416
Marek Vasut884e8142025-03-16 14:51:43 +01004417 if (product == 0x2) { /* V4H-3 */
Marek Vasut1f7ba642024-12-12 14:34:30 +01004418 priv->ddr_mbps = 4800;
4419 priv->ddr_mbpsdiv = 1;
Marek Vasut884e8142025-03-16 14:51:43 +01004420 } else if (product == 0x1) { /* V4H-5 */
4421 if (md == 3)
4422 priv->ddr_mbps = 4800;
4423 else
4424 priv->ddr_mbps = 5000;
4425 priv->ddr_mbpsdiv = 1;
4426 } else { /* V4H-7 */
4427 if (md == 0) {
4428 if (sscg == 0) {
4429 priv->ddr_mbps = 6400;
4430 priv->ddr_mbpsdiv = 1;
4431 } else {
4432 priv->ddr_mbps = 19000;
4433 priv->ddr_mbpsdiv = 3;
4434 }
4435 } else if (md == 1) {
4436 priv->ddr_mbps = 6000;
4437 priv->ddr_mbpsdiv = 1;
4438 } else if (md == 2) {
4439 priv->ddr_mbps = 5500;
4440 priv->ddr_mbpsdiv = 1;
4441 } else if (md == 3) {
4442 priv->ddr_mbps = 4800;
4443 priv->ddr_mbpsdiv = 1;
4444 }
Marek Vasut1f7ba642024-12-12 14:34:30 +01004445 }
4446
4447 priv->ddr_mul = CLK_DIV(priv->ddr_mbps, priv->ddr_mbpsdiv * 2,
4448 priv->brd_clk, priv->brd_clkdiv * (priv->brd_clkdiva + 1));
4449 priv->ddr_mul_low = CLK_DIV(6400, 2, priv->brd_clk,
4450 priv->brd_clkdiv * (priv->brd_clkdiva + 1));
4451
4452 priv->ddr_mul_reg = priv->ddr_mul_low;
4453 if (sscg != 0)
4454 priv->ddr_mul_reg -= 2;
4455
4456 priv->ddr_mul_nf = ((8 * priv->ddr_mbps * priv->brd_clkdiv * (priv->brd_clkdiva + 1)) /
4457 (priv->ddr_mbpsdiv * priv->brd_clk * 2)) - (8 * (priv->ddr_mul / 2) * 2);
4458
4459 /* Adjust tccd */
4460 priv->ddr_tccd = 2;
4461
4462 /* Initialize DDR */
4463 dbsc5_reg_write(regs_dbsc_d + DBSC_DBSYSCNT0, 0x1234);
4464 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCNT0A, 0x1234);
4465
4466 reg = dbsc5_init_ddr(dev);
4467
4468 dbsc5_reg_write(regs_dbsc_d + DBSC_DBSYSCNT0, 0x0);
4469 dbsc5_reg_write(regs_dbsc_a + DBSC_DBSYSCNT0A, 0x0);
4470
4471 return reg != priv->ddr_phyvalid;
4472}
4473
4474/**
4475 * renesas_dbsc5_dram_of_to_plat() - Convert OF data to plat data
4476 * @dev: DBSC5 device
4477 *
4478 * Extract DBSC5 address from DT and store it in driver data.
4479 */
4480static int renesas_dbsc5_dram_of_to_plat(struct udevice *dev)
4481{
4482 struct renesas_dbsc5_dram_priv *priv = dev_get_priv(dev);
4483
4484 priv->regs = dev_read_addr_ptr(dev);
4485 if (!priv->regs)
4486 return -EINVAL;
4487
4488 return 0;
4489}
4490
4491/**
4492 * renesas_dbsc5_dram_get_info() - Return RAM size
4493 * @dev: DBSC5 device
4494 * @info: Output RAM info
4495 *
4496 * Return size of the RAM managed by this RAM driver.
4497 */
4498static int renesas_dbsc5_dram_get_info(struct udevice *dev,
4499 struct ram_info *info)
4500{
4501 info->base = 0x40000000;
4502 info->size = 0;
4503
4504 return 0;
4505}
4506
4507static const struct ram_ops renesas_dbsc5_dram_ops = {
4508 .get_info = renesas_dbsc5_dram_get_info,
4509};
4510
4511U_BOOT_DRIVER(renesas_dbsc5_dram) = {
4512 .name = "dbsc5_dram",
4513 .id = UCLASS_RAM,
4514 .of_to_plat = renesas_dbsc5_dram_of_to_plat,
4515 .ops = &renesas_dbsc5_dram_ops,
4516 .probe = renesas_dbsc5_dram_probe,
4517 .priv_auto = sizeof(struct renesas_dbsc5_dram_priv),
4518};