dhd: rename 100.10.315.x to 100.10.545.x
[GitHub/LineageOS/G12/android_hardware_amlogic_kernel-modules_dhd-driver.git] / bcmdhd.100.10.545.x / hndmem.c
CommitLineData
d2839953
RC
1/*
2 * Utility routines for configuring different memories in Broadcom chips.
3 *
965f77c4 4 * Copyright (C) 1999-2019, Broadcom.
d2839953
RC
5 *
6 * Unless you and Broadcom execute a separate written software license
7 * agreement governing use of this software, this software is licensed to you
8 * under the terms of the GNU General Public License version 2 (the "GPL"),
9 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10 * following added to such license:
11 *
12 * As a special exception, the copyright holders of this software give you
13 * permission to link this software with independent modules, and to copy and
14 * distribute the resulting executable under terms of your choice, provided that
15 * you also meet, for each linked independent module, the terms and conditions of
16 * the license of that module. An independent module is a module which is not
17 * derived from this software. The special exception does not apply to any
18 * modifications of the software.
19 *
20 * Notwithstanding the above, under no circumstances may you combine this
21 * software in any way with any other Broadcom software provided under a license
22 * other than the GPL, without Broadcom's express prior written consent.
23 *
24 *
25 * <<Broadcom-WL-IPTag/Open:>>
26 *
27 * $Id: $
28 */
29
30#include <typedefs.h>
31#include <sbchipc.h>
32#include <hndsoc.h>
33#include <bcmdevs.h>
34#include <osl.h>
35#include <sbgci.h>
36#include <siutils.h>
37#include <bcmutils.h>
38#include <hndmem.h>
39
40#define IS_MEMTYPE_VALID(mem) ((mem >= MEM_SOCRAM) && (mem < MEM_MAX))
41#define IS_MEMCONFIG_VALID(cfg) ((cfg >= PDA_CONFIG_CLEAR) && (cfg < PDA_CONFIG_MAX))
42
43/* Returns the number of banks in a given memory */
44int
45hndmem_num_banks(si_t *sih, int mem)
46{
47 uint32 savecore, mem_info;
48 int num_banks = 0;
49 gciregs_t *gciregs;
50 osl_t *osh = si_osh(sih);
51
52 if (!IS_MEMTYPE_VALID(mem)) {
53 goto exit;
54 }
55
56 savecore = si_coreidx(sih);
57
58 /* TODO: Check whether SOCRAM core is present or not. If not, bail out */
59 /* In future we need to add code for TCM based chips as well */
60 if (!si_setcore(sih, SOCRAM_CORE_ID, 0)) {
61 goto exit;
62 }
63
64 if (sih->gcirev >= 9) {
65 gciregs = si_setcore(sih, GCI_CORE_ID, 0);
66
67 mem_info = R_REG(osh, &gciregs->wlan_mem_info);
68
69 switch (mem) {
70 case MEM_SOCRAM:
71 num_banks = (mem_info & WLAN_MEM_INFO_REG_NUMSOCRAMBANKS_MASK) >>
72 WLAN_MEM_INFO_REG_NUMSOCRAMBANKS_SHIFT;
73 break;
74 case MEM_BM:
75 num_banks = (mem_info & WLAN_MEM_INFO_REG_NUMD11MACBM_MASK) >>
76 WLAN_MEM_INFO_REG_NUMD11MACBM_SHIFT;
77 break;
78 case MEM_UCM:
79 num_banks = (mem_info & WLAN_MEM_INFO_REG_NUMD11MACUCM_MASK) >>
80 WLAN_MEM_INFO_REG_NUMD11MACUCM_SHIFT;
81 break;
82 case MEM_SHM:
83 num_banks = (mem_info & WLAN_MEM_INFO_REG_NUMD11MACSHM_MASK) >>
84 WLAN_MEM_INFO_REG_NUMD11MACSHM_SHIFT;
85 break;
86 default:
87 ASSERT(0);
88 break;
89 }
90 } else {
91 /* TODO: Figure out bank information using SOCRAM registers */
92 }
93
94 si_setcoreidx(sih, savecore);
95exit:
96 return num_banks;
97}
98
99/* Returns the size of a give bank in a given memory */
100int
101hndmem_bank_size(si_t *sih, hndmem_type_t mem, int bank_num)
102{
103 uint32 savecore, bank_info, reg_data;
104 int bank_sz = 0;
105 gciregs_t *gciregs;
106 osl_t *osh = si_osh(sih);
107
108 if (!IS_MEMTYPE_VALID(mem)) {
109 goto exit;
110 }
111
112 savecore = si_coreidx(sih);
113
114 /* TODO: Check whether SOCRAM core is present or not. If not, bail out */
115 /* In future we need to add code for TCM based chips as well */
116 if (!si_setcore(sih, SOCRAM_CORE_ID, 0)) {
117 goto exit;
118 }
119
120 if (sih->gcirev >= 9) {
121 gciregs = si_setcore(sih, GCI_CORE_ID, 0);
122
123 reg_data = ((mem &
124 GCI_INDIRECT_ADDRESS_REG_GPIOINDEX_MASK) <<
125 GCI_INDIRECT_ADDRESS_REG_GPIOINDEX_SHIFT) |
126 ((bank_num & GCI_INDIRECT_ADDRESS_REG_REGINDEX_MASK)
127 << GCI_INDIRECT_ADDRESS_REG_REGINDEX_SHIFT);
128 W_REG(osh, &gciregs->gci_indirect_addr, reg_data);
129
130 bank_info = R_REG(osh, &gciregs->wlan_bankxinfo);
131 bank_sz = (bank_info & WLAN_BANKXINFO_BANK_SIZE_MASK) >>
132 WLAN_BANKXINFO_BANK_SIZE_SHIFT;
133 } else {
134 /* TODO: Figure out bank size using SOCRAM registers */
135 }
136
137 si_setcoreidx(sih, savecore);
138exit:
139 return bank_sz;
140}
141
142/* Returns the start address of given memory */
143uint32
144hndmem_mem_base(si_t *sih, hndmem_type_t mem)
145{
146 uint32 savecore, base_addr = 0;
147
148 /* Currently only support of SOCRAM is available in hardware */
149 if (mem != MEM_SOCRAM) {
150 goto exit;
151 }
152
153 savecore = si_coreidx(sih);
154
155 if (si_setcore(sih, SOCRAM_CORE_ID, 0))
156 {
157 base_addr = si_get_slaveport_addr(sih, CORE_SLAVE_PORT_1,
158 CORE_BASE_ADDR_0, SOCRAM_CORE_ID, 0);
159 } else {
160 /* TODO: Add code to get the base address of TCM */
161 base_addr = 0;
162 }
163
164 si_setcoreidx(sih, savecore);
165
166exit:
167 return base_addr;
168}
169
170#ifdef BCMDEBUG
171char *hndmem_type_str[] =
172 {
173 "SOCRAM", /* 0 */
174 "BM", /* 1 */
175 "UCM", /* 2 */
176 "SHM", /* 3 */
177 };
178
179/* Dumps the complete memory information */
180void
181hndmem_dump_meminfo_all(si_t *sih)
182{
183 int mem, bank, bank_cnt, bank_sz;
184
185 for (mem = MEM_SOCRAM; mem < MEM_MAX; mem++) {
186 bank_cnt = hndmem_num_banks(sih, mem);
187
188 printf("\nMemtype: %s\n", hndmem_type_str[mem]);
189 for (bank = 0; bank < bank_cnt; bank++) {
190 bank_sz = hndmem_bank_size(sih, mem, bank);
191 printf("Bank-%d: %d KB\n", bank, bank_sz);
192 }
193 }
194}
195#endif /* BCMDEBUG */
196
197/* Configures the Sleep PDA for a particular bank for a given memory type */
198int
199hndmem_sleeppda_bank_config(si_t *sih, hndmem_type_t mem, int bank_num,
200 hndmem_config_t config, uint32 pda)
201{
202 uint32 savecore, reg_data;
203 gciregs_t *gciregs;
204 int err = BCME_OK;
205 osl_t *osh = si_osh(sih);
206
207 /* TODO: Check whether SOCRAM core is present or not. If not, bail out */
208 /* In future we need to add code for TCM based chips as well */
209 if (!si_setcore(sih, SOCRAM_CORE_ID, 0)) {
210 err = BCME_UNSUPPORTED;
211 goto exit;
212 }
213
214 /* Sleep PDA is supported only by GCI rev >= 9 */
215 if (sih->gcirev < 9) {
216 err = BCME_UNSUPPORTED;
217 goto exit;
218 }
219
220 if (!IS_MEMTYPE_VALID(mem)) {
221 err = BCME_BADOPTION;
222 goto exit;
223 }
224
225 if (!IS_MEMCONFIG_VALID(config)) {
226 err = BCME_BADOPTION;
227 goto exit;
228 }
229
230 savecore = si_coreidx(sih);
231 gciregs = si_setcore(sih, GCI_CORE_ID, 0);
232
233 reg_data = ((mem &
234 GCI_INDIRECT_ADDRESS_REG_GPIOINDEX_MASK) <<
235 GCI_INDIRECT_ADDRESS_REG_GPIOINDEX_SHIFT) |
236 ((bank_num & GCI_INDIRECT_ADDRESS_REG_REGINDEX_MASK)
237 << GCI_INDIRECT_ADDRESS_REG_REGINDEX_SHIFT);
238
239 W_REG(osh, &gciregs->gci_indirect_addr, reg_data);
240
241 if (config == PDA_CONFIG_SET_PARTIAL) {
242 W_REG(osh, &gciregs->wlan_bankxsleeppda, pda);
243 W_REG(osh, &gciregs->wlan_bankxkill, 0);
244 }
245 else if (config == PDA_CONFIG_SET_FULL) {
246 W_REG(osh, &gciregs->wlan_bankxsleeppda, WLAN_BANKX_SLEEPPDA_REG_SLEEPPDA_MASK);
247 W_REG(osh, &gciregs->wlan_bankxkill, WLAN_BANKX_PKILL_REG_SLEEPPDA_MASK);
248 } else {
249 W_REG(osh, &gciregs->wlan_bankxsleeppda, 0);
250 W_REG(osh, &gciregs->wlan_bankxkill, 0);
251 }
252
253 si_setcoreidx(sih, savecore);
254
255exit:
256 return err;
257}
258
259/* Configures the Active PDA for a particular bank for a given memory type */
260int
261hndmem_activepda_bank_config(si_t *sih, hndmem_type_t mem,
262 int bank_num, hndmem_config_t config, uint32 pda)
263{
264 uint32 savecore, reg_data;
265 gciregs_t *gciregs;
266 int err = BCME_OK;
267 osl_t *osh = si_osh(sih);
268
269 if (!IS_MEMTYPE_VALID(mem)) {
270 err = BCME_BADOPTION;
271 goto exit;
272 }
273
274 if (!IS_MEMCONFIG_VALID(config)) {
275 err = BCME_BADOPTION;
276 goto exit;
277 }
278
279 savecore = si_coreidx(sih);
280
281 /* TODO: Check whether SOCRAM core is present or not. If not, bail out */
282 /* In future we need to add code for TCM based chips as well */
283 if (!si_setcore(sih, SOCRAM_CORE_ID, 0)) {
284 err = BCME_UNSUPPORTED;
285 goto exit;
286 }
287
288 if (sih->gcirev >= 9) {
289 gciregs = si_setcore(sih, GCI_CORE_ID, 0);
290
291 reg_data = ((mem &
292 GCI_INDIRECT_ADDRESS_REG_GPIOINDEX_MASK) <<
293 GCI_INDIRECT_ADDRESS_REG_GPIOINDEX_SHIFT) |
294 ((bank_num & GCI_INDIRECT_ADDRESS_REG_REGINDEX_MASK)
295 << GCI_INDIRECT_ADDRESS_REG_REGINDEX_SHIFT);
296
297 W_REG(osh, &gciregs->gci_indirect_addr, reg_data);
298
299 if (config == PDA_CONFIG_SET_PARTIAL) {
300 W_REG(osh, &gciregs->wlan_bankxactivepda, pda);
301 }
302 else if (config == PDA_CONFIG_SET_FULL) {
303 W_REG(osh, &gciregs->wlan_bankxactivepda,
304 WLAN_BANKX_SLEEPPDA_REG_SLEEPPDA_MASK);
305 } else {
306 W_REG(osh, &gciregs->wlan_bankxactivepda, 0);
307 }
308 } else {
309 /* TODO: Configure SOCRAM PDA using SOCRAM registers */
310 err = BCME_UNSUPPORTED;
311 }
312
313 si_setcoreidx(sih, savecore);
314
315exit:
316 return err;
317}
318
319/* Configures the Sleep PDA for all the banks for a given memory type */
320int
321hndmem_sleeppda_config(si_t *sih, hndmem_type_t mem, hndmem_config_t config)
322{
323 int bank;
324 int num_banks = hndmem_num_banks(sih, mem);
325 int err = BCME_OK;
326
327 /* Sleep PDA is supported only by GCI rev >= 9 */
328 if (sih->gcirev < 9) {
329 err = BCME_UNSUPPORTED;
330 goto exit;
331 }
332
333 if (!IS_MEMTYPE_VALID(mem)) {
334 err = BCME_BADOPTION;
335 goto exit;
336 }
337
338 if (!IS_MEMCONFIG_VALID(config)) {
339 err = BCME_BADOPTION;
340 goto exit;
341 }
342
343 for (bank = 0; bank < num_banks; bank++)
344 {
345 err = hndmem_sleeppda_bank_config(sih, mem, bank, config, 0);
346 }
347
348exit:
349 return err;
350}
351
352/* Configures the Active PDA for all the banks for a given memory type */
353int
354hndmem_activepda_config(si_t *sih, hndmem_type_t mem, hndmem_config_t config)
355{
356 int bank;
357 int num_banks = hndmem_num_banks(sih, mem);
358 int err = BCME_OK;
359
360 if (!IS_MEMTYPE_VALID(mem)) {
361 err = BCME_BADOPTION;
362 goto exit;
363 }
364
365 if (!IS_MEMCONFIG_VALID(config)) {
366 err = BCME_BADOPTION;
367 goto exit;
368 }
369
370 for (bank = 0; bank < num_banks; bank++)
371 {
372 err = hndmem_activepda_bank_config(sih, mem, bank, config, 0);
373 }
374
375exit:
376 return err;
377}
378
379/* Turn off/on all the possible banks in a given memory range.
380 * Currently this works only for SOCRAM as this is restricted by HW.
381 */
382int
383hndmem_activepda_mem_config(si_t *sih, hndmem_type_t mem, uint32 mem_start,
384 uint32 size, hndmem_config_t config)
385{
386 int bank, bank_sz, num_banks;
387 int mem_end;
388 int bank_start_addr, bank_end_addr;
389 int err = BCME_OK;
390
391 /* We can get bank size for only SOCRAM/TCM only. Support is not avilable
392 * for other memories (BM, UCM and SHM)
393 */
394 if (mem != MEM_SOCRAM) {
395 err = BCME_UNSUPPORTED;
396 goto exit;
397 }
398
399 num_banks = hndmem_num_banks(sih, mem);
400 bank_start_addr = hndmem_mem_base(sih, mem);
401 mem_end = mem_start + size - 1;
402
403 for (bank = 0; bank < num_banks; bank++)
404 {
405 /* Bank size is spcified in bankXinfo register in terms on KBs */
406 bank_sz = 1024 * hndmem_bank_size(sih, mem, bank);
407
408 bank_end_addr = bank_start_addr + bank_sz - 1;
409
410 if (config == PDA_CONFIG_SET_FULL) {
411 /* Check if the bank is completely overlapping with the given mem range */
412 if ((mem_start <= bank_start_addr) && (mem_end >= bank_end_addr)) {
413 err = hndmem_activepda_bank_config(sih, mem, bank, config, 0);
414 }
415 } else {
416 /* Check if the bank is completely overlaped with the given mem range */
417 if (((mem_start <= bank_start_addr) && (mem_end >= bank_end_addr)) ||
418 /* Check if the bank is partially overlaped with the given range */
419 ((mem_start <= bank_end_addr) && (mem_end >= bank_start_addr))) {
420 err = hndmem_activepda_bank_config(sih, mem, bank, config, 0);
421 }
422 }
423
424 bank_start_addr += bank_sz;
425 }
426
427exit:
428 return err;
429}