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