1// SPDX-License-Identifier: BSD-3-Clause
2/*
3 * Cadence DDR Driver
4 *
5 * Copyright (C) 2012-2022 Cadence Design Systems, Inc.
6 * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/
7 */
8
9#include <errno.h>
10
11#include "cps_drv_lpddr4.h"
12#include "lpddr4_if.h"
13#include "lpddr4.h"
14#include "lpddr4_structs_if.h"
15
16static u32 lpddr4_pollphyindepirq(const lpddr4_privatedata *pd, lpddr4_intr_phyindepinterrupt irqbit, u32 delay);
17static u32 lpddr4_pollandackirq(const lpddr4_privatedata *pd);
18static u32 lpddr4_startsequencecontroller(const lpddr4_privatedata *pd);
19static u32 lpddr4_writemmrregister(const lpddr4_privatedata *pd, u32 writemoderegval);
20static void lpddr4_checkcatrainingerror(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, bool *errfoundptr);
21static void lpddr4_checkgatelvlerror(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, bool *errfoundptr);
22static void lpddr4_checkreadlvlerror(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, bool *errfoundptr);
23static void lpddr4_checkdqtrainingerror(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, bool *errfoundptr);
24static u8 lpddr4_seterror(volatile u32 *reg, u32 errbitmask, u8 *errfoundptr, const u32 errorinfobits);
25static void lpddr4_setphysnapsettings(lpddr4_ctlregs *ctlregbase, const bool errorfound);
26static void lpddr4_setphyadrsnapsettings(lpddr4_ctlregs *ctlregbase, const bool errorfound);
27static void readpdwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles);
28static void readsrshortwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles);
29static void readsrlongwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles);
30static void readsrlonggatewakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles);
31static void readsrdpshortwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles);
32static void readsrdplongwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles);
33static void readsrdplonggatewakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles);
34static void lpddr4_readlpiwakeuptime(lpddr4_ctlregs *ctlregbase, const lpddr4_lpiwakeupparam *lpiwakeupparam, const lpddr4_ctlfspnum *fspnum, u32 *cycles);
35static void writepdwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles);
36static void writesrshortwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles);
37static void writesrlongwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles);
38static void writesrlonggatewakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles);
39static void writesrdpshortwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles);
40static void writesrdplongwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles);
41static void writesrdplonggatewakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles);
42static void lpddr4_writelpiwakeuptime(lpddr4_ctlregs *ctlregbase, const lpddr4_lpiwakeupparam *lpiwakeupparam, const lpddr4_ctlfspnum *fspnum, const u32 *cycles);
43static void lpddr4_updatefsp2refrateparams(const lpddr4_privatedata *pd, const u32 *tref, const u32 *tras_max);
44static void lpddr4_updatefsp1refrateparams(const lpddr4_privatedata *pd, const u32 *tref, const u32 *tras_max);
45static void lpddr4_updatefsp0refrateparams(const lpddr4_privatedata *pd, const u32 *tref, const u32 *tras_max);
46static u32 lpddr4_getphyrwmask(u32 regoffset);
47
48u32 lpddr4_pollctlirq(const lpddr4_privatedata *pd, lpddr4_intr_ctlinterrupt irqbit, u32 delay)
49{
50	u32 result = 0U;
51	u32 timeout = 0U;
52	bool irqstatus = false;
53
54	do {
55		if (++timeout == delay) {
56			result = (u32)EIO;
57			break;
58		}
59		result = lpddr4_checkctlinterrupt(pd, irqbit, &irqstatus);
60	} while ((irqstatus == (bool)false) && (result == (u32)0));
61
62	return result;
63}
64
65static u32 lpddr4_pollphyindepirq(const lpddr4_privatedata *pd, lpddr4_intr_phyindepinterrupt irqbit, u32 delay)
66{
67	u32 result = 0U;
68	u32 timeout = 0U;
69	bool irqstatus = false;
70
71	do {
72		if (++timeout == delay) {
73			result = (u32)EIO;
74			break;
75		}
76		result = lpddr4_checkphyindepinterrupt(pd, irqbit, &irqstatus);
77	} while ((irqstatus == (bool)false) && (result == (u32)0));
78
79	return result;
80}
81
82static u32 lpddr4_pollandackirq(const lpddr4_privatedata *pd)
83{
84	u32 result = 0U;
85
86	result = lpddr4_pollphyindepirq(pd, LPDDR4_INTR_PHY_INDEP_INIT_DONE_BIT, LPDDR4_CUSTOM_TIMEOUT_DELAY);
87
88	if (result == (u32)0)
89		result = lpddr4_ackphyindepinterrupt(pd, LPDDR4_INTR_PHY_INDEP_INIT_DONE_BIT);
90	if (result == (u32)0)
91		result = lpddr4_pollctlirq(pd, LPDDR4_INTR_MC_INIT_DONE, LPDDR4_CUSTOM_TIMEOUT_DELAY);
92	if (result == (u32)0)
93		result = lpddr4_ackctlinterrupt(pd, LPDDR4_INTR_MC_INIT_DONE);
94	return result;
95}
96
97static u32 lpddr4_startsequencecontroller(const lpddr4_privatedata *pd)
98{
99	u32 result = 0U;
100	u32 regval = 0U;
101	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
102	lpddr4_infotype infotype;
103
104	regval = CPS_FLD_SET(LPDDR4__PI_START__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__PI_START__REG)));
105	CPS_REG_WRITE((&(ctlregbase->LPDDR4__PI_START__REG)), regval);
106
107	regval = CPS_FLD_SET(LPDDR4__START__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__START__REG)));
108	CPS_REG_WRITE(&(ctlregbase->LPDDR4__START__REG), regval);
109
110	if (pd->infohandler != (lpddr4_infocallback)NULL) {
111		infotype = LPDDR4_DRV_SOC_PLL_UPDATE;
112		pd->infohandler(pd, infotype);
113	}
114
115	result = lpddr4_pollandackirq(pd);
116
117	return result;
118}
119
120volatile u32 *lpddr4_addoffset(volatile u32 *addr, u32 regoffset)
121{
122	volatile u32 *local_addr = addr;
123	volatile u32 *regaddr = &local_addr[regoffset];
124
125	return regaddr;
126}
127
128u32 lpddr4_probe(const lpddr4_config *config, u16 *configsize)
129{
130	u32 result;
131
132	result = (u32)(lpddr4_probesf(config, configsize));
133	if (result == (u32)0)
134		*configsize = (u16)(sizeof(lpddr4_privatedata));
135	return result;
136}
137
138u32 lpddr4_init(lpddr4_privatedata *pd, const lpddr4_config *cfg)
139{
140	u32 result = 0U;
141
142	result = lpddr4_initsf(pd, cfg);
143	if (result == (u32)0) {
144		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)cfg->ctlbase;
145		pd->ctlbase = ctlregbase;
146		pd->infohandler = (lpddr4_infocallback)cfg->infohandler;
147		pd->ctlinterrupthandler = (lpddr4_ctlcallback)cfg->ctlinterrupthandler;
148		pd->phyindepinterrupthandler = (lpddr4_phyindepcallback)cfg->phyindepinterrupthandler;
149	}
150	return result;
151}
152
153u32 lpddr4_start(const lpddr4_privatedata *pd)
154{
155	u32 result = 0U;
156
157	result = lpddr4_startsf(pd);
158	if (result == (u32)0) {
159		result = lpddr4_enablepiinitiator(pd);
160		result = lpddr4_startsequencecontroller(pd);
161	}
162	return result;
163}
164
165u32 lpddr4_readreg(const lpddr4_privatedata *pd, lpddr4_regblock cpp, u32 regoffset, u32 *regvalue)
166{
167	u32 result = 0U;
168
169	result = lpddr4_readregsf(pd, cpp, regvalue);
170	if (result == (u32)0) {
171		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
172
173		if (cpp == LPDDR4_CTL_REGS) {
174			if (regoffset >= LPDDR4_INTR_CTL_REG_COUNT)
175				result = (u32)EINVAL;
176			else
177				*regvalue = CPS_REG_READ(lpddr4_addoffset(&(ctlregbase->DENALI_CTL_0), regoffset));
178		} else if (cpp == LPDDR4_PHY_REGS) {
179			if (regoffset >= LPDDR4_INTR_PHY_REG_COUNT)
180				result = (u32)EINVAL;
181			else
182				*regvalue = CPS_REG_READ(lpddr4_addoffset(&(ctlregbase->DENALI_PHY_0), regoffset));
183
184		} else {
185			if (regoffset >= LPDDR4_INTR_PHY_INDEP_REG_COUNT)
186				result = (u32)EINVAL;
187			else
188				*regvalue = CPS_REG_READ(lpddr4_addoffset(&(ctlregbase->DENALI_PI_0), regoffset));
189		}
190	}
191	return result;
192}
193
194static u32 lpddr4_getphyrwmask(u32 regoffset)
195{
196	u32 rwmask = 0U;
197	u32 arrayoffset = 0U;
198	u32 slicenum, sliceoffset = 0U;
199
200	for (slicenum = (u32)0U; slicenum <= (DSLICE_NUM + ASLICE_NUM); slicenum++) {
201		sliceoffset = sliceoffset + (u32)SLICE_WIDTH;
202		if (regoffset < sliceoffset)
203			break;
204	}
205	arrayoffset = regoffset - (sliceoffset - (u32)SLICE_WIDTH);
206
207	if (slicenum < DSLICE_NUM) {
208		rwmask = lpddr4_getdslicemask(slicenum, arrayoffset);
209	} else {
210		if (slicenum == DSLICE_NUM) {
211			if (arrayoffset < ASLICE0_REG_COUNT)
212				rwmask = g_lpddr4_address_slice_0_rw_mask[arrayoffset];
213		} else {
214			if (arrayoffset < PHY_CORE_REG_COUNT)
215				rwmask = g_lpddr4_phy_core_rw_mask[arrayoffset];
216		}
217	}
218	return rwmask;
219}
220
221u32 lpddr4_deferredregverify(const lpddr4_privatedata *pd, lpddr4_regblock cpp, u32 regvalues[], u16 regnum[], u16 regcount)
222{
223	u32 result = (u32)0;
224	u32 aindex;
225	u32 regreadval = 0U;
226	u32 rwmask = 0U;
227
228	result = lpddr4_deferredregverifysf(pd, cpp);
229
230	if ((regvalues == (u32 *)NULL) || (regnum == (u16 *)NULL))
231		result = EINVAL;
232	if (result == (u32)0) {
233		for (aindex = 0; aindex < regcount; aindex++) {
234			result = lpddr4_readreg(pd, cpp, (u32)regnum[aindex], &regreadval);
235
236			if (result == (u32)0) {
237				switch (cpp) {
238				case LPDDR4_PHY_INDEP_REGS:
239					rwmask = g_lpddr4_pi_rw_mask[(u32)regnum[aindex]];
240					break;
241				case LPDDR4_PHY_REGS:
242					rwmask = lpddr4_getphyrwmask((u32)regnum[aindex]);
243					break;
244				default:
245					rwmask = g_lpddr4_ddr_controller_rw_mask[(u32)regnum[aindex]];
246					break;
247				}
248
249				if ((rwmask & regreadval) != ((u32)(regvalues[aindex]) & rwmask)) {
250					result = EIO;
251					break;
252				}
253			}
254		}
255	}
256	return result;
257}
258
259u32 lpddr4_writereg(const lpddr4_privatedata *pd, lpddr4_regblock cpp, u32 regoffset, u32 regvalue)
260{
261	u32 result = 0U;
262
263	result = lpddr4_writeregsf(pd, cpp);
264	if (result == (u32)0) {
265		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
266
267		if (cpp == LPDDR4_CTL_REGS) {
268			if (regoffset >= LPDDR4_INTR_CTL_REG_COUNT)
269				result = (u32)EINVAL;
270			else
271				CPS_REG_WRITE(lpddr4_addoffset(&(ctlregbase->DENALI_CTL_0), regoffset), regvalue);
272		} else if (cpp == LPDDR4_PHY_REGS) {
273			if (regoffset >= LPDDR4_INTR_PHY_REG_COUNT)
274				result = (u32)EINVAL;
275			else
276				CPS_REG_WRITE(lpddr4_addoffset(&(ctlregbase->DENALI_PHY_0), regoffset), regvalue);
277		} else {
278			if (regoffset >= LPDDR4_INTR_PHY_INDEP_REG_COUNT)
279				result = (u32)EINVAL;
280			else
281				CPS_REG_WRITE(lpddr4_addoffset(&(ctlregbase->DENALI_PI_0), regoffset), regvalue);
282		}
283	}
284
285	return result;
286}
287
288u32 lpddr4_getmmrregister(const lpddr4_privatedata *pd, u32 readmoderegval, u64 *mmrvalue, u8 *mmrstatus)
289{
290	u32 result = 0U;
291	u32 tdelay = 1000U;
292	u32 regval = 0U;
293
294	result = lpddr4_getmmrregistersf(pd, mmrvalue, mmrstatus);
295	if (result == (u32)0) {
296		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
297
298		regval = CPS_FLD_WRITE(LPDDR4__READ_MODEREG__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__READ_MODEREG__REG)), readmoderegval);
299		CPS_REG_WRITE(&(ctlregbase->LPDDR4__READ_MODEREG__REG), regval);
300
301		result = lpddr4_pollctlirq(pd, LPDDR4_INTR_MR_READ_DONE, tdelay);
302	}
303	if (result == (u32)0)
304		result = lpddr4_checkmmrreaderror(pd, mmrvalue, mmrstatus);
305	return result;
306}
307
308static u32 lpddr4_writemmrregister(const lpddr4_privatedata *pd, u32 writemoderegval)
309{
310	u32 result = (u32)0;
311	u32 tdelay = 1000U;
312	u32 regval = 0U;
313	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
314
315	regval = CPS_FLD_WRITE(LPDDR4__WRITE_MODEREG__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__WRITE_MODEREG__REG)), writemoderegval);
316	CPS_REG_WRITE(&(ctlregbase->LPDDR4__WRITE_MODEREG__REG), regval);
317
318	result = lpddr4_pollctlirq(pd, LPDDR4_INTR_MR_WRITE_DONE, tdelay);
319
320	return result;
321}
322
323u32 lpddr4_setmmrregister(const lpddr4_privatedata *pd, u32 writemoderegval, u8 *mrwstatus)
324{
325	u32 result = 0U;
326
327	result = lpddr4_setmmrregistersf(pd, mrwstatus);
328	if (result == (u32)0) {
329		result = lpddr4_writemmrregister(pd, writemoderegval);
330
331		if (result == (u32)0)
332			result = lpddr4_ackctlinterrupt(pd, LPDDR4_INTR_MR_WRITE_DONE);
333		if (result == (u32)0) {
334			lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
335			*mrwstatus = (u8)CPS_FLD_READ(LPDDR4__MRW_STATUS__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__MRW_STATUS__REG)));
336			if ((*mrwstatus) != 0U)
337				result = (u32)EIO;
338		}
339	}
340
341	return result;
342}
343
344u32 lpddr4_writectlconfig(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount)
345{
346	u32 result;
347	u32 aindex;
348
349	result = lpddr4_writectlconfigsf(pd);
350	if ((regvalues == (u32 *)NULL) || (regnum == (u16 *)NULL))
351		result = EINVAL;
352
353	if (result == (u32)0) {
354		for (aindex = 0; aindex < regcount; aindex++)
355			result = (u32)lpddr4_writereg(pd, LPDDR4_CTL_REGS, (u32)regnum[aindex],
356							   (u32)regvalues[aindex]);
357	}
358	return result;
359}
360
361u32 lpddr4_writephyindepconfig(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount)
362{
363	u32 result;
364	u32 aindex;
365
366	result = lpddr4_writephyindepconfigsf(pd);
367	if ((regvalues == (u32 *)NULL) || (regnum == (u16 *)NULL))
368		result = EINVAL;
369	if (result == (u32)0) {
370		for (aindex = 0; aindex < regcount; aindex++)
371			result = (u32)lpddr4_writereg(pd, LPDDR4_PHY_INDEP_REGS, (u32)regnum[aindex],
372							   (u32)regvalues[aindex]);
373	}
374	return result;
375}
376
377u32 lpddr4_writephyconfig(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount)
378{
379	u32 result;
380	u32 aindex;
381
382	result = lpddr4_writephyconfigsf(pd);
383	if ((regvalues == (u32 *)NULL) || (regnum == (u16 *)NULL))
384		result = EINVAL;
385	if (result == (u32)0) {
386		for (aindex = 0; aindex < regcount; aindex++)
387			result = (u32)lpddr4_writereg(pd, LPDDR4_PHY_REGS, (u32)regnum[aindex],
388							   (u32)regvalues[aindex]);
389	}
390	return result;
391}
392
393u32 lpddr4_readctlconfig(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount)
394{
395	u32 result;
396	u32 aindex;
397
398	result = lpddr4_readctlconfigsf(pd);
399	if ((regvalues == (u32 *)NULL) || (regnum == (u16 *)NULL))
400		result = EINVAL;
401	if (result == (u32)0) {
402		for (aindex = 0; aindex < regcount; aindex++)
403			result = (u32)lpddr4_readreg(pd, LPDDR4_CTL_REGS, (u32)regnum[aindex],
404							  (u32 *)(&regvalues[aindex]));
405	}
406	return result;
407}
408
409u32 lpddr4_readphyindepconfig(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount)
410{
411	u32 result;
412	u32 aindex;
413
414	result = lpddr4_readphyindepconfigsf(pd);
415	if ((regvalues == (u32 *)NULL) || (regnum == (u16 *)NULL))
416		result = EINVAL;
417	if (result == (u32)0) {
418		for (aindex = 0; aindex < regcount; aindex++)
419			result = (u32)lpddr4_readreg(pd, LPDDR4_PHY_INDEP_REGS, (u32)regnum[aindex],
420							  (u32 *)(&regvalues[aindex]));
421	}
422	return result;
423}
424
425u32 lpddr4_readphyconfig(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount)
426{
427	u32 result;
428	u32 aindex;
429
430	result = lpddr4_readphyconfigsf(pd);
431	if ((regvalues == (u32 *)NULL) || (regnum == (u16 *)NULL))
432		result = EINVAL;
433	if (result == (u32)0) {
434		for (aindex = 0; aindex < regcount; aindex++)
435			result = (u32)lpddr4_readreg(pd, LPDDR4_PHY_REGS, (u32)regnum[aindex],
436							  (u32 *)(&regvalues[aindex]));
437	}
438	return result;
439}
440
441u32 lpddr4_getphyindepinterruptmask(const lpddr4_privatedata *pd, u32 *mask)
442{
443	u32 result;
444
445	result = lpddr4_getphyindepinterruptmsf(pd, mask);
446	if (result == (u32)0) {
447		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
448		*mask = CPS_FLD_READ(LPDDR4__PI_INT_MASK__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__PI_INT_MASK__REG)));
449	}
450	return result;
451}
452
453u32 lpddr4_setphyindepinterruptmask(const lpddr4_privatedata *pd, const u32 *mask)
454{
455	u32 result;
456	u32 regval = 0;
457	const u32 ui32irqcount = (u32)LPDDR4_INTR_PHY_INDEP_DLL_LOCK_STATE_CHANGE_BIT + 1U;
458
459	result = lpddr4_setphyindepinterruptmsf(pd, mask);
460	if ((result == (u32)0) && (ui32irqcount < WORD_SHIFT)) {
461		if (*mask >= (1U << ui32irqcount))
462			result = (u32)EINVAL;
463	}
464	if (result == (u32)0) {
465		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
466
467		regval = CPS_FLD_WRITE(LPDDR4__PI_INT_MASK__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__PI_INT_MASK__REG)), *mask);
468		CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_MASK__REG), regval);
469	}
470	return result;
471}
472
473u32 lpddr4_checkphyindepinterrupt(const lpddr4_privatedata *pd, lpddr4_intr_phyindepinterrupt intr, bool *irqstatus)
474{
475	u32 result = 0;
476	u32 phyindepirqstatus = 0;
477
478	result = LPDDR4_INTR_CheckPhyIndepIntSF(pd, intr, irqstatus);
479	if ((result == (u32)0) && ((u32)intr < WORD_SHIFT)) {
480		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
481
482		phyindepirqstatus = CPS_REG_READ(&(ctlregbase->LPDDR4__PI_INT_STATUS__REG));
483		*irqstatus = (bool)(((phyindepirqstatus >> (u32)intr) & LPDDR4_BIT_MASK) > 0U);
484	}
485	return result;
486}
487
488u32 lpddr4_ackphyindepinterrupt(const lpddr4_privatedata *pd, lpddr4_intr_phyindepinterrupt intr)
489{
490	u32 result = 0U;
491	u32 regval = 0U;
492
493	result = LPDDR4_INTR_AckPhyIndepIntSF(pd, intr);
494	if ((result == (u32)0) && ((u32)intr < WORD_SHIFT)) {
495		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
496
497		regval = ((u32)LPDDR4_BIT_MASK << (u32)intr);
498		CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_ACK__REG), regval);
499	}
500
501	return result;
502}
503
504static void lpddr4_checkcatrainingerror(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, bool *errfoundptr)
505{
506	u32 regval;
507	u32 errbitmask = 0U;
508	u32 snum;
509	volatile u32 *regaddress;
510
511	regaddress = (volatile u32 *)(&(ctlregbase->LPDDR4__PHY_ADR_CALVL_OBS1_0__REG));
512	errbitmask = (CA_TRAIN_RL) | (NIBBLE_MASK);
513	for (snum = 0U; snum < ASLICE_NUM; snum++) {
514		regval = CPS_REG_READ(regaddress);
515		if ((regval & errbitmask) != CA_TRAIN_RL) {
516			debuginfo->catraingerror = CDN_TRUE;
517			*errfoundptr = true;
518		}
519		regaddress = lpddr4_addoffset(regaddress, (u32)SLICE_WIDTH);
520	}
521}
522
523static void lpddr4_checkgatelvlerror(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, bool *errfoundptr)
524{
525	u32 regval;
526	u32 errbitmask = 0U;
527	u32 snum;
528	volatile u32 *regaddress;
529
530	regaddress = (volatile u32 *)(&(ctlregbase->LPDDR4__PHY_GTLVL_STATUS_OBS_0__REG));
531	errbitmask = GATE_LVL_ERROR_FIELDS;
532	for (snum = (u32)0U; snum < DSLICE_NUM; snum++) {
533		regval = CPS_REG_READ(regaddress);
534		if ((regval & errbitmask) != 0U) {
535			debuginfo->gatelvlerror = CDN_TRUE;
536			*errfoundptr = true;
537		}
538		regaddress = lpddr4_addoffset(regaddress, (u32)SLICE_WIDTH);
539	}
540}
541
542static void lpddr4_checkreadlvlerror(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, bool *errfoundptr)
543{
544	u32 regval;
545	u32 errbitmask = 0U;
546	u32 snum;
547	volatile u32 *regaddress;
548
549	regaddress = (volatile u32 *)(&(ctlregbase->LPDDR4__PHY_RDLVL_STATUS_OBS_0__REG));
550	errbitmask = READ_LVL_ERROR_FIELDS;
551	for (snum = (u32)0U; snum < DSLICE_NUM; snum++) {
552		regval = CPS_REG_READ(regaddress);
553		if ((regval & errbitmask) != 0U) {
554			debuginfo->readlvlerror = CDN_TRUE;
555			*errfoundptr = true;
556		}
557		regaddress = lpddr4_addoffset(regaddress, (u32)SLICE_WIDTH);
558	}
559}
560
561static void lpddr4_checkdqtrainingerror(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, bool *errfoundptr)
562{
563	u32 regval;
564	u32 errbitmask = 0U;
565	u32 snum;
566	volatile u32 *regaddress;
567
568	regaddress = (volatile u32 *)(&(ctlregbase->LPDDR4__PHY_WDQLVL_STATUS_OBS_0__REG));
569	errbitmask = DQ_LVL_STATUS;
570	for (snum = (u32)0U; snum < DSLICE_NUM; snum++) {
571		regval = CPS_REG_READ(regaddress);
572		if ((regval & errbitmask) != 0U) {
573			debuginfo->dqtrainingerror = CDN_TRUE;
574			*errfoundptr = true;
575		}
576		regaddress = lpddr4_addoffset(regaddress, (u32)SLICE_WIDTH);
577	}
578}
579
580bool lpddr4_checklvlerrors(const lpddr4_privatedata *pd, lpddr4_debuginfo *debuginfo, bool errfound)
581{
582	bool localerrfound = errfound;
583
584	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
585
586	if (localerrfound == (bool)false)
587		lpddr4_checkcatrainingerror(ctlregbase, debuginfo, &localerrfound);
588
589	if (localerrfound == (bool)false)
590		lpddr4_checkwrlvlerror(ctlregbase, debuginfo, &localerrfound);
591
592	if (localerrfound == (bool)false)
593		lpddr4_checkgatelvlerror(ctlregbase, debuginfo, &localerrfound);
594
595	if (localerrfound == (bool)false)
596		lpddr4_checkreadlvlerror(ctlregbase, debuginfo, &localerrfound);
597
598	if (localerrfound == (bool)false)
599		lpddr4_checkdqtrainingerror(ctlregbase, debuginfo, &localerrfound);
600	return localerrfound;
601}
602
603static u8 lpddr4_seterror(volatile u32 *reg, u32 errbitmask, u8 *errfoundptr, const u32 errorinfobits)
604{
605	u32 regval = 0U;
606
607	regval = CPS_REG_READ(reg);
608	if ((regval & errbitmask) != errorinfobits)
609		*errfoundptr = CDN_TRUE;
610	return *errfoundptr;
611}
612
613void lpddr4_seterrors(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, u8 *errfoundptr)
614{
615	u32 errbitmask = (LPDDR4_BIT_MASK << 0x1U) | (LPDDR4_BIT_MASK);
616
617	debuginfo->pllerror = lpddr4_seterror(&(ctlregbase->LPDDR4__PHY_PLL_OBS_0__REG),
618					      errbitmask, errfoundptr, PLL_READY);
619	if (*errfoundptr == CDN_FALSE)
620		debuginfo->pllerror = lpddr4_seterror(&(ctlregbase->LPDDR4__PHY_PLL_OBS_1__REG),
621						      errbitmask, errfoundptr, PLL_READY);
622
623	if (*errfoundptr == CDN_FALSE)
624		debuginfo->iocaliberror = lpddr4_seterror(&(ctlregbase->LPDDR4__PHY_CAL_RESULT_OBS_0__REG),
625							  IO_CALIB_DONE, errfoundptr, IO_CALIB_DONE);
626	if (*errfoundptr == CDN_FALSE)
627		debuginfo->iocaliberror = lpddr4_seterror(&(ctlregbase->LPDDR4__PHY_CAL_RESULT2_OBS_0__REG),
628							  IO_CALIB_DONE, errfoundptr, IO_CALIB_DONE);
629	if (*errfoundptr == CDN_FALSE)
630		debuginfo->iocaliberror = lpddr4_seterror(&(ctlregbase->LPDDR4__PHY_CAL_RESULT3_OBS_0__REG),
631							  IO_CALIB_FIELD, errfoundptr, IO_CALIB_STATE);
632}
633
634static void lpddr4_setphysnapsettings(lpddr4_ctlregs *ctlregbase, const bool errorfound)
635{
636	u32 snum = 0U;
637	volatile u32 *regaddress;
638	u32 regval = 0U;
639
640	if (errorfound == (bool)false) {
641		regaddress = (volatile u32 *)(&(ctlregbase->LPDDR4__SC_PHY_SNAP_OBS_REGS_0__REG));
642		for (snum = (u32)0U; snum < DSLICE_NUM; snum++) {
643			regval = CPS_FLD_SET(LPDDR4__SC_PHY_SNAP_OBS_REGS_0__FLD, CPS_REG_READ(regaddress));
644			CPS_REG_WRITE(regaddress, regval);
645			regaddress = lpddr4_addoffset(regaddress, (u32)SLICE_WIDTH);
646		}
647	}
648}
649
650static void lpddr4_setphyadrsnapsettings(lpddr4_ctlregs *ctlregbase, const bool errorfound)
651{
652	u32 snum = 0U;
653	volatile u32 *regaddress;
654	u32 regval = 0U;
655
656	if (errorfound == (bool)false) {
657		regaddress = (volatile u32 *)(&(ctlregbase->LPDDR4__SC_PHY_ADR_SNAP_OBS_REGS_0__REG));
658		for (snum = (u32)0U; snum < ASLICE_NUM; snum++) {
659			regval = CPS_FLD_SET(LPDDR4__SC_PHY_ADR_SNAP_OBS_REGS_0__FLD, CPS_REG_READ(regaddress));
660			CPS_REG_WRITE(regaddress, regval);
661			regaddress = lpddr4_addoffset(regaddress, (u32)SLICE_WIDTH);
662		}
663	}
664}
665
666void lpddr4_setsettings(lpddr4_ctlregs *ctlregbase, const bool errorfound)
667{
668	lpddr4_setphysnapsettings(ctlregbase, errorfound);
669	lpddr4_setphyadrsnapsettings(ctlregbase, errorfound);
670}
671
672static void readpdwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles)
673{
674	if (*fspnum == LPDDR4_FSP_0)
675		*cycles = CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F0__REG)));
676	else if (*fspnum == LPDDR4_FSP_1)
677		*cycles = CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F1__REG)));
678	else
679		*cycles = CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F2__REG)));
680}
681
682static void readsrshortwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles)
683{
684	if (*fspnum == LPDDR4_FSP_0)
685		*cycles = CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG)));
686	else if (*fspnum == LPDDR4_FSP_1)
687		*cycles = CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG)));
688	else
689		*cycles = CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG)));
690}
691
692static void readsrlongwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles)
693{
694	if (*fspnum == LPDDR4_FSP_0)
695		*cycles = CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG)));
696	else if (*fspnum == LPDDR4_FSP_1)
697		*cycles = CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG)));
698	else
699		*cycles = CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG)));
700}
701
702static void readsrlonggatewakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles)
703{
704	if (*fspnum == LPDDR4_FSP_0)
705		*cycles = CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG)));
706	else if (*fspnum == LPDDR4_FSP_1)
707		*cycles = CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG)));
708	else
709		*cycles = CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG)));
710}
711
712static void readsrdpshortwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles)
713{
714	if (*fspnum == LPDDR4_FSP_0)
715		*cycles = CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG)));
716	else if (*fspnum == LPDDR4_FSP_1)
717		*cycles = CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG)));
718	else
719		*cycles = CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG)));
720}
721
722static void readsrdplongwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles)
723{
724	if (*fspnum == LPDDR4_FSP_0)
725		*cycles = CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG)));
726	else if (*fspnum == LPDDR4_FSP_1)
727		*cycles = CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG)));
728	else
729		*cycles = CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG)));
730}
731
732static void readsrdplonggatewakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, u32 *cycles)
733{
734	if (*fspnum == LPDDR4_FSP_0)
735		*cycles = CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG)));
736	else if (*fspnum == LPDDR4_FSP_1)
737		*cycles = CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG)));
738	else
739		*cycles = CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG)));
740
741}
742
743static void lpddr4_readlpiwakeuptime(lpddr4_ctlregs *ctlregbase, const lpddr4_lpiwakeupparam *lpiwakeupparam, const lpddr4_ctlfspnum *fspnum, u32 *cycles)
744{
745	if (*lpiwakeupparam == LPDDR4_LPI_PD_WAKEUP_FN)
746		readpdwakeup(fspnum, ctlregbase, cycles);
747	else if (*lpiwakeupparam == LPDDR4_LPI_SR_SHORT_WAKEUP_FN)
748		readsrshortwakeup(fspnum, ctlregbase, cycles);
749	else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_WAKEUP_FN)
750		readsrlongwakeup(fspnum, ctlregbase, cycles);
751	else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_MCCLK_GATE_WAKEUP_FN)
752		readsrlonggatewakeup(fspnum, ctlregbase, cycles);
753	else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_SHORT_WAKEUP_FN)
754		readsrdpshortwakeup(fspnum, ctlregbase, cycles);
755	else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_LONG_WAKEUP_FN)
756		readsrdplongwakeup(fspnum, ctlregbase, cycles);
757	else
758		readsrdplonggatewakeup(fspnum, ctlregbase, cycles);
759}
760
761u32 lpddr4_getlpiwakeuptime(const lpddr4_privatedata *pd, const lpddr4_lpiwakeupparam *lpiwakeupparam, const lpddr4_ctlfspnum *fspnum, u32 *cycles)
762{
763	u32 result = 0U;
764
765	result = lpddr4_getlpiwakeuptimesf(pd, lpiwakeupparam, fspnum, cycles);
766	if (result == (u32)0) {
767		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
768		lpddr4_readlpiwakeuptime(ctlregbase, lpiwakeupparam, fspnum, cycles);
769	}
770	return result;
771}
772
773static void writepdwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles)
774{
775	u32 regval = 0U;
776
777	if (*fspnum == LPDDR4_FSP_0) {
778		regval = CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F0__REG)), *cycles);
779		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F0__REG), regval);
780	} else if (*fspnum == LPDDR4_FSP_1) {
781		regval = CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F1__REG)), *cycles);
782		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F1__REG), regval);
783	} else {
784		regval = CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F2__REG)), *cycles);
785		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F2__REG), regval);
786	}
787}
788
789static void writesrshortwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles)
790{
791	u32 regval = 0U;
792
793	if (*fspnum == LPDDR4_FSP_0) {
794		regval = CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG)), *cycles);
795		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG), regval);
796	} else if (*fspnum == LPDDR4_FSP_1) {
797		regval = CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG)), *cycles);
798		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG), regval);
799	} else {
800		regval = CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG)), *cycles);
801		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG), regval);
802	}
803}
804
805static void writesrlongwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles)
806{
807	u32 regval = 0U;
808
809	if (*fspnum == LPDDR4_FSP_0) {
810		regval = CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG)), *cycles);
811		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG), regval);
812	} else if (*fspnum == LPDDR4_FSP_1) {
813		regval = CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG)), *cycles);
814		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG), regval);
815	} else {
816		regval = CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG)), *cycles);
817		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG), regval);
818	}
819}
820
821static void writesrlonggatewakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles)
822{
823	u32 regval = 0U;
824
825	if (*fspnum == LPDDR4_FSP_0) {
826		regval = CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG)), *cycles);
827		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG), regval);
828	} else if (*fspnum == LPDDR4_FSP_1) {
829		regval = CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG)), *cycles);
830		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG), regval);
831	} else {
832		regval = CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG)), *cycles);
833		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG), regval);
834	}
835}
836
837static void writesrdpshortwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles)
838{
839	u32 regval = 0U;
840
841	if (*fspnum == LPDDR4_FSP_0) {
842		regval = CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG)), *cycles);
843		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG), regval);
844	} else if (*fspnum == LPDDR4_FSP_1) {
845		regval = CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG)), *cycles);
846		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG), regval);
847	} else {
848		regval = CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG)), *cycles);
849		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG), regval);
850	}
851}
852
853static void writesrdplongwakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles)
854{
855	u32 regval = 0U;
856
857	if (*fspnum == LPDDR4_FSP_0) {
858		regval = CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG)), *cycles);
859		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG), regval);
860	} else if (*fspnum == LPDDR4_FSP_1) {
861		regval = CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG)), *cycles);
862		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG), regval);
863	} else {
864		regval = CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG)), *cycles);
865		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG), regval);
866	}
867}
868static void writesrdplonggatewakeup(const lpddr4_ctlfspnum *fspnum, lpddr4_ctlregs *ctlregbase, const u32 *cycles)
869{
870	u32 regval = 0U;
871
872	if (*fspnum == LPDDR4_FSP_0) {
873		regval = CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG)), *cycles);
874		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG), regval);
875	} else if (*fspnum == LPDDR4_FSP_1) {
876		regval = CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG)), *cycles);
877		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG), regval);
878	} else {
879		regval = CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG)), *cycles);
880		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG), regval);
881	}
882}
883
884static void lpddr4_writelpiwakeuptime(lpddr4_ctlregs *ctlregbase, const lpddr4_lpiwakeupparam *lpiwakeupparam, const lpddr4_ctlfspnum *fspnum, const u32 *cycles)
885{
886	if (*lpiwakeupparam == LPDDR4_LPI_PD_WAKEUP_FN)
887		writepdwakeup(fspnum, ctlregbase, cycles);
888	else if (*lpiwakeupparam == LPDDR4_LPI_SR_SHORT_WAKEUP_FN)
889		writesrshortwakeup(fspnum, ctlregbase, cycles);
890	else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_WAKEUP_FN)
891		writesrlongwakeup(fspnum, ctlregbase, cycles);
892	else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_MCCLK_GATE_WAKEUP_FN)
893		writesrlonggatewakeup(fspnum, ctlregbase, cycles);
894	else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_SHORT_WAKEUP_FN)
895		writesrdpshortwakeup(fspnum, ctlregbase, cycles);
896	else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_LONG_WAKEUP_FN)
897		writesrdplongwakeup(fspnum, ctlregbase, cycles);
898	else
899		writesrdplonggatewakeup(fspnum, ctlregbase, cycles);
900}
901
902u32 lpddr4_setlpiwakeuptime(const lpddr4_privatedata *pd, const lpddr4_lpiwakeupparam *lpiwakeupparam, const lpddr4_ctlfspnum *fspnum, const u32 *cycles)
903{
904	u32 result = 0U;
905
906	result = lpddr4_setlpiwakeuptimesf(pd, lpiwakeupparam, fspnum, cycles);
907	if (result == (u32)0) {
908		if (*cycles > NIBBLE_MASK)
909			result = (u32)EINVAL;
910	}
911	if (result == (u32)0) {
912		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
913		lpddr4_writelpiwakeuptime(ctlregbase, lpiwakeupparam, fspnum, cycles);
914	}
915	return result;
916}
917
918u32 lpddr4_getdbireadmode(const lpddr4_privatedata *pd, bool *on_off)
919{
920	u32 result = 0U;
921
922	result = lpddr4_getdbireadmodesf(pd, on_off);
923
924	if (result == (u32)0) {
925		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
926		if (CPS_FLD_READ(LPDDR4__RD_DBI_EN__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__RD_DBI_EN__REG))) == 0U)
927			*on_off = false;
928		else
929			*on_off = true;
930	}
931	return result;
932}
933
934u32 lpddr4_getdbiwritemode(const lpddr4_privatedata *pd, bool *on_off)
935{
936	u32 result = 0U;
937
938	result = lpddr4_getdbireadmodesf(pd, on_off);
939
940	if (result == (u32)0) {
941		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
942		if (CPS_FLD_READ(LPDDR4__WR_DBI_EN__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__WR_DBI_EN__REG))) == 0U)
943			*on_off = false;
944		else
945			*on_off = true;
946	}
947	return result;
948}
949
950u32 lpddr4_setdbimode(const lpddr4_privatedata *pd, const lpddr4_dbimode *mode)
951{
952	u32 result = 0U;
953	u32 regval = 0U;
954
955	result = lpddr4_setdbimodesf(pd, mode);
956
957	if (result == (u32)0) {
958		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
959
960		if (*mode == LPDDR4_DBI_RD_ON)
961			regval = CPS_FLD_WRITE(LPDDR4__RD_DBI_EN__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__RD_DBI_EN__REG)), 1U);
962		else if (*mode == LPDDR4_DBI_RD_OFF)
963			regval = CPS_FLD_WRITE(LPDDR4__RD_DBI_EN__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__RD_DBI_EN__REG)), 0U);
964		else if (*mode == LPDDR4_DBI_WR_ON)
965			regval = CPS_FLD_WRITE(LPDDR4__WR_DBI_EN__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__WR_DBI_EN__REG)), 1U);
966		else
967			regval = CPS_FLD_WRITE(LPDDR4__WR_DBI_EN__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__WR_DBI_EN__REG)), 0U);
968		CPS_REG_WRITE(&(ctlregbase->LPDDR4__RD_DBI_EN__REG), regval);
969	}
970	return result;
971}
972
973u32 lpddr4_getrefreshrate(const lpddr4_privatedata *pd, const lpddr4_ctlfspnum *fspnum, u32 *tref, u32 *tras_max)
974{
975	u32 result = 0U;
976
977	result = lpddr4_getrefreshratesf(pd, fspnum, tref, tras_max);
978
979	if (result == (u32)0) {
980		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
981
982		switch (*fspnum) {
983		case LPDDR4_FSP_2:
984			*tref = CPS_FLD_READ(LPDDR4__TREF_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TREF_F2__REG)));
985			*tras_max = CPS_FLD_READ(LPDDR4__TRAS_MAX_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TRAS_MAX_F2__REG)));
986			break;
987		case LPDDR4_FSP_1:
988			*tref = CPS_FLD_READ(LPDDR4__TREF_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TREF_F1__REG)));
989			*tras_max = CPS_FLD_READ(LPDDR4__TRAS_MAX_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TRAS_MAX_F1__REG)));
990			break;
991		default:
992			*tref = CPS_FLD_READ(LPDDR4__TREF_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TREF_F0__REG)));
993			*tras_max = CPS_FLD_READ(LPDDR4__TRAS_MAX_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TRAS_MAX_F0__REG)));
994			break;
995		}
996	}
997	return result;
998}
999
1000static void lpddr4_updatefsp2refrateparams(const lpddr4_privatedata *pd, const u32 *tref, const u32 *tras_max)
1001{
1002	u32 regval = 0U;
1003	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
1004
1005	regval = CPS_FLD_WRITE(LPDDR4__TREF_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TREF_F2__REG)), *tref);
1006	CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F2__REG), regval);
1007	regval = CPS_FLD_WRITE(LPDDR4__TRAS_MAX_F2__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TRAS_MAX_F2__REG)), *tras_max);
1008	CPS_REG_WRITE(&(ctlregbase->LPDDR4__TRAS_MAX_F2__REG), regval);
1009}
1010
1011static void lpddr4_updatefsp1refrateparams(const lpddr4_privatedata *pd, const u32 *tref, const u32 *tras_max)
1012{
1013	u32 regval = 0U;
1014	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
1015
1016	regval = CPS_FLD_WRITE(LPDDR4__TREF_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TREF_F1__REG)), *tref);
1017	CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F1__REG), regval);
1018	regval = CPS_FLD_WRITE(LPDDR4__TRAS_MAX_F1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TRAS_MAX_F1__REG)), *tras_max);
1019	CPS_REG_WRITE(&(ctlregbase->LPDDR4__TRAS_MAX_F1__REG), regval);;
1020}
1021
1022static void lpddr4_updatefsp0refrateparams(const lpddr4_privatedata *pd, const u32 *tref, const u32 *tras_max)
1023{
1024	u32 regval = 0U;
1025	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
1026
1027	regval = CPS_FLD_WRITE(LPDDR4__TREF_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TREF_F0__REG)), *tref);
1028	CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F0__REG), regval);
1029	regval = CPS_FLD_WRITE(LPDDR4__TRAS_MAX_F0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TRAS_MAX_F0__REG)), *tras_max);
1030	CPS_REG_WRITE(&(ctlregbase->LPDDR4__TRAS_MAX_F0__REG), regval);
1031}
1032
1033u32 lpddr4_setrefreshrate(const lpddr4_privatedata *pd, const lpddr4_ctlfspnum *fspnum, const u32 *tref, const u32 *tras_max)
1034{
1035	u32 result = 0U;
1036
1037	result = lpddr4_setrefreshratesf(pd, fspnum, tref, tras_max);
1038
1039	if (result == (u32)0) {
1040		switch (*fspnum) {
1041		case LPDDR4_FSP_2:
1042			lpddr4_updatefsp2refrateparams(pd, tref, tras_max);
1043			break;
1044		case LPDDR4_FSP_1:
1045			lpddr4_updatefsp1refrateparams(pd, tref, tras_max);
1046			break;
1047		default:
1048			lpddr4_updatefsp0refrateparams(pd, tref, tras_max);
1049			break;
1050		}
1051	}
1052	return result;
1053}
1054
1055u32 lpddr4_refreshperchipselect(const lpddr4_privatedata *pd, const u32 trefinterval)
1056{
1057	u32 result = 0U;
1058	u32 regval = 0U;
1059
1060	result = lpddr4_refreshperchipselectsf(pd);
1061
1062	if (result == (u32)0) {
1063		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
1064		regval = CPS_FLD_WRITE(LPDDR4__TREF_INTERVAL__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__TREF_INTERVAL__REG)), trefinterval);
1065		CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_INTERVAL__REG), regval);
1066	}
1067	return result;
1068}
1069