Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_aic.c
48525 views
1
/*
2
* Copyright (c) 2013 Qualcomm Atheros, Inc.
3
*
4
* Permission to use, copy, modify, and/or distribute this software for any
5
* purpose with or without fee is hereby granted, provided that the above
6
* copyright notice and this permission notice appear in all copies.
7
*
8
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14
* PERFORMANCE OF THIS SOFTWARE.
15
*/
16
17
18
#include "opt_ah.h"
19
20
#ifdef AH_SUPPORT_AR9300
21
22
#include "ah.h"
23
#include "ah_internal.h"
24
25
#include "ar9300/ar9300.h"
26
#include "ar9300/ar9300reg.h"
27
#include "ar9300/ar9300phy.h"
28
29
#if ATH_SUPPORT_AIC
30
31
#define ATH_AIC_TEST_PATTERN 1
32
33
struct ath_aic_sram_info {
34
HAL_BOOL valid;
35
u_int8_t rot_quad_att_db;
36
HAL_BOOL vga_quad_sign;
37
u_int8_t rot_dir_att_db;
38
HAL_BOOL vga_dir_sign;
39
u_int8_t com_att_6db;
40
};
41
42
struct ath_aic_out_info {
43
int16_t dir_path_gain_lin;
44
int16_t quad_path_gain_lin;
45
struct ath_aic_sram_info sram;
46
};
47
48
#define ATH_AIC_MAX_COM_ATT_DB_TABLE 6
49
#define ATH_AIC_MAX_AIC_LIN_TABLE 69
50
#define ATH_AIC_MIN_ROT_DIR_ATT_DB 0
51
#define ATH_AIC_MIN_ROT_QUAD_ATT_DB 0
52
#define ATH_AIC_MAX_ROT_DIR_ATT_DB 37
53
#define ATH_AIC_MAX_ROT_QUAD_ATT_DB 37
54
#define ATH_AIC_SRAM_AUTO_INCREMENT 0x80000000
55
#define ATH_AIC_SRAM_GAIN_TABLE_OFFSET 0x280
56
#define ATH_AIC_SRAM_CAL_OFFSET 0x140
57
#define ATH_AIC_MAX_CAL_COUNT 5
58
#define ATH_AIC_MEAS_MAG_THRESH 20
59
#define ATH_AIC_BT_JUPITER_CTRL 0x66820
60
#define ATH_AIC_BT_AIC_ENABLE 0x02
61
62
63
static const u_int8_t com_att_db_table[ATH_AIC_MAX_COM_ATT_DB_TABLE] = {
64
0, 3, 9, 15, 21, 27};
65
66
static const u_int16_t aic_lin_table[ATH_AIC_MAX_AIC_LIN_TABLE] = {
67
8191, 7300, 6506, 5799, 5168, 4606, 4105, 3659,
68
3261, 2906, 2590, 2309, 2057, 1834, 1634, 1457,
69
1298, 1157, 1031, 919, 819, 730, 651, 580,
70
517, 461, 411, 366, 326, 291, 259, 231,
71
206, 183, 163, 146, 130, 116, 103, 92,
72
82, 73, 65, 58, 52, 46, 41, 37,
73
33, 29, 26, 23, 21, 18, 16, 15,
74
13, 12, 10, 9, 8, 7, 7, 6,
75
5, 5, 4, 4, 3};
76
77
#if ATH_AIC_TEST_PATTERN
78
static const u_int32_t aic_test_pattern[ATH_AIC_MAX_BT_CHANNEL] = {
79
0x00000, // 0
80
0x00000,
81
0x00000,
82
0x00000,
83
0x00000,
84
0x00000,
85
0x00000,
86
0x00000,
87
0x00000,
88
0x1918d,
89
0x1938d, // 10
90
0x00000,
91
0x1978d,
92
0x19e8d,
93
0x00000,
94
0x00000,
95
0x00000,
96
0x00000,
97
0x00000,
98
0x00000,
99
0x00000, // 20
100
0x00000,
101
0x00000,
102
0x1ce8f,
103
0x00000,
104
0x00000,
105
0x00000,
106
0x00000,
107
0x1ca93,
108
0x1c995,
109
0x00000, // 30
110
0x1c897,
111
0x1c899,
112
0x00000,
113
0x00000,
114
0x1c79f,
115
0x00000,
116
0x1c7a5,
117
0x1c6ab,
118
0x00000,
119
0x00000, // 40
120
0x00000,
121
0x00000,
122
0x1c63f,
123
0x00000,
124
0x1c52b,
125
0x1c525,
126
0x1c523,
127
0x00000,
128
0x00000,
129
0x00000, // 50
130
0x00000,
131
0x00000,
132
0x1c617,
133
0x00000,
134
0x1c615,
135
0x1c613,
136
0x00000,
137
0x00000,
138
0x00000,
139
0x00000, // 60
140
0x1c80f,
141
0x1c90f,
142
0x1c90f,
143
0x1ca0f,
144
0x1ca0d,
145
0x1cb0d,
146
0x00000,
147
0x00000,
148
0x00000,
149
0x00000, // 70
150
0x1d00d,
151
0x00000,
152
0x00000,
153
0x00000,
154
0x00000,
155
0x00000,
156
0x00000,
157
0x00000
158
};
159
#endif
160
161
static void
162
ar9300_aic_gain_table(struct ath_hal *ah)
163
{
164
u_int32_t aic_atten_word[19], i;
165
166
/* Program gain table */
167
aic_atten_word[0] = (0x1 & 0xf)<<14 | (0x1f & 0x1f)<<9 | (0x0 & 0xf)<<5 |
168
(0x1f & 0x1f); // -01 dB: 4'd1, 5'd31, 00 dB: 4'd0, 5'd31;
169
aic_atten_word[1] = (0x3 & 0xf)<<14 | (0x1f & 0x1f)<<9 | (0x2 & 0xf)<<5 |
170
(0x1f & 0x1f); // -03 dB: 4'd3, 5'd31, -02 dB: 4'd2, 5'd31;
171
aic_atten_word[2] = (0x5 & 0xf)<<14 | (0x1f & 0x1f)<<9 | (0x4 & 0xf)<<5 |
172
(0x1f & 0x1f); // -05 dB: 4'd5, 5'd31, -04 dB: 4'd4, 5'd31;
173
aic_atten_word[3] = (0x1 & 0xf)<<14 | (0x1e & 0x1f)<<9 | (0x0 & 0xf)<<5 |
174
(0x1e & 0x1f); // -07 dB: 4'd1, 5'd30, -06 dB: 4'd0, 5'd30;
175
aic_atten_word[4] = (0x3 & 0xf)<<14 | (0x1e & 0x1f)<<9 | (0x2 & 0xf)<<5 |
176
(0x1e & 0x1f); // -09 dB: 4'd3, 5'd30, -08 dB: 4'd2, 5'd30;
177
aic_atten_word[5] = (0x5 & 0xf)<<14 | (0x1e & 0x1f)<<9 | (0x4 & 0xf)<<5 |
178
(0x1e & 0x1f); // -11 dB: 4'd5, 5'd30, -10 dB: 4'd4, 5'd30;
179
aic_atten_word[6] = (0x1 & 0xf)<<14 | (0xf & 0x1f)<<9 | (0x0 & 0xf)<<5 |
180
(0xf & 0x1f); // -13 dB: 4'd1, 5'd15, -12 dB: 4'd0, 5'd15;
181
aic_atten_word[7] = (0x3 & 0xf)<<14 | (0xf & 0x1f)<<9 | (0x2 & 0xf)<<5 |
182
(0xf & 0x1f); // -15 dB: 4'd3, 5'd15, -14 dB: 4'd2, 5'd15;
183
aic_atten_word[8] = (0x5 & 0xf)<<14 | (0xf & 0x1f)<<9 | (0x4 & 0xf)<<5 |
184
(0xf & 0x1f); // -17 dB: 4'd5, 5'd15, -16 dB: 4'd4, 5'd15;
185
aic_atten_word[9] = (0x1 & 0xf)<<14 | (0x7 & 0x1f)<<9 | (0x0 & 0xf)<<5 |
186
(0x7 & 0x1f); // -19 dB: 4'd1, 5'd07, -18 dB: 4'd0, 5'd07;
187
aic_atten_word[10] =(0x3 & 0xf)<<14 | (0x7 & 0x1f)<<9 | (0x2 & 0xf)<<5 |
188
(0x7 & 0x1f); // -21 dB: 4'd3, 5'd07, -20 dB: 4'd2, 5'd07;
189
aic_atten_word[11] =(0x5 & 0xf)<<14 | (0x7 & 0x1f)<<9 | (0x4 & 0xf)<<5 |
190
(0x7 & 0x1f); // -23 dB: 4'd5, 5'd07, -22 dB: 4'd4, 5'd07;
191
aic_atten_word[12] =(0x7 & 0xf)<<14 | (0x7 & 0x1f)<<9 | (0x6 & 0xf)<<5 |
192
(0x7 & 0x1f); // -25 dB: 4'd7, 5'd07, -24 dB: 4'd6, 5'd07;
193
aic_atten_word[13] =(0x3 & 0xf)<<14 | (0x3 & 0x1f)<<9 | (0x2 & 0xf)<<5 |
194
(0x3 & 0x1f); // -27 dB: 4'd3, 5'd03, -26 dB: 4'd2, 5'd03;
195
aic_atten_word[14] =(0x5 & 0xf)<<14 | (0x3 & 0x1f)<<9 | (0x4 & 0xf)<<5 |
196
(0x3 & 0x1f); // -29 dB: 4'd5, 5'd03, -28 dB: 4'd4, 5'd03;
197
aic_atten_word[15] =(0x1 & 0xf)<<14 | (0x1 & 0x1f)<<9 | (0x0 & 0xf)<<5 |
198
(0x1 & 0x1f); // -31 dB: 4'd1, 5'd01, -30 dB: 4'd0, 5'd01;
199
aic_atten_word[16] =(0x3 & 0xf)<<14 | (0x1 & 0x1f)<<9 | (0x2 & 0xf)<<5 |
200
(0x1 & 0x1f); // -33 dB: 4'd3, 5'd01, -32 dB: 4'd2, 5'd01;
201
aic_atten_word[17] =(0x5 & 0xf)<<14 | (0x1 & 0x1f)<<9 | (0x4 & 0xf)<<5 |
202
(0x1 & 0x1f); // -35 dB: 4'd5, 5'd01, -34 dB: 4'd4, 5'd01;
203
aic_atten_word[18] =(0x7 & 0xf)<<14 | (0x1 & 0x1f)<<9 | (0x6 & 0xf)<<5 |
204
(0x1 & 0x1f); // -37 dB: 4'd7, 5'd01, -36 dB: 4'd6, 5'd01;
205
206
/* Write to Gain table with auto increment enabled. */
207
OS_REG_WRITE(ah, (AR_PHY_AIC_SRAM_ADDR_B0 + 0x3000),
208
(ATH_AIC_SRAM_AUTO_INCREMENT |
209
ATH_AIC_SRAM_GAIN_TABLE_OFFSET));
210
211
for (i = 0; i < 19; i++) {
212
OS_REG_WRITE(ah, (AR_PHY_AIC_SRAM_DATA_B0 + 0x3000),
213
aic_atten_word[i]);
214
}
215
216
}
217
218
static int16_t
219
ar9300_aic_find_valid (struct ath_aic_sram_info *cal_sram,
220
HAL_BOOL dir,
221
u_int8_t index)
222
{
223
int16_t i;
224
225
if (dir) {
226
/* search forward */
227
for (i = index + 1; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
228
if (cal_sram[i].valid) {
229
break;
230
}
231
}
232
}
233
else {
234
/* search backword */
235
for (i = index - 1; i >= 0; i--) {
236
if (cal_sram[i].valid) {
237
break;
238
}
239
}
240
}
241
if ((i >= ATH_AIC_MAX_BT_CHANNEL) || (i < 0)) {
242
i = -1;
243
}
244
245
return i;
246
}
247
248
static int16_t
249
ar9300_aic_find_index (u_int8_t type, int16_t value)
250
{
251
int16_t i = -1;
252
253
/*
254
* type 0: aic_lin_table, 1: com_att_db_table
255
*/
256
257
if (type == 0) {
258
/* Find in aic_lin_table */
259
for (i = ATH_AIC_MAX_AIC_LIN_TABLE - 1; i >= 0; i--) {
260
if (aic_lin_table[i] >= value) {
261
break;
262
}
263
}
264
}
265
else if (type == 1) {
266
/* find in com_att_db_table */
267
for (i = 0; i < ATH_AIC_MAX_COM_ATT_DB_TABLE; i++) {
268
if (com_att_db_table[i] > value) {
269
i--;
270
break;
271
}
272
}
273
if (i >= ATH_AIC_MAX_COM_ATT_DB_TABLE) {
274
i = -1;
275
}
276
}
277
278
return i;
279
}
280
281
static HAL_BOOL
282
ar9300_aic_cal_post_process (struct ath_hal *ah)
283
{
284
struct ath_hal_9300 *ahp = AH9300(ah);
285
struct ath_aic_sram_info cal_sram[ATH_AIC_MAX_BT_CHANNEL];
286
struct ath_aic_out_info aic_sram[ATH_AIC_MAX_BT_CHANNEL];
287
u_int32_t dir_path_gain_idx, quad_path_gain_idx, value;
288
u_int32_t fixed_com_att_db;
289
int8_t dir_path_sign, quad_path_sign;
290
int16_t i;
291
HAL_BOOL ret = AH_TRUE;
292
293
/* Read CAL_SRAM and get valid values. */
294
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) CAL_SRAM:\n");
295
296
for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
297
OS_REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1,
298
(ATH_AIC_SRAM_CAL_OFFSET + i*4));
299
#if ATH_AIC_TEST_PATTERN
300
value = aic_test_pattern[i];
301
#else
302
value = OS_REG_READ(ah, AR_PHY_AIC_SRAM_DATA_B1);
303
#endif
304
cal_sram[i].valid = MS(value, AR_PHY_AIC_SRAM_VALID);
305
cal_sram[i].rot_quad_att_db = MS(value,
306
AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB);
307
cal_sram[i].vga_quad_sign = MS(value, AR_PHY_AIC_SRAM_VGA_QUAD_SIGN);
308
cal_sram[i].rot_dir_att_db = MS(value, AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB);
309
cal_sram[i].vga_dir_sign = MS(value, AR_PHY_AIC_SRAM_VGA_DIR_SIGN);
310
cal_sram[i].com_att_6db = MS(value, AR_PHY_AIC_SRAM_COM_ATT_6DB);
311
312
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
313
"(AIC) %2d %2d %2d %2d %2d %2d %2d 0x%05x\n",
314
i, cal_sram[i].vga_quad_sign,
315
cal_sram[i].vga_dir_sign,
316
cal_sram[i].rot_dir_att_db,
317
cal_sram[i].rot_quad_att_db,
318
cal_sram[i].com_att_6db,
319
cal_sram[i].valid,
320
value);
321
322
if (cal_sram[i].valid) {
323
dir_path_gain_idx = cal_sram[i].rot_dir_att_db +
324
com_att_db_table[cal_sram[i].com_att_6db];
325
quad_path_gain_idx = cal_sram[i].rot_quad_att_db +
326
com_att_db_table[cal_sram[i].com_att_6db];
327
dir_path_sign = (cal_sram[i].vga_dir_sign) ? 1 : -1;
328
quad_path_sign = (cal_sram[i].vga_quad_sign) ? 1 : -1;
329
aic_sram[i].dir_path_gain_lin = dir_path_sign *
330
aic_lin_table[dir_path_gain_idx];
331
aic_sram[i].quad_path_gain_lin = quad_path_sign *
332
aic_lin_table[quad_path_gain_idx];
333
}
334
}
335
336
for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
337
int16_t start_idx, end_idx;
338
339
if (cal_sram[i].valid) {
340
continue;
341
}
342
343
start_idx = ar9300_aic_find_valid(cal_sram, 0, i);
344
end_idx = ar9300_aic_find_valid(cal_sram, 1, i);
345
346
if (start_idx < 0)
347
{
348
/* extrapolation */
349
start_idx = end_idx;
350
end_idx = ar9300_aic_find_valid(cal_sram, 1, start_idx);
351
352
if (end_idx < 0) {
353
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
354
"(AIC) Error (1): i = %d, start_idx = %d \n",
355
i, start_idx);
356
ret = AH_FALSE;
357
break;
358
}
359
aic_sram[i].dir_path_gain_lin =
360
((aic_sram[start_idx].dir_path_gain_lin -
361
aic_sram[end_idx].dir_path_gain_lin) *
362
(start_idx - i) + ((end_idx - i) >> 1)) /
363
(end_idx - i) +
364
aic_sram[start_idx].dir_path_gain_lin;
365
aic_sram[i].quad_path_gain_lin =
366
((aic_sram[start_idx].quad_path_gain_lin -
367
aic_sram[end_idx].quad_path_gain_lin) *
368
(start_idx - i) + ((end_idx - i) >> 1)) /
369
(end_idx - i) +
370
aic_sram[start_idx].quad_path_gain_lin;
371
}
372
if (end_idx < 0)
373
{
374
/* extrapolation */
375
end_idx = ar9300_aic_find_valid(cal_sram, 0, start_idx);
376
377
if (end_idx < 0) {
378
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
379
"(AIC) Error (2): i = %d, start_idx = %d\n",
380
i, start_idx);
381
ret = AH_FALSE;
382
break;
383
}
384
aic_sram[i].dir_path_gain_lin =
385
((aic_sram[start_idx].dir_path_gain_lin -
386
aic_sram[end_idx].dir_path_gain_lin) *
387
(i - start_idx) + ((start_idx - end_idx) >> 1)) /
388
(start_idx - end_idx) +
389
aic_sram[start_idx].dir_path_gain_lin;
390
aic_sram[i].quad_path_gain_lin =
391
((aic_sram[start_idx].quad_path_gain_lin -
392
aic_sram[end_idx].quad_path_gain_lin) *
393
(i - start_idx) + ((start_idx - end_idx) >> 1)) /
394
(start_idx - end_idx) +
395
aic_sram[start_idx].quad_path_gain_lin;
396
397
}
398
else {
399
/* interpolation */
400
aic_sram[i].dir_path_gain_lin =
401
(((end_idx - i) * aic_sram[start_idx].dir_path_gain_lin) +
402
((i - start_idx) * aic_sram[end_idx].dir_path_gain_lin) +
403
((end_idx - start_idx) >> 1)) /
404
(end_idx - start_idx);
405
aic_sram[i].quad_path_gain_lin =
406
(((end_idx - i) * aic_sram[start_idx].quad_path_gain_lin) +
407
((i - start_idx) * aic_sram[end_idx].quad_path_gain_lin) +
408
((end_idx - start_idx) >> 1))/
409
(end_idx - start_idx);
410
}
411
}
412
413
/* From dir/quad_path_gain_lin to sram. */
414
i = ar9300_aic_find_valid(cal_sram, 1, 0);
415
if (i < 0) {
416
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
417
"(AIC) Error (3): can't find valid. Force it to 0.\n");
418
i = 0;
419
ret = AH_FALSE;
420
}
421
fixed_com_att_db = com_att_db_table[cal_sram[i].com_att_6db];
422
423
for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
424
int16_t rot_dir_path_att_db, rot_quad_path_att_db;
425
426
aic_sram[i].sram.vga_dir_sign = (aic_sram[i].dir_path_gain_lin >= 0)
427
? 1 : 0;
428
aic_sram[i].sram.vga_quad_sign= (aic_sram[i].quad_path_gain_lin >= 0)
429
? 1 : 0;
430
431
rot_dir_path_att_db =
432
ar9300_aic_find_index(0, abs(aic_sram[i].dir_path_gain_lin)) -
433
fixed_com_att_db;
434
rot_quad_path_att_db =
435
ar9300_aic_find_index(0, abs(aic_sram[i].quad_path_gain_lin)) -
436
fixed_com_att_db;
437
438
aic_sram[i].sram.com_att_6db = ar9300_aic_find_index(1,
439
fixed_com_att_db);
440
441
aic_sram[i].sram.valid = 1;
442
aic_sram[i].sram.rot_dir_att_db =
443
MIN(MAX(rot_dir_path_att_db, ATH_AIC_MIN_ROT_DIR_ATT_DB),
444
ATH_AIC_MAX_ROT_DIR_ATT_DB);
445
aic_sram[i].sram.rot_quad_att_db =
446
MIN(MAX(rot_quad_path_att_db, ATH_AIC_MIN_ROT_QUAD_ATT_DB),
447
ATH_AIC_MAX_ROT_QUAD_ATT_DB);
448
}
449
450
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Post processing results:\n");
451
452
for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
453
ahp->ah_aic_sram[i] = (SM(aic_sram[i].sram.vga_dir_sign,
454
AR_PHY_AIC_SRAM_VGA_DIR_SIGN) |
455
SM(aic_sram[i].sram.vga_quad_sign,
456
AR_PHY_AIC_SRAM_VGA_QUAD_SIGN) |
457
SM(aic_sram[i].sram.com_att_6db,
458
AR_PHY_AIC_SRAM_COM_ATT_6DB) |
459
SM(aic_sram[i].sram.valid,
460
AR_PHY_AIC_SRAM_VALID) |
461
SM(aic_sram[i].sram.rot_dir_att_db,
462
AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB) |
463
SM(aic_sram[i].sram.rot_quad_att_db,
464
AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB));
465
466
467
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
468
"(AIC) ch%02d 0x%05x %2d %2d %2d %2d %2d %2d %d %d\n",
469
i,
470
ahp->ah_aic_sram[i],
471
aic_sram[i].sram.vga_quad_sign,
472
aic_sram[i].sram.vga_dir_sign,
473
aic_sram[i].sram.rot_dir_att_db,
474
aic_sram[i].sram.rot_quad_att_db,
475
aic_sram[i].sram.com_att_6db,
476
aic_sram[i].sram.valid,
477
aic_sram[i].dir_path_gain_lin,
478
aic_sram[i].quad_path_gain_lin);
479
}
480
481
return ret;
482
}
483
484
u_int32_t
485
ar9300_aic_calibration(struct ath_hal *ah)
486
{
487
u_int32_t aic_ctrl_b0[5], aic_ctrl_b1[5];
488
u_int32_t aic_stat_b0[2], aic_stat_b1[2];
489
u_int32_t aic_stat, value;
490
u_int32_t i, cal_count = ATH_AIC_MAX_CAL_COUNT;
491
struct ath_hal_9300 *ahp = AH9300(ah);
492
493
if (AR_SREV_JUPITER_10(ah)) {
494
aic_ctrl_b0[0] = AR_PHY_AIC_CTRL_0_B0_10;
495
aic_ctrl_b0[1] = AR_PHY_AIC_CTRL_1_B0_10;
496
aic_ctrl_b0[2] = AR_PHY_AIC_CTRL_2_B0_10;
497
aic_ctrl_b0[3] = AR_PHY_AIC_CTRL_3_B0_10;
498
aic_ctrl_b1[0] = AR_PHY_AIC_CTRL_0_B1_10;
499
aic_ctrl_b1[1] = AR_PHY_AIC_CTRL_1_B1_10;
500
aic_stat_b0[0] = AR_PHY_AIC_STAT_0_B0_10;
501
aic_stat_b0[1] = AR_PHY_AIC_STAT_1_B0_10;
502
aic_stat_b1[0] = AR_PHY_AIC_STAT_0_B1_10;
503
aic_stat_b1[1] = AR_PHY_AIC_STAT_1_B1_10;
504
}
505
else {
506
aic_ctrl_b0[0] = AR_PHY_AIC_CTRL_0_B0_20;
507
aic_ctrl_b0[1] = AR_PHY_AIC_CTRL_1_B0_20;
508
aic_ctrl_b0[2] = AR_PHY_AIC_CTRL_2_B0_20;
509
aic_ctrl_b0[3] = AR_PHY_AIC_CTRL_3_B0_20;
510
aic_ctrl_b0[4] = AR_PHY_AIC_CTRL_4_B0_20;
511
aic_ctrl_b1[0] = AR_PHY_AIC_CTRL_0_B1_20;
512
aic_ctrl_b1[1] = AR_PHY_AIC_CTRL_1_B1_20;
513
aic_ctrl_b1[4] = AR_PHY_AIC_CTRL_4_B1_20;
514
aic_stat_b0[0] = AR_PHY_AIC_STAT_0_B0_20;
515
aic_stat_b0[1] = AR_PHY_AIC_STAT_1_B0_20;
516
aic_stat_b1[0] = AR_PHY_AIC_STAT_0_B1_20;
517
aic_stat_b1[1] = AR_PHY_AIC_STAT_1_B1_20;
518
}
519
520
/* Config LNA gain difference */
521
OS_REG_WRITE(ah, AR_PHY_BT_COEX_4, 0x22180600);
522
OS_REG_WRITE(ah, AR_PHY_BT_COEX_5, 0x52443a2e);
523
524
OS_REG_WRITE(ah, aic_ctrl_b0[0],
525
(SM(0, AR_PHY_AIC_MON_ENABLE) |
526
SM(40, AR_PHY_AIC_CAL_MAX_HOP_COUNT) |
527
SM(1, AR_PHY_AIC_CAL_MIN_VALID_COUNT) | //26
528
SM(37, AR_PHY_AIC_F_WLAN) |
529
SM(1, AR_PHY_AIC_CAL_CH_VALID_RESET) |
530
SM(0, AR_PHY_AIC_CAL_ENABLE) |
531
SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) |
532
SM(0, AR_PHY_AIC_ENABLE)));
533
534
OS_REG_WRITE(ah, aic_ctrl_b1[0],
535
(SM(0, AR_PHY_AIC_MON_ENABLE) |
536
SM(1, AR_PHY_AIC_CAL_CH_VALID_RESET) |
537
SM(0, AR_PHY_AIC_CAL_ENABLE) |
538
SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) |
539
SM(0, AR_PHY_AIC_ENABLE)));
540
541
OS_REG_WRITE(ah, aic_ctrl_b0[1],
542
(SM(8, AR_PHY_AIC_CAL_BT_REF_DELAY) |
543
SM(6, AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO) |
544
SM(3, AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO) |
545
SM(0, AR_PHY_AIC_BT_IDLE_CFG) |
546
SM(1, AR_PHY_AIC_STDBY_COND) |
547
SM(37, AR_PHY_AIC_STDBY_ROT_ATT_DB) |
548
SM(5, AR_PHY_AIC_STDBY_COM_ATT_DB) |
549
SM(15, AR_PHY_AIC_RSSI_MAX) |
550
SM(0, AR_PHY_AIC_RSSI_MIN)));
551
552
OS_REG_WRITE(ah, aic_ctrl_b1[1],
553
(SM(6, AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO) |
554
SM(3, AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO) |
555
SM(15, AR_PHY_AIC_RSSI_MAX) |
556
SM(0, AR_PHY_AIC_RSSI_MIN)));
557
558
OS_REG_WRITE(ah, aic_ctrl_b0[2],
559
(SM(44, AR_PHY_AIC_RADIO_DELAY) |
560
SM(7, AR_PHY_AIC_CAL_STEP_SIZE_CORR) |
561
SM(12, AR_PHY_AIC_CAL_ROT_IDX_CORR) |
562
SM(2, AR_PHY_AIC_CAL_CONV_CHECK_FACTOR) |
563
SM(5, AR_PHY_AIC_ROT_IDX_COUNT_MAX) |
564
SM(1, AR_PHY_AIC_CAL_SYNTH_TOGGLE) |
565
SM(1, AR_PHY_AIC_CAL_SYNTH_AFTER_BTRX) |
566
SM(200, AR_PHY_AIC_CAL_SYNTH_SETTLING)));
567
568
OS_REG_WRITE(ah, aic_ctrl_b0[3],
569
(SM(20, AR_PHY_AIC_MON_MAX_HOP_COUNT) |
570
SM(10, AR_PHY_AIC_MON_MIN_STALE_COUNT) |
571
SM(1, AR_PHY_AIC_MON_PWR_EST_LONG) |
572
SM(2, AR_PHY_AIC_MON_PD_TALLY_SCALING) |
573
SM(18, AR_PHY_AIC_MON_PERF_THR) |
574
SM(1, AR_PHY_AIC_CAL_COM_ATT_DB_FIXED) |
575
SM(2, AR_PHY_AIC_CAL_TARGET_MAG_SETTING) |
576
SM(3, AR_PHY_AIC_CAL_PERF_CHECK_FACTOR) |
577
SM(1, AR_PHY_AIC_CAL_PWR_EST_LONG)));
578
579
ar9300_aic_gain_table(ah);
580
581
/* Need to enable AIC reference signal in BT modem. */
582
OS_REG_WRITE(ah, ATH_AIC_BT_JUPITER_CTRL,
583
(OS_REG_READ(ah, ATH_AIC_BT_JUPITER_CTRL) |
584
ATH_AIC_BT_AIC_ENABLE));
585
586
while (cal_count)
587
{
588
/* Start calibration */
589
OS_REG_CLR_BIT(ah, aic_ctrl_b1[0], AR_PHY_AIC_CAL_ENABLE);
590
OS_REG_SET_BIT(ah, aic_ctrl_b1[0], AR_PHY_AIC_CAL_CH_VALID_RESET);
591
OS_REG_SET_BIT(ah, aic_ctrl_b1[0], AR_PHY_AIC_CAL_ENABLE);
592
593
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Start calibration #%d\n",
594
(ATH_AIC_MAX_CAL_COUNT - cal_count));
595
596
/* Wait until calibration is completed. */
597
for (i = 0; i < 10000; i++) {
598
/*
599
* Use AR_PHY_AIC_CAL_ENABLE bit instead of AR_PHY_AIC_CAL_DONE.
600
* Sometimes CAL_DONE bit is not asserted.
601
*/
602
if ((OS_REG_READ(ah, aic_ctrl_b1[0]) & AR_PHY_AIC_CAL_ENABLE) == 0)
603
{
604
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Cal is done at #%d\n", i);
605
break;
606
}
607
OS_DELAY(1);
608
}
609
610
/* print out status registers */
611
aic_stat = OS_REG_READ(ah, aic_stat_b1[0]);
612
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
613
"(AIC) CAL_DONE = %d, CAL_ACTIVE = %d, MEAS_COUNT = %d\n",
614
MS(aic_stat, AR_PHY_AIC_CAL_DONE),
615
MS(aic_stat, AR_PHY_AIC_CAL_ACTIVE),
616
MS(aic_stat, AR_PHY_AIC_MEAS_COUNT));
617
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
618
"(AIC) ANT_ISO = %d, HOP_COUNT = %d, VALID_COUNT = %d\n",
619
MS(aic_stat, AR_PHY_AIC_CAL_ANT_ISO_EST),
620
MS(aic_stat, AR_PHY_AIC_CAL_HOP_COUNT),
621
MS(aic_stat, AR_PHY_AIC_CAL_VALID_COUNT));
622
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
623
"(AIC) BT_WEAK = %d, BT_STRONG = %d, , \n",
624
MS(aic_stat, AR_PHY_AIC_CAL_BT_TOO_WEAK_ERR),
625
MS(aic_stat, AR_PHY_AIC_CAL_BT_TOO_STRONG_ERR));
626
627
aic_stat = OS_REG_READ(ah, aic_stat_b1[1]);
628
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
629
"(AIC) MEAS_MAG_MIN = %d, CAL_AIC_SM = %d, AIC_SM = %d\n",
630
MS(aic_stat, AR_PHY_AIC_MEAS_MAG_MIN),
631
MS(aic_stat, AR_PHY_AIC_CAL_AIC_SM),
632
MS(aic_stat, AR_PHY_AIC_SM));
633
634
if (i >= 10000) {
635
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Calibration failed.\n");
636
break;
637
}
638
639
/* print out calibration result */
640
if (MS(aic_stat, AR_PHY_AIC_MEAS_MAG_MIN) < ATH_AIC_MEAS_MAG_THRESH) {
641
for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
642
OS_REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1,
643
(ATH_AIC_SRAM_CAL_OFFSET + i*4));
644
value = OS_REG_READ(ah, AR_PHY_AIC_SRAM_DATA_B1);
645
if (value & 0x01) {
646
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
647
"(AIC) BT chan %02d: 0x%08x\n", i, value);
648
}
649
}
650
break;
651
}
652
cal_count--;
653
}
654
655
if (!cal_count) {
656
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Calibration failed2.\n");
657
}
658
659
/* Disable AIC reference signal in BT modem. */
660
OS_REG_WRITE(ah, ATH_AIC_BT_JUPITER_CTRL,
661
(OS_REG_READ(ah, ATH_AIC_BT_JUPITER_CTRL) &
662
~ATH_AIC_BT_AIC_ENABLE));
663
664
ahp->ah_aic_enabled = ar9300_aic_cal_post_process(ah) ? AH_TRUE : AH_FALSE;
665
666
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) ah_aic_enable = %d\n",
667
ahp->ah_aic_enabled);
668
return 0;
669
}
670
671
672
u_int32_t
673
ar9300_aic_start_normal (struct ath_hal *ah)
674
{
675
struct ath_hal_9300 *ahp = AH9300(ah);
676
u_int32_t aic_ctrl0_b1, aic_ctrl1_b0, aic_ctrl1_b1;
677
int16_t i;
678
679
/* Config LNA gain difference */
680
OS_REG_WRITE(ah, AR_PHY_BT_COEX_4, 0x22180600);
681
OS_REG_WRITE(ah, AR_PHY_BT_COEX_5, 0x52443a2e);
682
683
ar9300_aic_gain_table(ah);
684
685
OS_REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1, ATH_AIC_SRAM_AUTO_INCREMENT);
686
687
for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
688
OS_REG_WRITE(ah, AR_PHY_AIC_SRAM_DATA_B1, ahp->ah_aic_sram[i]);
689
}
690
691
if (AR_SREV_JUPITER_10(ah)) {
692
aic_ctrl0_b1 = AR_PHY_AIC_CTRL_0_B1_10;
693
aic_ctrl1_b0 = AR_PHY_AIC_CTRL_1_B0_10;
694
aic_ctrl1_b1 = AR_PHY_AIC_CTRL_1_B1_10;
695
}
696
else {
697
aic_ctrl0_b1 = AR_PHY_AIC_CTRL_0_B1_20;
698
aic_ctrl1_b0 = AR_PHY_AIC_CTRL_1_B0_20;
699
aic_ctrl1_b1 = AR_PHY_AIC_CTRL_1_B1_20;
700
}
701
702
OS_REG_WRITE(ah, aic_ctrl1_b0,
703
(SM(0, AR_PHY_AIC_BT_IDLE_CFG) |
704
SM(1, AR_PHY_AIC_STDBY_COND) |
705
SM(37, AR_PHY_AIC_STDBY_ROT_ATT_DB) |
706
SM(5, AR_PHY_AIC_STDBY_COM_ATT_DB) |
707
SM(15, AR_PHY_AIC_RSSI_MAX) |
708
SM(0, AR_PHY_AIC_RSSI_MIN)));
709
710
OS_REG_WRITE(ah, aic_ctrl1_b1,
711
(SM(15, AR_PHY_AIC_RSSI_MAX) |
712
SM(0, AR_PHY_AIC_RSSI_MIN)));
713
714
OS_REG_WRITE(ah, aic_ctrl0_b1,
715
(SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) |
716
SM(1, AR_PHY_AIC_ENABLE)));
717
718
ahp->ah_aic_enabled = AH_TRUE;
719
720
HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Start normal operation mode.\n");
721
return 0;
722
}
723
#endif
724
725
#endif
726
727
728
729