1 /* Copyright(c) 2021 Intel Corporation. All rights reserved.
2  * SPDX-License-Identifier: Apache-2.0
3  */
4 
5 #include <stddef.h>
6 #include <stdint.h>
7 
8 #include <zephyr/devicetree.h>
9 #include <soc_util.h>
10 #include <zephyr/cache.h>
11 #include <adsp_shim.h>
12 #include <adsp_memory.h>
13 #include <cpu_init.h>
14 #include "manifest.h"
15 
16 #define DELAY_COUNT			256
17 #define LPSRAM_MASK(x)		0x00000003
18 #define PLATFORM_INIT_HPSRAM
19 #define PLATFORM_INIT_LPSRAM
20 
21 BUILD_ASSERT((DT_REG_SIZE(DT_NODELABEL(sram0)) % SRAM_BANK_SIZE) == 0,
22 		"sram0 must be divisible by 64*1024 bank size.");
23 
24 /*
25  * Function powers up a number of memory banks provided as an argument
26  * and gates remaining memory banks
27  */
hp_sram_pm_banks(uint32_t banks)28 static __imr void hp_sram_pm_banks(uint32_t banks)
29 {
30 #ifdef CONFIG_ADSP_INIT_HPSRAM
31 	uint32_t status, ebb_mask0, ebb_mask1, ebb_avail_mask0, ebb_avail_mask1,
32 		total_banks_count = HPSRAM_EBB_COUNT;
33 
34 	CAVS_SHIM.ldoctl = SHIM_LDOCTL_HPSRAM_LDO_ON;
35 
36 	/* Add some delay before touch power register */
37 	z_idelay(DELAY_COUNT);
38 
39 	/*
40 	 * bit masks reflect total number of available EBB (banks) in each
41 	 * segment; current implementation supports 2 segments 0,1
42 	 */
43 	if (total_banks_count > EBB_SEG_SIZE) {
44 		ebb_avail_mask0 = (uint32_t)GENMASK(EBB_SEG_SIZE - 1, 0);
45 		ebb_avail_mask1 = (uint32_t)GENMASK(total_banks_count -
46 						    EBB_SEG_SIZE - 1, 0);
47 	} else {
48 		ebb_avail_mask0 = (uint32_t)GENMASK(total_banks_count - 1, 0);
49 		ebb_avail_mask1 = 0;
50 	}
51 
52 	/* bit masks of banks that have to be powered up in each segment */
53 	if (banks > EBB_SEG_SIZE) {
54 		ebb_mask0 = (uint32_t)GENMASK(EBB_SEG_SIZE - 1, 0);
55 		ebb_mask1 = (uint32_t)GENMASK(banks - EBB_SEG_SIZE - 1,
56 		0);
57 	} else {
58 		/* assumption that ebb_in_use is > 0 */
59 		ebb_mask0 = (uint32_t)GENMASK(banks - 1, 0);
60 		ebb_mask1 = 0;
61 	}
62 
63 	/* HSPGCTL, HSRMCTL use reverse logic - 0 means EBB is power gated */
64 	CAVS_L2LM.hspgctl0 = (~ebb_mask0) & ebb_avail_mask0;
65 	CAVS_L2LM.hsrmctl0 = (~ebb_mask0) & ebb_avail_mask0;
66 	CAVS_L2LM.hspgctl1 = (~ebb_mask1) & ebb_avail_mask1;
67 	CAVS_L2LM.hsrmctl1 = (~ebb_mask1) & ebb_avail_mask1;
68 
69 	/*
70 	 * Query the power status of first part of HP memory
71 	 * to check whether it has been powered up. A few
72 	 * cycles are needed for it to be powered up
73 	 */
74 	status = CAVS_L2LM.hspgists0;
75 	while (status != ((~ebb_mask0) & ebb_avail_mask0)) {
76 		z_idelay(DELAY_COUNT);
77 		status = CAVS_L2LM.hspgists0;
78 	}
79 
80 	/*
81 	 * Query the power status of second part of HP memory
82 	 * and do as above code
83 	 */
84 	status = CAVS_L2LM.hspgists1;
85 
86 	while (status != ((~ebb_mask1) & ebb_avail_mask1)) {
87 		z_idelay(DELAY_COUNT);
88 		status = CAVS_L2LM.hspgists1;
89 	}
90 
91 	/* Add some delay before touch power register */
92 	z_idelay(DELAY_COUNT);
93 
94 	CAVS_SHIM.ldoctl = SHIM_LDOCTL_HPSRAM_LDO_BYPASS;
95 #endif
96 }
97 
hp_sram_init(uint32_t memory_size)98 __imr void hp_sram_init(uint32_t memory_size)
99 {
100 	uint32_t ebb_in_use;
101 
102 	/*
103 	 * Calculate total number of used SRAM banks (EBB)
104 	 * to power up only necessary banks
105 	 */
106 	ebb_in_use = DIV_ROUND_UP(memory_size, SRAM_BANK_SIZE);
107 
108 	hp_sram_pm_banks(ebb_in_use);
109 
110 	bbzero((void *)L2_SRAM_BASE, L2_SRAM_SIZE);
111 }
112 
lp_sram_init(void)113 __imr void lp_sram_init(void)
114 {
115 #ifdef PLATFORM_INIT_LPSRAM
116 	uint32_t timeout_counter;
117 
118 	timeout_counter = DELAY_COUNT;
119 
120 	CAVS_SHIM.ldoctl = SHIM_LDOCTL_LPSRAM_LDO_ON;
121 
122 	/* Add some delay before writing power registers */
123 	z_idelay(DELAY_COUNT);
124 
125 	/* FIXME */
126 	CAVS_L2LM.lspgctl = CAVS_L2LM.lspgists & ~LPSRAM_MASK(0);
127 
128 	/* Add some delay before checking the status */
129 	z_idelay(DELAY_COUNT);
130 
131 	/*
132 	 * Query the power status of first part of LP memory
133 	 * to check whether it has been powered up. A few
134 	 * cycles are needed for it to be powered up
135 	 */
136 	/* FIXME */
137 	while (CAVS_L2LM.lspgists && timeout_counter--) {
138 		z_idelay(DELAY_COUNT);
139 	}
140 
141 	CAVS_SHIM.ldoctl = SHIM_LDOCTL_LPSRAM_LDO_BYPASS;
142 	bbzero((void *)LP_SRAM_BASE, LP_SRAM_SIZE);
143 #endif
144 }
145