blob: 3c61470868ee055007f2936268a39a40df194c30 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (C) 2018 MediaTek Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/kernel.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
17#include <asm/io.h>
18#include <mt-plat/sync_write.h>
19#include <mt-plat/mtk_io.h>
20/* #include "mtk_typedefs.h" */
21#include "core_plf_init.h"
22#include "mtk_emi_bm.h"
23#include "met_drv.h"
24#include "interface.h"
25#if defined(CONFIG_MTK_TINYSYS_SSPM_SUPPORT) && defined(ONDIEMET_SUPPORT)
26#include "sspm/ondiemet_sspm.h"
27#endif
28
29#undef DEBUG
30
31#define emi_readl readl
32#define emi_reg_sync_writel mt_reg_sync_writel
33
34#define MASK_MASTER 0xFF
35#define MASK_TRANS_TYPE 0xFF
36
37static void __iomem *BaseAddrEMI;
38const unsigned int emi_config[] = {
39 EMI_BMEN,
40 EMI_MSEL,
41 EMI_MSEL2,
42 EMI_MSEL3,
43 EMI_MSEL4,
44 EMI_MSEL5,
45 EMI_MSEL6,
46 EMI_MSEL7,
47 EMI_MSEL8,
48 EMI_MSEL9,
49 EMI_MSEL10,
50 EMI_BMID0,
51 EMI_BMID1,
52 EMI_BMID2,
53 EMI_BMID3,
54 EMI_BMID4,
55 EMI_BMID5,
56 EMI_BMID6,
57 EMI_BMID7,
58 EMI_BMID8,
59 EMI_BMID9,
60 EMI_BMID10,
61 EMI_BMEN1,
62 EMI_BMEN2,
63 EMI_BMRW0,
64 EMI_BMRW1
65};
66#define EMI_CONFIG_MX_NR (sizeof(emi_config)/sizeof(unsigned int))
67static unsigned int emi_config_val[EMI_CONFIG_MX_NR];
68
69int MET_BM_Init(void)
70{
71 /*emi*/
72 if (mt_cen_emi_base_get_symbol) {
73 BaseAddrEMI = mt_cen_emi_base_get_symbol();
74 } else {
75 pr_debug("mt_cen_emi_base_get_symbol = NULL\n");
76 PR_BOOTMSG_ONCE("mt_cen_emi_base_get_symbol = NULL\n");
77 BaseAddrEMI = 0;
78 }
79
80 if (BaseAddrEMI == 0) {
81 pr_debug("BaseAddrEMI = 0\n");
82 PR_BOOTMSG_ONCE("BaseAddrEMI = 0\n");
83 return -1;
84 }
85 pr_debug("MET EMI: map emi to %p\n", BaseAddrEMI);
86 PR_BOOTMSG("MET EMI: map emi to %p\n", BaseAddrEMI);
87
88 return 0;
89}
90
91void MET_BM_DeInit(void)
92{
93}
94
95void MET_BM_SaveCfg(void)
96{
97 int i;
98
99 for (i = 0; i < EMI_CONFIG_MX_NR; i++)
100 emi_config_val[i] = emi_readl(IOMEM(ADDR_EMI + emi_config[i]));
101}
102
103void MET_BM_RestoreCfg(void)
104{
105 int i;
106
107 for (i = 0; i < EMI_CONFIG_MX_NR; i++)
108 emi_reg_sync_writel(emi_config_val[i], ADDR_EMI + emi_config[i]);
109}
110
111int MET_BM_SetMonitorCounter(const unsigned int counter_num,
112 const unsigned int master, const unsigned int trans_type)
113{
114 unsigned int value, addr;
115 const unsigned int iMask = (MASK_TRANS_TYPE << 8) | MASK_MASTER;
116
117 if (counter_num < 1 || counter_num > BM_COUNTER_MAX)
118 return BM_ERR_WRONG_REQ;
119
120
121 if (counter_num == 1) {
122 addr = EMI_BMEN;
123 value = (emi_readl(IOMEM(ADDR_EMI + addr)) & ~(iMask << 16)) |
124 ((trans_type & MASK_TRANS_TYPE) << 24) | ((master & MASK_MASTER) << 16);
125 } else {
126 addr = (counter_num <= 3) ? EMI_MSEL : (EMI_MSEL2 + (counter_num / 2 - 2) * 8);
127
128
129 value = emi_readl(IOMEM(ADDR_EMI + addr)) & ~(iMask << ((counter_num % 2) * 16));
130
131
132 value |= (((trans_type & MASK_TRANS_TYPE) << 8) |
133 (master & MASK_MASTER)) << ((counter_num % 2) * 16);
134 }
135
136 emi_reg_sync_writel(value, ADDR_EMI + addr);
137
138 return BM_REQ_OK;
139}
140
141int MET_BM_SetTtypeCounterRW(unsigned int bmrw0_val, unsigned int bmrw1_val)
142{
143
144 unsigned int value_origin;
145
146 value_origin = emi_readl(IOMEM(ADDR_EMI + EMI_BMRW0));
147 MET_TRACE("[MET_EMI_settype1] value_origin: %x\n", value_origin);
148 if (value_origin != bmrw0_val) {
149 emi_reg_sync_writel(bmrw0_val, ADDR_EMI + EMI_BMRW0);
150 MET_TRACE("[MET_EMI_settype1] bmrw0_val: %x, value_origin: %x\n", bmrw0_val,
151 value_origin);
152 }
153
154 value_origin = emi_readl(IOMEM(ADDR_EMI + EMI_BMRW1));
155 MET_TRACE("[MET_EMI_settype2] value_origin: %x\n", value_origin);
156 if (value_origin != bmrw1_val) {
157 emi_reg_sync_writel(bmrw1_val, ADDR_EMI + EMI_BMRW1);
158 MET_TRACE("[MET_EMI_settype2] bmrw0_val: %x, value_origin: %x\n", bmrw1_val,
159 value_origin);
160
161 }
162 return BM_REQ_OK;
163}
164
165int MET_BM_Set_WsctTsct_id_sel(unsigned int counter_num, unsigned int enable)
166{
167 unsigned int value;
168
169 if (counter_num > 3)
170 return BM_ERR_WRONG_REQ;
171
172 value =
173 ((emi_readl(IOMEM(ADDR_EMI + EMI_BMEN2)) & (~(1 << (28 + counter_num)))) |
174 (enable << (28 + counter_num)));
175 emi_reg_sync_writel(value, ADDR_EMI + EMI_BMEN2);
176
177 return BM_REQ_OK;
178}
179
180int MET_BM_SetbusID_En(const unsigned int counter_num,
181 const unsigned int enable)
182{
183 unsigned int value;
184
185 if ((counter_num < 1 || counter_num > BM_COUNTER_MAX) || (enable > 1))
186 return BM_ERR_WRONG_REQ;
187
188 if (enable == 0) {
189
190 value = (emi_readl(IOMEM(ADDR_EMI + EMI_BMEN2))
191 & ~(1 << (counter_num - 1)));
192 } else {
193
194 value = (emi_readl(IOMEM(ADDR_EMI + EMI_BMEN2))
195 | (1 << (counter_num - 1)));
196 }
197 emi_reg_sync_writel(value, ADDR_EMI + EMI_BMEN2);
198
199 return BM_REQ_OK;
200}
201
202int MET_BM_SetbusID(const unsigned int counter_num,
203 const unsigned int id)
204{
205 unsigned int value, addr, shift_num;
206
207 if ((counter_num < 1 || counter_num > BM_COUNTER_MAX))
208 return BM_ERR_WRONG_REQ;
209
210
211 addr = EMI_BMID0 + (counter_num - 1) / 2 * 4;
212 shift_num = ((counter_num - 1) % 2) * 16;
213
214 value = emi_readl(IOMEM(ADDR_EMI + addr)) & ~(EMI_BMID_MASK << shift_num);
215
216
217 if (id <= 0xffff)
218 value |= id << shift_num;
219
220 emi_reg_sync_writel(value, ADDR_EMI + addr);
221
222 return BM_REQ_OK;
223}
224
225int MET_BM_SetUltraHighFilter(const unsigned int counter_num, const unsigned int enable)
226{
227 unsigned int value;
228
229 if ((counter_num < 1 || counter_num > BM_COUNTER_MAX) || (enable > 1))
230 return BM_ERR_WRONG_REQ;
231
232
233 value = (emi_readl(IOMEM(ADDR_EMI + EMI_BMEN1))
234 & ~(1 << (counter_num - 1)))
235 | (enable << (counter_num - 1));
236
237 emi_reg_sync_writel(value, ADDR_EMI + EMI_BMEN1);
238
239 return BM_REQ_OK;
240}
241
242int MET_BM_SetLatencyCounter(unsigned int enable)
243{
244 unsigned int value;
245
246 value = emi_readl(IOMEM(ADDR_EMI + EMI_BMEN2)) & ~(0x3 << 24);
247 if (enable == 1)
248 value |= (0x2 << 24);
249
250 emi_reg_sync_writel(value, ADDR_EMI + EMI_BMEN2);
251
252 return BM_REQ_OK;
253}