3939#define PWR_SRAM_CLKISO_BIT BIT(5)
4040#define PWR_SRAM_ISOINT_B_BIT BIT(6)
4141
42+ #define PWR_RTFF_SAVE BIT(24)
43+ #define PWR_RTFF_NRESTORE BIT(25)
44+ #define PWR_RTFF_CLK_DIS BIT(26)
45+ #define PWR_RTFF_SAVE_FLAG BIT(27)
46+ #define PWR_RTFF_UFS_CLK_DIS BIT(28)
47+
4248struct scpsys_domain {
4349 struct generic_pm_domain genpd ;
4450 const struct scpsys_domain_data * data ;
@@ -247,7 +253,7 @@ static int scpsys_regulator_disable(struct regulator *supply)
247253static int scpsys_ctl_pwrseq_on (struct scpsys_domain * pd )
248254{
249255 struct scpsys * scpsys = pd -> scpsys ;
250- bool tmp ;
256+ bool do_rtff_nrestore , tmp ;
251257 int ret ;
252258
253259 /* subsys power on */
@@ -260,19 +266,105 @@ static int scpsys_ctl_pwrseq_on(struct scpsys_domain *pd)
260266 if (ret < 0 )
261267 return ret ;
262268
269+ if (pd -> data -> rtff_type == SCPSYS_RTFF_TYPE_PCIE_PHY )
270+ regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_CLK_DIS );
271+
263272 regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_CLK_DIS_BIT );
264273 regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_ISO_BIT );
274+
275+ /* Wait for RTFF HW to sync buck isolation state if this is PCIe PHY RTFF */
276+ if (pd -> data -> rtff_type == SCPSYS_RTFF_TYPE_PCIE_PHY )
277+ udelay (5 );
278+
265279 regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RST_B_BIT );
266280
281+ /*
282+ * RTFF HW state may be modified by secure world or remote processors.
283+ *
284+ * With the only exception of STOR_UFS, which always needs save/restore,
285+ * check if this power domain's RTFF is already on before trying to do
286+ * the NRESTORE procedure, otherwise the system will lock up.
287+ */
288+ switch (pd -> data -> rtff_type ) {
289+ case SCPSYS_RTFF_TYPE_GENERIC :
290+ case SCPSYS_RTFF_TYPE_PCIE_PHY :
291+ {
292+ u32 ctl_status ;
293+
294+ regmap_read (scpsys -> base , pd -> data -> ctl_offs , & ctl_status );
295+ do_rtff_nrestore = ctl_status & PWR_RTFF_SAVE_FLAG ;
296+ break ;
297+ }
298+ case SCPSYS_RTFF_TYPE_STOR_UFS :
299+ /* STOR_UFS always needs NRESTORE */
300+ do_rtff_nrestore = true;
301+ break ;
302+ default :
303+ do_rtff_nrestore = false;
304+ break ;
305+ }
306+
307+ /* Return early if RTFF NRESTORE shall not be done */
308+ if (!do_rtff_nrestore )
309+ return 0 ;
310+
311+ switch (pd -> data -> rtff_type ) {
312+ case SCPSYS_RTFF_TYPE_GENERIC :
313+ regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_SAVE_FLAG );
314+ regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_CLK_DIS );
315+ regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_NRESTORE );
316+ regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_NRESTORE );
317+ regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_CLK_DIS );
318+ break ;
319+ case SCPSYS_RTFF_TYPE_PCIE_PHY :
320+ regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_SAVE_FLAG );
321+ regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_NRESTORE );
322+ regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_NRESTORE );
323+ regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_CLK_DIS );
324+ break ;
325+ case SCPSYS_RTFF_TYPE_STOR_UFS :
326+ regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_UFS_CLK_DIS );
327+ regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_NRESTORE );
328+ regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_NRESTORE );
329+ regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_UFS_CLK_DIS );
330+ break ;
331+ default :
332+ break ;
333+ }
334+
267335 return 0 ;
268336}
269337
270338static void scpsys_ctl_pwrseq_off (struct scpsys_domain * pd )
271339{
272340 struct scpsys * scpsys = pd -> scpsys ;
273341
342+ switch (pd -> data -> rtff_type ) {
343+ case SCPSYS_RTFF_TYPE_GENERIC :
344+ case SCPSYS_RTFF_TYPE_PCIE_PHY :
345+ regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_CLK_DIS );
346+ regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_SAVE );
347+ regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_SAVE );
348+ regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_CLK_DIS );
349+ regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_SAVE_FLAG );
350+ break ;
351+ case SCPSYS_RTFF_TYPE_STOR_UFS :
352+ regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_UFS_CLK_DIS );
353+ regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_SAVE );
354+ regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_SAVE );
355+ regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RTFF_UFS_CLK_DIS );
356+ break ;
357+ default :
358+ break ;
359+ }
360+
274361 /* subsys power off */
275362 regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_ISO_BIT );
363+
364+ /* Wait for RTFF HW to sync buck isolation state if this is PCIe PHY RTFF */
365+ if (pd -> data -> rtff_type == SCPSYS_RTFF_TYPE_PCIE_PHY )
366+ udelay (1 );
367+
276368 regmap_set_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_CLK_DIS_BIT );
277369 regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_RST_B_BIT );
278370 regmap_clear_bits (scpsys -> base , pd -> data -> ctl_offs , PWR_ON_2ND_BIT );
0 commit comments