1 /*
2  * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #pragma once
7 
8 #include <zephyr.h>
9 #include "soc/dport_reg.h"
10 
11 #define DPORT_CACHE_MASK 0x3f
12 
13 static uint32_t s_cache_ops_saved_state[2];
14 static unsigned int s_intr_saved_state;
15 
esp32_disable_cache(uint32_t cpuid,uint32_t * saved_state)16 static void IRAM_ATTR esp32_disable_cache(uint32_t cpuid, uint32_t *saved_state)
17 {
18 	uint32_t ret = 0;
19 
20 	if (cpuid == PRO_CPU_NUM) {
21 		ret |= DPORT_GET_PERI_REG_BITS2(DPORT_PRO_CACHE_CTRL1_REG, DPORT_CACHE_MASK, 0);
22 		while (DPORT_GET_PERI_REG_BITS2(DPORT_PRO_DCACHE_DBUG0_REG, DPORT_PRO_CACHE_STATE, DPORT_PRO_CACHE_STATE_S) != 1) {
23 			;
24 		}
25 		DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL_REG, 1, 0, DPORT_PRO_CACHE_ENABLE_S);
26 	} else   {
27 		ret |= DPORT_GET_PERI_REG_BITS2(DPORT_APP_CACHE_CTRL1_REG, DPORT_CACHE_MASK, 0);
28 		while (DPORT_GET_PERI_REG_BITS2(DPORT_APP_DCACHE_DBUG0_REG, DPORT_APP_CACHE_STATE, DPORT_APP_CACHE_STATE_S) != 1) {
29 			;
30 		}
31 		DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL_REG, 1, 0, DPORT_APP_CACHE_ENABLE_S);
32 	}
33 	*saved_state = ret;
34 }
35 
esp32_restore_cache(uint32_t cpuid,uint32_t saved_state)36 static void IRAM_ATTR esp32_restore_cache(uint32_t cpuid, uint32_t saved_state)
37 {
38 	if (cpuid == PRO_CPU_NUM) {
39 		DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL_REG, 1, 1, DPORT_PRO_CACHE_ENABLE_S);
40 		DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL1_REG, DPORT_CACHE_MASK, saved_state, 0);
41 	} else   {
42 		DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL_REG, 1, 1, DPORT_APP_CACHE_ENABLE_S);
43 		DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL1_REG, DPORT_CACHE_MASK, saved_state, 0);
44 	}
45 }
46 
esp32_spiflash_start(void)47 void IRAM_ATTR esp32_spiflash_start(void)
48 {
49 	k_sched_lock();
50 
51 	s_intr_saved_state = irq_lock();
52 
53 	int cpu_id = arch_curr_cpu()->id;
54 	esp32_disable_cache(cpu_id, &s_cache_ops_saved_state[cpu_id]);
55 
56 #ifdef CONFIG_SMP
57 	int other_cpu = (cpu_id == PRO_CPU_NUM) ? APP_CPU_NUM : PRO_CPU_NUM;
58 	esp32_disable_cache(other_cpu, &s_cache_ops_saved_state[other_cpu]);
59 #endif
60 }
61 
esp32_spiflash_end(void)62 void IRAM_ATTR esp32_spiflash_end(void)
63 {
64 	int cpu_id = arch_curr_cpu()->id;
65 
66 	esp32_restore_cache(cpu_id, s_cache_ops_saved_state[cpu_id]);
67 
68 #ifdef CONFIG_SMP
69 	int other_cpu = (cpu_id == PRO_CPU_NUM) ? APP_CPU_NUM : PRO_CPU_NUM;
70 	esp32_restore_cache(other_cpu, s_cache_ops_saved_state[other_cpu]);
71 #endif
72 	irq_unlock(s_intr_saved_state);
73 
74 	k_sched_unlock();
75 }
76 
77