3535#include <uapi/user/manifest.h>
3636#include <platform/platform.h>
3737#include <platform/memory.h>
38+ #include <platform/platcfg.h>
3839
3940#if defined CONFIG_SUECREEK
4041#define MANIFEST_BASE BOOT_LDR_MANIFEST_BASE
@@ -133,12 +134,71 @@ static int32_t hp_sram_init(void)
133134{
134135 int delay_count = 256 ;
135136 uint32_t status ;
137+ #if defined(CONFIG_CANNONLAKE )
138+ uint32_t ebb_in_use ;
139+ uint32_t ebb_mask0 , ebb_mask1 , ebb_avail_mask0 , ebb_avail_mask1 ;
140+ #endif
136141
137142 shim_write (SHIM_LDOCTL , SHIM_LDOCTL_HPSRAM_LDO_ON );
138143
139144 /* add some delay before touch power register */
140145 idelay (delay_count );
141146
147+ #if defined(CONFIG_CANNONLAKE )
148+ /* calculate total number of used SRAM banks (EBB)
149+ * to power up only ncecesary banks
150+ */
151+ ebb_in_use = ((SOF_MEMORY_SIZE % SRAM_BANK_SIZE ) == 0 ) ?
152+ (SOF_MEMORY_SIZE / SRAM_BANK_SIZE ) :
153+ (SOF_MEMORY_SIZE / SRAM_BANK_SIZE ) + 1 ;
154+
155+ /* bit masks reflect total number of available EBB (banks) in each
156+ * segment; current implementation supports 2 segments 0,1
157+ */
158+ if (PLATFORM_HPSRAM_EBB_COUNT > EBB_SEGMENT_SIZE ) {
159+ ebb_avail_mask0 = (uint32_t )MASK (EBB_SEGMENT_SIZE - 1 , 0 );
160+ ebb_avail_mask1 = (uint32_t )MASK (PLATFORM_HPSRAM_EBB_COUNT -
161+ EBB_SEGMENT_SIZE - 1 , 0 );
162+ } else {
163+ ebb_avail_mask0 = (uint32_t )MASK (PLATFORM_HPSRAM_EBB_COUNT - 1 ,
164+ 0 );
165+ ebb_avail_mask1 = 0 ;
166+ }
167+
168+ /* bit masks of banks that have to be powered up in each segment */
169+ if (ebb_in_use > EBB_SEGMENT_SIZE ) {
170+ ebb_mask0 = (uint32_t )MASK (EBB_SEGMENT_SIZE - 1 , 0 );
171+ ebb_mask1 = (uint32_t )MASK (ebb_in_use - EBB_SEGMENT_SIZE - 1 ,
172+ 0 );
173+ } else {
174+ /* assumption that ebb_in_use is > 0 */
175+ ebb_mask0 = (uint32_t )MASK (ebb_in_use - 1 , 0 );
176+ ebb_mask1 = 0 ;
177+ }
178+
179+ /* HSPGCTL, HSRMCTL use reverse logic - 0 means EBB is power gated */
180+ io_reg_write (HSPGCTL0 , (~ebb_mask0 ) & ebb_avail_mask0 );
181+ io_reg_write (HSRMCTL0 , (~ebb_mask0 ) & ebb_avail_mask0 );
182+ io_reg_write (HSPGCTL1 , (~ebb_mask1 ) & ebb_avail_mask1 );
183+ io_reg_write (HSRMCTL1 , (~ebb_mask1 ) & ebb_avail_mask1 );
184+
185+ /* query the power status of first part of HP memory */
186+ /* to check whether it has been powered up. A few */
187+ /* cycles are needed for it to be powered up */
188+ status = io_reg_read (HSPGISTS0 );
189+ while (status != ((~ebb_mask0 ) & ebb_avail_mask0 )) {
190+ idelay (delay_count );
191+ status = io_reg_read (HSPGISTS0 );
192+ }
193+ /* query the power status of second part of HP memory */
194+ /* and do as above code */
195+
196+ status = io_reg_read (HSPGISTS1 );
197+ while (status != ((~ebb_mask1 ) & ebb_avail_mask1 )) {
198+ idelay (delay_count );
199+ status = io_reg_read (HSPGISTS1 );
200+ }
201+ #else
142202 /* now all the memory bank has been powered up */
143203 io_reg_write (HSPGCTL0 , 0 );
144204 io_reg_write (HSRMCTL0 , 0 );
@@ -161,7 +221,7 @@ static int32_t hp_sram_init(void)
161221 idelay (delay_count );
162222 status = io_reg_read (HSPGISTS1 );
163223 }
164-
224+ #endif
165225 /* add some delay before touch power register */
166226 idelay (delay_count );
167227
0 commit comments