diff mbox series

[RFC,v1,007/256] cl8k: add agc_params.c

Message ID 20210617160223.160998-8-viktor.barna@celeno.com (mailing list archive)
State RFC
Delegated to: Kalle Valo
Headers show
Series wireless: cl8k driver for Celeno IEEE 802.11ax devices | expand

Commit Message

Viktor Barna June 17, 2021, 3:58 p.m. UTC
From: Viktor Barna <viktor.barna@celeno.com>

(Part of the split. Please, take a look at the cover letter for more
details).

Signed-off-by: Viktor Barna <viktor.barna@celeno.com>
---
 drivers/net/wireless/celeno/cl8k/agc_params.c | 683 ++++++++++++++++++
 1 file changed, 683 insertions(+)
 create mode 100644 drivers/net/wireless/celeno/cl8k/agc_params.c

--
2.30.0
diff mbox series

Patch

diff --git a/drivers/net/wireless/celeno/cl8k/agc_params.c b/drivers/net/wireless/celeno/cl8k/agc_params.c
new file mode 100644
index 000000000000..3512defb6f18
--- /dev/null
+++ b/drivers/net/wireless/celeno/cl8k/agc_params.c
@@ -0,0 +1,683 @@ 
+// SPDX-License-Identifier: MIT
+/* Copyright(c) 2019-2021, Celeno Communications Ltd. */
+
+#include "agc_params.h"
+#include "chip.h"
+#include "hw.h"
+#include "e2p.h"
+#include "utils/utils.h"
+
+struct cl_agc_profile agc_profile_2_1_6 = {
+       .id                 = AGC_PROFILE(2, 1, 6),
+       .fsm_preset_p2      = { .val = 0x00004701, .mask = 0xffffffff }, /* 0x244 */
+       .lna_thr_set0_ref2  = { .val = 0x2E292624, .mask = 0xffffffff }, /* 0x25C */
+       .lna_thr_set0_ref3  = { .val = 0x00393933, .mask = 0xffffffff }, /* 0x260 */
+       .lna_thr_set1_ref2  = { .val = 0x2E292624, .mask = 0xffffffff }, /* 0x264 */
+       .lna_thr_set1_ref3  = { .val = 0x5D393933, .mask = 0xffffffff }, /* 0x268 */
+       .lna_thr_set2_ref2  = { .val = 0x2E292624, .mask = 0xffffffff }, /* 0x26C */
+       .lna_thr_set2_ref3  = { .val = 0x5D393933, .mask = 0xffffffff }, /* 0x270 */
+       .lna_gain_set0_ref2 = { .val = 0x2926231F, .mask = 0xffffffff }, /* 0x274 */
+       .lna_gain_set0_ref3 = { .val = 0x3838322E, .mask = 0xffffffff }, /* 0x278 */
+       .lna_nf_set0_ref2   = { .val = 0x04080C0F, .mask = 0xffffffff }, /* 0x27C */
+       .lna_nf_set0_ref3   = { .val = 0x03030303, .mask = 0xffffffff }, /* 0x280 */
+       .lna_icp1_set0_ref2 = { .val = 0x66696C6C, .mask = 0xffffffff }, /* 0x284 */
+       .lna_icp1_set0_ref3 = { .val = 0x625F6264, .mask = 0xffffffff }, /* 0x288 */
+       .fsm_preset_p10     = { .val = 0x00001E21, .mask = 0xffffffff }, /* 0x2A8 */
+       .fsm_preset_p11     = { .val = 0x00001E21, .mask = 0xffffffff }, /* 0x2AC */
+       .fsm_preset_p12     = { .val = 0x00ECEA07, .mask = 0xffffffff }, /* 0x2B0 */
+       .ant_loss           = { .val = 0x00000000, .mask = 0xffffffff }, /* 0x300 */
+       .gain_range         = { .val = 0x47076407, .mask = 0xffffffff }, /* 0x304 */
+       .vga_ref0           = { .val = 0x0001021E, .mask = 0xffffffff }, /* 0x308 */
+       .lna_gain_set0_ref0 = { .val = 0x15120F0B, .mask = 0xffffffff }, /* 0x30C */
+       .lna_gain_set0_ref1 = { .val = 0x24241E1A, .mask = 0xffffffff }, /* 0x310 */
+       .lna_thr_set0_ref0  = { .val = 0x1A16130F, .mask = 0xffffffff }, /* 0x314 */
+       .lna_thr_set0_ref1  = { .val = 0x2424241F, .mask = 0xffffffff }, /* 0x318 */
+       .lna_thr_set1_ref0  = { .val = 0x1A16130F, .mask = 0xffffffff }, /* 0x31C */
+       .lna_thr_set1_ref1  = { .val = 0x2424241F, .mask = 0xffffffff }, /* 0x320 */
+       .lna_thr_set2_ref0  = { .val = 0x1A16130F, .mask = 0xffffffff }, /* 0x324 */
+       .lna_thr_set2_ref1  = { .val = 0x2424241F, .mask = 0xffffffff }, /* 0x328 */
+       .lna_nf_set0_ref0   = { .val = 0x141A2023, .mask = 0xffffffff }, /* 0x32C */
+       .lna_nf_set0_ref1   = { .val = 0x000D0E10, .mask = 0xffffffff }, /* 0x330 */
+       .lna_icp1_set0_ref0 = { .val = 0x7A7D0000, .mask = 0xffffffff }, /* 0x334 */
+       .lna_icp1_set0_ref1 = { .val = 0x00737678, .mask = 0xffffffff }, /* 0x338 */
+       .saturation         = { .val = 0x08393536, .mask = 0xffffffff }, /* 0x364 */
+       .ramp               = { .val = 0x05200710, .mask = 0xffffffff }, /* 0x36C */
+       .dsp0               = { .val = 0x00000000, .mask = 0x000000ff }, /* 0x394 */
+       .dsp1               = { .val = 0x00000000, .mask = 0x000000ff }, /* 0x398 */
+       .dsp2               = { .val = 0x00000000, .mask = 0xffffffff }, /* 0x39A */
+       .dsp3               = { .val = 0x0B730000, .mask = 0xffff0000 }, /* 0x3A0 */
+       .lna_gain_set1_ref0 = { .val = 0x15120F0B, .mask = 0xffffffff }, /* 0x590 */
+       .lna_gain_set1_ref1 = { .val = 0x24241E1A, .mask = 0xffffffff }, /* 0x594 */
+       .lna_gain_set1_ref2 = { .val = 0x2926231F, .mask = 0xffffffff }, /* 0x598 */
+       .lna_gain_set1_ref3 = { .val = 0x3838322E, .mask = 0xffffffff }, /* 0x59C */
+       .lna_nf_set1_ref0   = { .val = 0x141A2023, .mask = 0xffffffff }, /* 0x5A0 */
+       .lna_nf_set1_ref1   = { .val = 0x000D0E10, .mask = 0xffffffff }, /* 0x5A4 */
+       .lna_nf_set1_ref2   = { .val = 0x04080C0F, .mask = 0xffffffff }, /* 0x5A8 */
+       .lna_nf_set1_ref3   = { .val = 0x03030303, .mask = 0xffffffff }, /* 0x5AC */
+       .lna_icp1_set1_ref0 = { .val = 0x7A7D0000, .mask = 0xffffffff }, /* 0x5B0 */
+       .lna_icp1_set1_ref1 = { .val = 0x00737678, .mask = 0xffffffff }, /* 0x5B4 */
+       .lna_icp1_set1_ref2 = { .val = 0x66696C6C, .mask = 0xffffffff }, /* 0x5B8 */
+       .lna_icp1_set1_ref3 = { .val = 0x625F6264, .mask = 0xffffffff }, /* 0x5BC */
+};
+
+struct cl_agc_profile agc_profile_5_1_7 = {
+       .id                 = AGC_PROFILE(5, 1, 7),
+       .fsm_preset_p2      = { .val = 0x00004701, .mask = 0xffffffff }, /* 0x244 */
+       .lna_thr_set0_ref2  = { .val = 0x2E28231F, .mask = 0xffffffff }, /* 0x25C */
+       .lna_thr_set0_ref3  = { .val = 0x00353532, .mask = 0xffffffff }, /* 0x260 */
+       .lna_thr_set1_ref2  = { .val = 0x2E28231F, .mask = 0xffffffff }, /* 0x264 */
+       .lna_thr_set1_ref3  = { .val = 0x5B353532, .mask = 0xffffffff }, /* 0x268 */
+       .lna_thr_set2_ref2  = { .val = 0x2E28231F, .mask = 0xffffffff }, /* 0x26C */
+       .lna_thr_set2_ref3  = { .val = 0x5B353532, .mask = 0xffffffff }, /* 0x270 */
+       .lna_gain_set0_ref2 = { .val = 0x27231E19, .mask = 0xffffffff }, /* 0x274 */
+       .lna_gain_set0_ref3 = { .val = 0x3535312C, .mask = 0xffffffff }, /* 0x278 */
+       .lna_nf_set0_ref2   = { .val = 0x0406090D, .mask = 0xffffffff }, /* 0x27C */
+       .lna_nf_set0_ref3   = { .val = 0x02030303, .mask = 0xffffffff }, /* 0x280 */
+       .lna_icp1_set0_ref2 = { .val = 0x5D666A6F, .mask = 0xffffffff }, /* 0x284 */
+       .lna_icp1_set0_ref3 = { .val = 0x5757575B, .mask = 0xffffffff }, /* 0x288 */
+       .fsm_preset_p10     = { .val = 0x00001E21, .mask = 0xffffffff }, /* 0x2A8 */
+       .fsm_preset_p11     = { .val = 0x00001E21, .mask = 0xffffffff }, /* 0x2AC */
+       .fsm_preset_p12     = { .val = 0x00ECEA07, .mask = 0xffffffff }, /* 0x2B0 */
+       .ant_loss           = { .val = 0x00000000, .mask = 0xffffffff }, /* 0x300 */
+       .gain_range         = { .val = 0x47026402, .mask = 0xffffffff }, /* 0x304 */
+       .vga_ref0           = { .val = 0x0001021E, .mask = 0xffffffff }, /* 0x308 */
+       .lna_gain_set0_ref0 = { .val = 0x120E0904, .mask = 0xffffffff }, /* 0x30C */
+       .lna_gain_set0_ref1 = { .val = 0x20201C17, .mask = 0xffffffff }, /* 0x310 */
+       .lna_thr_set0_ref0  = { .val = 0x17120E09, .mask = 0xffffffff }, /* 0x314 */
+       .lna_thr_set0_ref1  = { .val = 0x1F1F1F1C, .mask = 0xffffffff }, /* 0x318 */
+       .lna_thr_set1_ref0  = { .val = 0x17120E09, .mask = 0xffffffff }, /* 0x31C */
+       .lna_thr_set1_ref1  = { .val = 0x1F1F1F1C, .mask = 0xffffffff }, /* 0x320 */
+       .lna_thr_set2_ref0  = { .val = 0x17120E09, .mask = 0xffffffff }, /* 0x324 */
+       .lna_thr_set2_ref1  = { .val = 0x1F1F1F1C, .mask = 0xffffffff }, /* 0x328 */
+       .lna_nf_set0_ref0   = { .val = 0x12171C20, .mask = 0xffffffff }, /* 0x32C */
+       .lna_nf_set0_ref1   = { .val = 0x0A0B0B0F, .mask = 0xffffffff }, /* 0x330 */
+       .lna_icp1_set0_ref0 = { .val = 0x6F727476, .mask = 0xffffffff }, /* 0x334 */
+       .lna_icp1_set0_ref1 = { .val = 0x6268686D, .mask = 0xffffffff }, /* 0x338 */
+       .saturation         = { .val = 0x08393536, .mask = 0xffffffff }, /* 0x364 */
+       .ramp               = { .val = 0x05200710, .mask = 0xffffffff }, /* 0x36C */
+       .dsp0               = { .val = 0x00000000, .mask = 0x000000ff }, /* 0x394 */
+       .dsp1               = { .val = 0x00000000, .mask = 0x000000ff }, /* 0x398 */
+       .dsp2               = { .val = 0x00000000, .mask = 0xffffffff }, /* 0x39A */
+       .dsp3               = { .val = 0x0B730000, .mask = 0xffff0000 }, /* 0x3A0 */
+       .lna_gain_set1_ref0 = { .val = 0x120E0904, .mask = 0xffffffff }, /* 0x590 */
+       .lna_gain_set1_ref1 = { .val = 0x20201C17, .mask = 0xffffffff }, /* 0x594 */
+       .lna_gain_set1_ref2 = { .val = 0x27231E19, .mask = 0xffffffff }, /* 0x598 */
+       .lna_gain_set1_ref3 = { .val = 0x3535312C, .mask = 0xffffffff }, /* 0x59C */
+       .lna_nf_set1_ref0   = { .val = 0x12171C20, .mask = 0xffffffff }, /* 0x5A0 */
+       .lna_nf_set1_ref1   = { .val = 0x0A0B0B0F, .mask = 0xffffffff }, /* 0x5A4 */
+       .lna_nf_set1_ref2   = { .val = 0x0406090D, .mask = 0xffffffff }, /* 0x5A8 */
+       .lna_nf_set1_ref3   = { .val = 0x02030303, .mask = 0xffffffff }, /* 0x5AC */
+       .lna_icp1_set1_ref0 = { .val = 0x6F727476, .mask = 0xffffffff }, /* 0x5B0 */
+       .lna_icp1_set1_ref1 = { .val = 0x6268686D, .mask = 0xffffffff }, /* 0x5B4 */
+       .lna_icp1_set1_ref2 = { .val = 0x5D666A6F, .mask = 0xffffffff }, /* 0x5B8 */
+       .lna_icp1_set1_ref3 = { .val = 0x5757575B, .mask = 0xffffffff }, /* 0x5BC */
+};
+
+struct cl_agc_profile agc_profile_6_1_3 = {
+       .id                 = AGC_PROFILE(6, 1, 3),
+       .fsm_preset_p2      = { .val = 0x00004701, .mask = 0xffffffff }, /* 0x244 */
+       .lna_thr_set0_ref2  = { .val = 0x29241F1C, .mask = 0xffffffff }, /* 0x25C */
+       .lna_thr_set0_ref3  = { .val = 0x0033332D, .mask = 0xffffffff }, /* 0x260 */
+       .lna_thr_set1_ref2  = { .val = 0x29241F1C, .mask = 0xffffffff }, /* 0x264 */
+       .lna_thr_set1_ref3  = { .val = 0x5833332D, .mask = 0xffffffff }, /* 0x268 */
+       .lna_thr_set2_ref2  = { .val = 0x29241F1C, .mask = 0xffffffff }, /* 0x26C */
+       .lna_thr_set2_ref3  = { .val = 0x5833332D, .mask = 0xffffffff }, /* 0x270 */
+       .lna_gain_set0_ref2 = { .val = 0x1A15100C, .mask = 0xffffffff }, /* 0x274 */
+       .lna_gain_set0_ref3 = { .val = 0x2828231E, .mask = 0xffffffff }, /* 0x278 */
+       .lna_nf_set0_ref2   = { .val = 0x0406090D, .mask = 0xffffffff }, /* 0x27C */
+       .lna_nf_set0_ref3   = { .val = 0x02030303, .mask = 0xffffffff }, /* 0x280 */
+       .lna_icp1_set0_ref2 = { .val = 0x5D666A6F, .mask = 0xffffffff }, /* 0x284 */
+       .lna_icp1_set0_ref3 = { .val = 0x5757575B, .mask = 0xffffffff }, /* 0x288 */
+       .fsm_preset_p10     = { .val = 0x00001E21, .mask = 0xffffffff }, /* 0x2A8 */
+       .fsm_preset_p11     = { .val = 0x00001E21, .mask = 0xffffffff }, /* 0x2AC */
+       .fsm_preset_p12     = { .val = 0x00ECEA07, .mask = 0xffffffff }, /* 0x2B0 */
+       .ant_loss           = { .val = 0x00000000, .mask = 0xffffffff }, /* 0x300 */
+       .gain_range         = { .val = 0x47026402, .mask = 0xffffffff }, /* 0x304 */
+       .vga_ref0           = { .val = 0x0001A214, .mask = 0xffffffff }, /* 0x308 */
+       .lna_gain_set0_ref0 = { .val = 0x047F7A76, .mask = 0xffffffff }, /* 0x30C */
+       .lna_gain_set0_ref1 = { .val = 0x12120D08, .mask = 0xffffffff }, /* 0x310 */
+       .lna_thr_set0_ref0  = { .val = 0x130D0906, .mask = 0xffffffff }, /* 0x314 */
+       .lna_thr_set0_ref1  = { .val = 0x1A1A1A17, .mask = 0xffffffff }, /* 0x318 */
+       .lna_thr_set1_ref0  = { .val = 0x130D0906, .mask = 0xffffffff }, /* 0x31C */
+       .lna_thr_set1_ref1  = { .val = 0x1A1A1A17, .mask = 0xffffffff }, /* 0x320 */
+       .lna_thr_set2_ref0  = { .val = 0x130D0906, .mask = 0xffffffff }, /* 0x324 */
+       .lna_thr_set2_ref1  = { .val = 0x1A1A1A17, .mask = 0xffffffff }, /* 0x328 */
+       .lna_nf_set0_ref0   = { .val = 0x12171C20, .mask = 0xffffffff }, /* 0x32C */
+       .lna_nf_set0_ref1   = { .val = 0x0A0B0B0F, .mask = 0xffffffff }, /* 0x330 */
+       .lna_icp1_set0_ref0 = { .val = 0x6F727476, .mask = 0xffffffff }, /* 0x334 */
+       .lna_icp1_set0_ref1 = { .val = 0x6268686D, .mask = 0xffffffff }, /* 0x338 */
+       .saturation         = { .val = 0x08383435, .mask = 0xffffffff }, /* 0x364 */
+       .ramp               = { .val = 0x05200710, .mask = 0xffffffff }, /* 0x36C */
+       .dsp0               = { .val = 0x00000004, .mask = 0x000000ff }, /* 0x394 */
+       .dsp1               = { .val = 0x00000006, .mask = 0x000000ff }, /* 0x398 */
+       .dsp2               = { .val = 0x06060606, .mask = 0xffffffff }, /* 0x39A */
+       .dsp3               = { .val = 0x0B730000, .mask = 0xffff0000 }, /* 0x3A0 */
+       .lna_gain_set1_ref0 = { .val = 0x047F7A76, .mask = 0xffffffff }, /* 0x590 */
+       .lna_gain_set1_ref1 = { .val = 0x12120D08, .mask = 0xffffffff }, /* 0x594 */
+       .lna_gain_set1_ref2 = { .val = 0x1A15100C, .mask = 0xffffffff }, /* 0x598 */
+       .lna_gain_set1_ref3 = { .val = 0x2828231E, .mask = 0xffffffff }, /* 0x59C */
+       .lna_nf_set1_ref0   = { .val = 0x12171C20, .mask = 0xffffffff }, /* 0x5A0 */
+       .lna_nf_set1_ref1   = { .val = 0x0A0B0B0F, .mask = 0xffffffff }, /* 0x5A4 */
+       .lna_nf_set1_ref2   = { .val = 0x0406090D, .mask = 0xffffffff }, /* 0x5A8 */
+       .lna_nf_set1_ref3   = { .val = 0x02030303, .mask = 0xffffffff }, /* 0x5AC */
+       .lna_icp1_set1_ref0 = { .val = 0x6F727476, .mask = 0xffffffff }, /* 0x5B0 */
+       .lna_icp1_set1_ref1 = { .val = 0x6268686D, .mask = 0xffffffff }, /* 0x5B4 */
+       .lna_icp1_set1_ref2 = { .val = 0x5D666A6F, .mask = 0xffffffff }, /* 0x5B8 */
+       .lna_icp1_set1_ref3 = { .val = 0x5757575B, .mask = 0xffffffff }, /* 0x5BC */
+};
+
+#define PLATFORM_DESCRIPTION_LENGTH 100
+
+struct cl_agc_table {
+       u32 platform_id;
+       u8 platform_description[PLATFORM_DESCRIPTION_LENGTH];
+       struct cl_agc_profile *agc_profile[TCV_MAX];
+       struct cl_agc_profile *agc_profile_elastic[TCV_MAX];
+       struct cl_agc_profile *agc_profile_sensing;
+};
+
+struct cl_agc_table agc_table[] = {
+       {
+               .platform_id = AGC_PLATFORM(CL_CUSTOMER_CELENO, CL_BOARD_EVB, 0),
+               .platform_description = "Celeno, EVB, 5G 6x6 + 2.4G 6x6",
+               .agc_profile[TCV0] = &agc_profile_5_1_7,
+               .agc_profile[TCV1] = &agc_profile_2_1_6,
+               .agc_profile_elastic[TCV0] = NULL,
+               .agc_profile_elastic[TCV1] = NULL,
+               .agc_profile_sensing = NULL,
+       },
+       {
+               .platform_id = AGC_PLATFORM(CL_CUSTOMER_CELENO, CL_BOARD_MERLIN, 0),
+               .platform_description = "Celeno, Merlin, 5G 4x4 + 2.4G 4x4",
+               .agc_profile[TCV0] = &agc_profile_5_1_7,
+               .agc_profile[TCV1] = &agc_profile_2_1_6,
+               .agc_profile_elastic[TCV0] = NULL,
+               .agc_profile_elastic[TCV1] = NULL,
+               .agc_profile_sensing = NULL,
+       },
+       {
+               .platform_id = AGC_PLATFORM(CL_CUSTOMER_CELENO, CL_BOARD_EVB_6G, 0),
+               .platform_description = "Celeno, EVB, 6G 4x4 + 6G 4x4",
+               .agc_profile[TCV0] = &agc_profile_6_1_3,
+               .agc_profile[TCV1] = &agc_profile_6_1_3,
+               .agc_profile_elastic[TCV0] = NULL,
+               .agc_profile_elastic[TCV1] = NULL,
+               .agc_profile_sensing = NULL,
+       },
+       {
+               .platform_id = AGC_PLATFORM(CL_CUSTOMER_CELENO, CL_BOARD_ALBATROSS, 0),
+               .platform_description =
+                       "Celeno, Albatross, 6G 4x4 WiFi + 6G 2x2 sensing + 5G 2x2 sensing",
+               .agc_profile[TCV0] = &agc_profile_6_1_3,
+               .agc_profile[TCV1] = NULL,
+               .agc_profile_elastic[TCV0] = NULL,
+               .agc_profile_elastic[TCV1] = NULL,
+               .agc_profile_sensing = &agc_profile_6_1_3,
+       },
+       {
+               .platform_id = AGC_PLATFORM(CL_CUSTOMER_CELENO, CL_BOARD_ALBATROSS_2, 0),
+               .platform_description =
+                       "Celeno, Albatross 2, 6G 4x4 WiFi + 6G 2x2 sensing + 5G 2x2 sensing",
+               .agc_profile[TCV0] = &agc_profile_6_1_3,
+               .agc_profile[TCV1] = NULL,
+               .agc_profile_elastic[TCV0] = NULL,
+               .agc_profile_elastic[TCV1] = NULL,
+               .agc_profile_sensing = &agc_profile_6_1_3,
+       },
+       {
+               .platform_id = AGC_PLATFORM(CL_CUSTOMER_CELENO, CL_BOARD_CHAMELEON, 0),
+               .platform_description = "Celeno, Chameleon, 5G 4x4 WiFi + 5G 4x4 sensing",
+               .agc_profile[TCV0] = &agc_profile_5_1_7,
+               .agc_profile[TCV1] = NULL,
+               .agc_profile_elastic[TCV0] = NULL,
+               .agc_profile_elastic[TCV1] = NULL,
+               .agc_profile_sensing = &agc_profile_5_1_7,
+       },
+};
+
+int cl_agc_params_read_platform_id(struct cl_chip *chip)
+{
+       u8 i;
+       u32 platform_id = 0;
+
+       if (cl_e2p_read(chip, (u8 *)&platform_id, SIZE_FEM_PLATFORM_ID, ADDR_FEM_PLATFORM_ID))
+               return -1;
+
+       cl_dbg_chip_verbose(chip,
+                           "platform_id: 0x%08x, "
+                           "customer_id: 0x%04x, board_id: 0x%02x, chip_id: 0x%x\n",
+                           platform_id,
+                           AGC_PLATFORM_CUSTOMER(platform_id),
+                           AGC_PLATFORM_BOARD(platform_id),
+                           AGC_PLATFORM_CHIP(platform_id));
+
+       for (i = 0; i < ARRAY_SIZE(agc_table); i++) {
+               if (platform_id != agc_table[i].platform_id)
+                       continue;
+
+               cl_dbg_chip_verbose(chip, "%s\n", agc_table[i].platform_description);
+               chip->agc_table_entry = i;
+               return 0;
+       }
+
+       CL_DBG_ERROR_CHIP(chip, "Invalid platform_id 0x%08x\n", platform_id);
+
+       if (!chip->conf->ce_production_mode)
+               return -1;
+
+       return 0;
+}
+
+#ifdef __BIG_ENDIAN_BITFIELD
+static void agc_profile_to_le32(struct cl_agc_profile *profile)
+{
+       u32 i;
+       u32 size = sizeof(struct cl_agc_profile);
+       u32 *ptr = (u32 *)profile;
+
+       /* Make sure that size divides by 4 */
+       WARN_ON((size & 0x3) != 0);
+
+       for (i = 0; i < size / 4; i++)
+               ptr[i] = cpu_to_le32(ptr[i]);
+}
+#endif
+
+int cl_agc_params_fill(struct cl_hw *cl_hw, struct cl_agc_params *agc_params)
+{
+       u8 tcv_idx = cl_hw->tcv_idx;
+       u8 agc_table_entry = cl_hw->chip->agc_table_entry;
+       struct cl_agc_table *table;
+
+       memset(agc_params, 0, sizeof(struct cl_agc_params));
+
+       if (agc_table_entry == U8_MAX)
+               return 0;
+
+       table = &agc_table[agc_table_entry];
+
+       if (!table->agc_profile_elastic[tcv_idx] || cl_hw->num_antennas <= 2) {
+               u8 ant_shift = cl_hw_ant_shift(cl_hw);
+
+               if (table->agc_profile[tcv_idx]) {
+                       memcpy(&agc_params->profile1,
+                              table->agc_profile[tcv_idx],
+                              sizeof(struct cl_agc_profile));
+               } else if (tcv_idx == TCV1 && table->agc_profile_sensing) {
+                       memcpy(&agc_params->profile1,
+                              table->agc_profile_sensing,
+                              sizeof(struct cl_agc_profile));
+               } else {
+                       CL_DBG_ERROR(cl_hw, "Invalid tcv/sensing profile");
+                       return -1;
+               }
+
+               agc_params->num_profiles = 1;
+               agc_params->ant_mask1 = ANT_MASK(cl_hw->num_antennas) << ant_shift;
+               agc_params->ant_mask2 = 0;
+
+#ifdef __BIG_ENDIAN_BITFIELD
+               agc_profile_to_le32(&agc_params->profile1);
+#endif
+       } else {
+               if (table->agc_profile[tcv_idx]) {
+                       memcpy(&agc_params->profile1,
+                              table->agc_profile[tcv_idx],
+                              sizeof(struct cl_agc_profile));
+               } else {
+                       CL_DBG_ERROR(cl_hw, "Invalid tcv profile");
+                       return -1;
+               }
+
+               if (table->agc_profile_elastic[tcv_idx]) {
+                       memcpy(&agc_params->profile2,
+                              table->agc_profile_elastic[tcv_idx],
+                              sizeof(struct cl_agc_profile));
+               } else {
+                       CL_DBG_ERROR(cl_hw, "Invalid elastic profile");
+                       return -1;
+               }
+
+               agc_params->num_profiles = 2;
+               agc_params->ant_mask1 = ANT_MASK(2);
+               agc_params->ant_mask2 = ANT_MASK(cl_hw->num_antennas - 2) << 2;
+
+#ifdef __BIG_ENDIAN_BITFIELD
+               agc_profile_to_le32(&agc_params->profile1);
+               agc_profile_to_le32(&agc_params->profile2);
+#endif
+       }
+
+       return 0;
+}
+
+static void _cl_agc_params_dump(struct cl_hw *cl_hw, char **buf, int *len,
+                               ssize_t *buf_size, struct cl_agc_profile *agc_table)
+{
+       cl_snprintf(buf, len, buf_size,
+                   "|------------------------------------------------------|\n"
+                   "| Addr  | Name               | Mask       | Value      |\n"
+                   "|-------+--------------------+------------+------------|\n");
+
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x244 | fsm_preset_p2      | 0x%08x | 0x%08x |\n",
+                   agc_table->fsm_preset_p2.mask, agc_table->fsm_preset_p2.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x25C | lna_thr_set0_ref2  | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_thr_set0_ref2.mask, agc_table->lna_thr_set0_ref2.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x260 | lna_thr_set0_ref3  | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_thr_set0_ref3.mask, agc_table->lna_thr_set0_ref3.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x264 | lna_thr_set1_ref2  | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_thr_set1_ref2.mask, agc_table->lna_thr_set1_ref2.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x268 | lna_thr_set1_ref3  | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_thr_set1_ref3.mask, agc_table->lna_thr_set1_ref3.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x26C | lna_thr_set2_ref2  | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_thr_set2_ref2.mask, agc_table->lna_thr_set2_ref2.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x270 | lna_thr_set2_ref3  | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_thr_set2_ref3.mask, agc_table->lna_thr_set2_ref3.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x274 | lna_gain_set0_ref2 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_gain_set0_ref2.mask, agc_table->lna_gain_set0_ref2.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x278 | lna_gain_set0_ref3 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_gain_set0_ref3.mask, agc_table->lna_gain_set0_ref3.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x27C | lna_nf_set0_ref2   | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_nf_set0_ref2.mask, agc_table->lna_nf_set0_ref2.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x280 | lna_nf_set0_ref3   | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_nf_set0_ref3.mask, agc_table->lna_nf_set0_ref3.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x284 | lna_icp1_set0_ref2 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_icp1_set0_ref2.mask, agc_table->lna_icp1_set0_ref2.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x288 | lna_icp1_set0_ref3 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_icp1_set0_ref3.mask, agc_table->lna_icp1_set0_ref3.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x2A8 | fsm_preset_p10     | 0x%08x | 0x%08x |\n",
+                   agc_table->fsm_preset_p10.mask, agc_table->fsm_preset_p10.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x2AC | fsm_preset_p11     | 0x%08x | 0x%08x |\n",
+                   agc_table->fsm_preset_p11.mask, agc_table->fsm_preset_p11.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x2B0 | fsm_preset_p12     | 0x%08x | 0x%08x |\n",
+                   agc_table->fsm_preset_p12.mask, agc_table->fsm_preset_p12.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x300 | ant_loss           | 0x%08x | 0x%08x |\n",
+                   agc_table->ant_loss.mask, agc_table->ant_loss.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x304 | gain_range         | 0x%08x | 0x%08x |\n",
+                   agc_table->gain_range.mask, agc_table->gain_range.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x308 | vga_ref0           | 0x%08x | 0x%08x |\n",
+                   agc_table->vga_ref0.mask, agc_table->vga_ref0.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x30C | lna_gain_set0_ref0 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_gain_set0_ref0.mask, agc_table->lna_gain_set0_ref0.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x310 | lna_gain_set0_ref1 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_gain_set0_ref1.mask, agc_table->lna_gain_set0_ref1.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x314 | lna_thr_set0_ref0  | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_thr_set0_ref0.mask, agc_table->lna_thr_set0_ref0.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x318 | lna_thr_set0_ref1  | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_thr_set0_ref1.mask, agc_table->lna_thr_set0_ref1.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x31C | lna_thr_set1_ref0  | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_thr_set1_ref0.mask, agc_table->lna_thr_set1_ref0.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x320 | lna_thr_set1_ref1  | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_thr_set1_ref1.mask, agc_table->lna_thr_set1_ref1.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x324 | lna_thr_set2_ref0  | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_thr_set2_ref0.mask, agc_table->lna_thr_set2_ref0.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x328 | lna_thr_set2_ref1  | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_thr_set2_ref1.mask, agc_table->lna_thr_set2_ref1.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x32C | lna_nf_set0_ref0   | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_nf_set0_ref0.mask, agc_table->lna_nf_set0_ref0.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x330 | lna_nf_set0_ref1   | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_nf_set0_ref1.mask, agc_table->lna_nf_set0_ref1.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x334 | lna_icp1_set0_ref0 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_icp1_set0_ref0.mask, agc_table->lna_icp1_set0_ref0.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x338 | lna_icp1_set0_ref1 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_icp1_set0_ref1.mask, agc_table->lna_icp1_set0_ref1.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x364 | saturation          | 0x%08x | 0x%08x |\n",
+                   agc_table->saturation.mask, agc_table->saturation.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x36C | ramp               | 0x%08x | 0x%08x |\n",
+                   agc_table->ramp.mask, agc_table->ramp.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x394 | dsp0               | 0x%08x | 0x%08x |\n",
+                   agc_table->dsp0.mask, agc_table->dsp0.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x398 | dsp1               | 0x%08x | 0x%08x |\n",
+                   agc_table->dsp1.mask, agc_table->dsp1.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x39C | dsp2               | 0x%08x | 0x%08x |\n",
+                   agc_table->dsp2.mask, agc_table->dsp2.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x3A0 | dsp3               | 0x%08x | 0x%08x |\n",
+                   agc_table->dsp3.mask, agc_table->dsp3.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x590 | lna_gain_set1_ref0 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_gain_set1_ref0.mask,
+                   agc_table->lna_gain_set1_ref0.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x594 | lna_gain_set1_ref1 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_gain_set1_ref1.mask,
+                   agc_table->lna_gain_set1_ref1.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x598 | lna_gain_set1_ref2 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_gain_set1_ref2.mask,
+                   agc_table->lna_gain_set1_ref2.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x59C | lna_gain_set1_ref3 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_gain_set1_ref3.mask,
+                   agc_table->lna_gain_set1_ref3.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x5A0 | lna_nf_set1_ref0   | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_nf_set1_ref0.mask,
+                   agc_table->lna_nf_set1_ref0.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x5A4 | lna_nf_set1_ref1   | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_nf_set1_ref1.mask,
+                   agc_table->lna_nf_set1_ref1.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x5A8 | lna_nf_set1_ref2   | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_nf_set1_ref2.mask,
+                   agc_table->lna_nf_set1_ref2.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x5AC | lna_nf_set1_ref3   | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_nf_set1_ref3.mask,
+                   agc_table->lna_nf_set1_ref3.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x5B0 | lna_icp1_set1_ref0 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_icp1_set1_ref0.mask,
+                   agc_table->lna_icp1_set1_ref0.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x5B4 | lna_icp1_set1_ref1 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_icp1_set1_ref1.mask,
+                   agc_table->lna_icp1_set1_ref1.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x5B8 | lna_icp1_set1_ref2 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_icp1_set1_ref2.mask,
+                   agc_table->lna_icp1_set1_ref2.val);
+       cl_snprintf(buf, len, buf_size,
+                   "| 0x5BC | lna_icp1_set1_ref3 | 0x%08x | 0x%08x |\n",
+                   agc_table->lna_icp1_set1_ref3.mask,
+                   agc_table->lna_icp1_set1_ref3.val);
+
+       cl_snprintf(buf, len, buf_size,
+                   "|------------------------------------------------------|\n");
+}
+
+static int cl_agc_params_dump(struct cl_hw *cl_hw)
+{
+       struct cl_agc_params *agc_params =
+                                       &cl_hw->phy_data_info.data->agc_params;
+       char *buf = NULL;
+       ssize_t buf_size;
+       int err = 0;
+       int len = 0;
+
+       if (agc_params->profile1.id) {
+               cl_snprintf(&buf, &len, &buf_size, "AGC Params [%ug]\n", cl_hw->conf->ci_band_num);
+               _cl_agc_params_dump(cl_hw, &buf, &len, &buf_size, &agc_params->profile1);
+       }
+
+       if (agc_params->profile2.id) {
+               cl_snprintf(&buf, &len, &buf_size, "AGC Params [%ug elastic]",
+                           cl_hw->conf->ci_band_num);
+               _cl_agc_params_dump(cl_hw, &buf, &len, &buf_size, &agc_params->profile2);
+       }
+
+       err = cl_vendor_reply(cl_hw, buf, len);
+       kfree(buf);
+
+       return err;
+}
+
+static int cl_agc_params_print_table(struct cl_hw *cl_hw)
+{
+       struct cl_agc_table *table;
+       u32 platform_id;
+       u8 i;
+       char *buf = NULL;
+       ssize_t buf_size;
+       int err = 0;
+       int len = 0;
+
+       for (i = 0; i < ARRAY_SIZE(agc_table); i++) {
+               table = &agc_table[i];
+               platform_id = table->platform_id;
+
+               cl_snprintf(&buf, &len, &buf_size,
+                           "------------------------------------------------------\n");
+               cl_snprintf(&buf, &len, &buf_size, "Table #%u\n", i);
+               cl_snprintf(&buf, &len, &buf_size,
+                           "------------------------------------------------------\n");
+               cl_snprintf(&buf, &len, &buf_size, "Platform ID: 0x%08x\n", platform_id);
+               cl_snprintf(&buf, &len, &buf_size, "  - Customer = 0x%04x\n",
+                           AGC_PLATFORM_CUSTOMER(platform_id));
+               cl_snprintf(&buf, &len, &buf_size, "  - Board = 0x%02x\n",
+                           AGC_PLATFORM_BOARD(platform_id));
+               cl_snprintf(&buf, &len, &buf_size, "  - Chip = 0x%x\n",
+                           AGC_PLATFORM_CHIP(platform_id));
+               cl_snprintf(&buf, &len, &buf_size, "Description:\n");
+               cl_snprintf(&buf, &len, &buf_size, "  - %s\n", table->platform_description);
+               cl_snprintf(&buf, &len, &buf_size, "AGC Profile:\n");
+
+               cl_agc_params_print_profile(&buf, &len, &buf_size, table->agc_profile[TCV0],
+                                           "  - TCV0 =");
+               cl_agc_params_print_profile(&buf, &len, &buf_size,
+                                           table->agc_profile[TCV1], "  - TCV1 =");
+               cl_agc_params_print_profile(&buf, &len, &buf_size,
+                                           table->agc_profile_elastic[TCV0],
+                                           "  - Elastic TCV0 =");
+               cl_agc_params_print_profile(&buf, &len, &buf_size,
+                                           table->agc_profile_elastic[TCV1],
+                                           "  - Elastic TCV1 =");
+               cl_agc_params_print_profile(&buf, &len, &buf_size,
+                                           table->agc_profile_sensing, "  - Sensing =");
+       }
+
+       err = cl_vendor_reply(cl_hw, buf, len);
+       kfree(buf);
+
+       return err;
+}
+
+void cl_agc_params_print_profile(char **buf, int *len, ssize_t *buf_size,
+                                struct cl_agc_profile *profile,
+                                const char *str)
+{
+       u32 id;
+       u8 band, branch, version;
+
+       if (!profile)
+               return;
+
+       id = profile->id;
+
+       if (id == 0)
+               return;
+
+       band = AGC_PROFILE_BAND(id);
+       branch = AGC_PROFILE_BRANCH(id);
+       version = AGC_PROFILE_VERSION(id);
+
+       if (*buf)
+               cl_snprintf(buf, len, buf_size, "%s %u.%u.%u\n", str, band, branch, version);
+       else
+               pr_debug("%s %u.%u.%u\n", str, band, branch, version);
+}
+
+static int cl_agc_params_cli_help(struct cl_hw *cl_hw)
+{
+       char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+       int err = 0;
+
+       if (!buf)
+               return -ENOMEM;
+
+       snprintf(buf, PAGE_SIZE,
+                "agc_params usage:\n"
+                "-d : Dump AGC parameters\n"
+                "-t : Print AGC table\n");
+
+       err = cl_vendor_reply(cl_hw, buf, strlen(buf));
+       kfree(buf);
+
+       return err;
+}
+
+int cl_agc_params_cli(struct cl_hw *cl_hw, struct cli_params *cli_params)
+{
+       bool dump_params = false;
+       bool print_table = false;
+       u32 expected_params = -1;
+
+       switch (cli_params->option) {
+       case 'd':
+               dump_params = true;
+               expected_params = 0;
+               break;
+       case 't':
+               print_table = true;
+               expected_params = 0;
+               break;
+       case '?':
+               return cl_agc_params_cli_help(cl_hw);
+       default:
+               cl_dbg_err(cl_hw, "Illegal option (%c) - try '?' for help\n", cli_params->option);
+               goto out_err;
+       }
+
+       if (expected_params != cli_params->num_params) {
+               cl_dbg_err(cl_hw, "Wrong number of arguments (expected %u) (actual %u)\n",
+                          expected_params, cli_params->num_params);
+               goto out_err;
+       }
+
+       if (dump_params)
+               return cl_agc_params_dump(cl_hw);
+
+       if (print_table)
+               return cl_agc_params_print_table(cl_hw);
+
+out_err:
+       return -EIO;
+}
+