1 /*
2  * Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <common/debug.h>
9 #include <errno.h>
10 #include <lib/mmio.h>
11 
12 #include "ncore_ccu.h"
13 
14 uint32_t poll_active_bit(uint32_t dir);
15 
16 static coh_ss_id_t subsystem_id;
17 
18 
get_subsystem_id(void)19 void get_subsystem_id(void)
20 {
21 	uint32_t snoop_filter, directory, coh_agent;
22 
23 	snoop_filter = CSIDR_NUM_SF(mmio_read_32(NCORE_CCU_CSR(NCORE_CSIDR)));
24 	directory = CSUIDR_NUM_DIR(mmio_read_32(NCORE_CCU_CSR(NCORE_CSUIDR)));
25 	coh_agent = CSUIDR_NUM_CAI(mmio_read_32(NCORE_CCU_CSR(NCORE_CSUIDR)));
26 
27 	subsystem_id.num_snoop_filter = snoop_filter + 1;
28 	subsystem_id.num_directory = directory;
29 	subsystem_id.num_coh_agent = coh_agent;
30 }
31 
directory_init(void)32 uint32_t directory_init(void)
33 {
34 	uint32_t dir_sf_mtn, dir_sf_en;
35 	uint32_t dir, sf, ret;
36 
37 	for (dir = 0; dir < subsystem_id.num_directory; dir++) {
38 		for (sf = 0; sf < subsystem_id.num_snoop_filter; sf++) {
39 			dir_sf_mtn = DIRECTORY_UNIT(dir, NCORE_DIRUSFMCR);
40 			dir_sf_en = DIRECTORY_UNIT(dir, NCORE_DIRUSFER);
41 
42 			/* Initialize All Entries */
43 			mmio_write_32(dir_sf_mtn, SNOOP_FILTER_ID(sf));
44 
45 			/* Poll Active Bit */
46 			ret = poll_active_bit(dir);
47 			if (ret != 0) {
48 				ERROR("Timeout during active bit polling");
49 				return -ETIMEDOUT;
50 			}
51 
52 			/* Disable snoop filter, a bit per snoop filter */
53 			mmio_clrbits_32(dir_sf_en, BIT(sf));
54 
55 		}
56 	}
57 
58 	return 0;
59 }
60 
coherent_agent_intfc_init(void)61 uint32_t coherent_agent_intfc_init(void)
62 {
63 	uint32_t dir, ca, ca_id, ca_type, ca_snoop_en;
64 
65 	for (dir = 0; dir < subsystem_id.num_directory; dir++) {
66 		for (ca = 0; ca < subsystem_id.num_coh_agent; ca++) {
67 			ca_snoop_en = DIRECTORY_UNIT(ca, NCORE_DIRUCASER0);
68 			ca_id = mmio_read_32(COH_AGENT_UNIT(ca, NCORE_CAIUIDR));
69 
70 			/* Coh Agent Snoop Enable */
71 			if (CACHING_AGENT_BIT(ca_id))
72 				mmio_write_32(ca_snoop_en, BIT(ca));
73 
74 			/* Coh Agent Snoop DVM Enable */
75 			ca_type = CACHING_AGENT_TYPE(ca_id);
76 			if (ca_type == ACE_W_DVM || ca_type == ACE_L_W_DVM)
77 				mmio_write_32(NCORE_CCU_CSR(NCORE_CSADSER0),
78 				BIT(ca));
79 		}
80 	}
81 
82 	return 0;
83 }
84 
poll_active_bit(uint32_t dir)85 uint32_t poll_active_bit(uint32_t dir)
86 {
87 	uint32_t timeout = 80000;
88 	uint32_t poll_dir =  DIRECTORY_UNIT(dir, NCORE_DIRUSFMAR);
89 
90 	while (timeout > 0) {
91 		if (mmio_read_32(poll_dir) == 0)
92 			return 0;
93 		timeout--;
94 	}
95 
96 	return -1;
97 }
98 
bypass_ocram_firewall(void)99 void bypass_ocram_firewall(void)
100 {
101 	mmio_clrbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF1),
102 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
103 	mmio_clrbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF2),
104 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
105 	mmio_clrbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF3),
106 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
107 	mmio_clrbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
108 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
109 }
110 
ncore_enable_ocram_firewall(void)111 void ncore_enable_ocram_firewall(void)
112 {
113 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF1),
114 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
115 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF2),
116 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
117 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF3),
118 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
119 	mmio_setbits_32(COH_CPU0_BYPASS_REG(NCORE_FW_OCRAM_BLK_CGF4),
120 			OCRAM_PRIVILEGED_MASK | OCRAM_SECURE_MASK);
121 }
122 
init_ncore_ccu(void)123 uint32_t init_ncore_ccu(void)
124 {
125 	uint32_t status;
126 
127 	get_subsystem_id();
128 	status = directory_init();
129 	status = coherent_agent_intfc_init();
130 	bypass_ocram_firewall();
131 
132 	return status;
133 }
134