1 /*
2  * Copyright 2023 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include "fsl_common.h"
7 #include "fsl_misc_soc.h"
8 
SOC_MixPowerInit(soc_mix_power_domain_e pwr_dom)9 int SOC_MixPowerInit(soc_mix_power_domain_e pwr_dom)
10 {
11     soc_src_mem_slice_id_e mem_id;
12     soc_src_mem_slice_regs_t *mem_regs;
13     soc_src_general_regs_t *global_regs;
14     BLK_CTRL_S_AONMIX_Type *aonmix_base;
15     uint32_t scr;
16     SRC_MIX_SLICE_Type *mix_base;
17 
18     switch (pwr_dom)
19     {
20         case SOC_MIX_PD_MEDIAMIX:
21             mix_base = SRC_MEDIA_SLICE;
22             mem_id   = SOC_SRC_MEM_MEDIA;
23             scr      = BIT(5);
24 
25             /* Enable S400 handshake */
26             aonmix_base = BLK_CTRL_S_AONMIX2;
27             aonmix_base->LP_HANDSHAKE |= BIT(13);
28             break;
29         case SOC_MIX_PD_MLMIX:
30             mix_base = SRC_ML_SLICE;
31             mem_id   = SOC_SRC_MEM_ML;
32             scr      = BIT(4);
33             break;
34         case SOC_MIX_PD_DDRMIX:
35             mix_base = SRC_DDR_SLICE;
36             mem_id   = SOC_SRC_MEM_DDRMIX;
37             scr      = BIT(6);
38             break;
39         default:
40             return -1;
41     }
42 
43     mem_regs    = (soc_src_mem_slice_regs_t *)(uint32_t)(SOC_SRC_IPS_BASE_ADDR + 0x3800 + 0x400 * mem_id);
44     global_regs = (soc_src_general_regs_t *)(uint32_t)SOC_SRC_GLOBAL_RBASE;
45 
46     /* Allow NS to set it */
47     mix_base->AUTHEN_CTRL |= BIT(9);
48 
49     mix_base->PSW_ACK_CTRL_0 &= ~(BIT(28) | BIT(29));
50 
51     /* mix reset will be held until boot core write this bit to 1 */
52     global_regs->scr |= scr;
53 
54     /* Enable mem in Low power auto sequence */
55     mem_regs->mem_ctrl |= BIT(2);
56 
57     /* Set the power down state */
58     if (mix_base->FUNC_STAT & SRC_MIX_SLICE_FUNC_STAT_PSW_STAT(1))
59     {
60         /*
61          * The mix is default power off, power down it to make PDN_SFT bit
62          *  aligned with FUNC STAT
63          */
64         mix_base->SLICE_SW_CTRL |= BIT(31);
65 
66         /* Since PSW_STAT is 1, can't be used for power off status (SW_CTRL BIT31 set)) */
67         /* Check the MEM STAT change to ensure SSAR is completed */
68         while (!(mix_base->FUNC_STAT & SRC_MIX_SLICE_FUNC_STAT_MEM_STAT(1)))
69         {
70         }
71 
72         /* wait few ipg clock cycles to ensure FSM done and power off status is correct */
73         /* About 5 cycles at 24Mhz, 1us is enough  */
74         SDK_DelayAtLeastUs(1, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
75     }
76     else
77     {
78         /*  The mix is default power on, Do mix power cycle */
79         mix_base->SLICE_SW_CTRL |= BIT(31);
80         while (!(mix_base->FUNC_STAT & SRC_MIX_SLICE_FUNC_STAT_PSW_STAT(1)))
81         {
82         }
83     }
84 
85     /* power on */
86     mix_base->SLICE_SW_CTRL &= ~BIT(31);
87     while (mix_base->FUNC_STAT & SRC_MIX_SLICE_FUNC_STAT_ISO_STAT(1))
88     {
89     }
90 
91     return 0;
92 }
93 
SOC_DisableIsolation(void)94 void SOC_DisableIsolation(void)
95 {
96     soc_src_general_regs_t *global_regs = (soc_src_general_regs_t *)(uint32_t)SOC_SRC_GLOBAL_RBASE;
97     /* clear isolation for usbphy, dsi, csi*/
98     global_regs->sp_iso_ctrl = 0x0;
99 }
100