Path: blob/master/ALFA-W1F1/RTL8814AU/hal/phydm/halrf/halrf_psd.c
1308 views
/******************************************************************************1*2* Copyright(c) 2007 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13*****************************************************************************/1415/*@===========================================================16* include files17*============================================================18*/19#include "mp_precomp.h"20#include "phydm_precomp.h"2122u64 _sqrt(u64 x)23{24u64 i = 0;25u64 j = (x >> 1) + 1;2627while (i <= j) {28u64 mid = (i + j) >> 1;2930u64 sq = mid * mid;3132if (sq == x)33return mid;34else if (sq < x)35i = mid + 1;36else37j = mid - 1;38}3940return j;41}4243u32 halrf_get_psd_data(44struct dm_struct *dm,45u32 point)46{47struct _hal_rf_ *rf = &(dm->rf_table);48struct _halrf_psd_data *psd = &(rf->halrf_psd_data);49u32 psd_val = 0, psd_reg, psd_report, psd_point, psd_start, i, delay_time = 0;5051#if (DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)52if (dm->support_interface == ODM_ITRF_USB || dm->support_interface == ODM_ITRF_SDIO) {53if (psd->average == 0)54delay_time = 100;55else56delay_time = 0;57}58#endif59#if (DEV_BUS_TYPE == RT_PCI_INTERFACE)60if (dm->support_interface == ODM_ITRF_PCIE) {61if (psd->average == 0)62delay_time = 1000;63else64delay_time = 100;65}66#endif6768if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C)) {69psd_reg = R_0x910;70psd_report = R_0xf44;71} else {72psd_reg = R_0x808;73psd_report = R_0x8b4;74}7576if (dm->support_ic_type & ODM_RTL8710B) {77psd_point = 0xeffffc00;78psd_start = 0x10000000;79} else {80psd_point = 0xffbffc00;81psd_start = 0x00400000;82}8384psd_val = odm_get_bb_reg(dm, psd_reg, MASKDWORD);8586psd_val &= psd_point;87psd_val |= point;8889odm_set_bb_reg(dm, psd_reg, MASKDWORD, psd_val);9091psd_val |= psd_start;9293odm_set_bb_reg(dm, psd_reg, MASKDWORD, psd_val);9495for (i = 0; i < delay_time; i++)96ODM_delay_us(1);9798psd_val = odm_get_bb_reg(dm, psd_report, MASKDWORD);99100if (dm->support_ic_type & (ODM_RTL8821C | ODM_RTL8710B)) {101psd_val &= MASKL3BYTES;102psd_val = psd_val / 32;103} else {104psd_val &= MASKLWORD;105}106107return psd_val;108}109110void halrf_psd(111struct dm_struct *dm,112u32 point,113u32 start_point,114u32 stop_point,115u32 average)116{117struct _hal_rf_ *rf = &(dm->rf_table);118struct _halrf_psd_data *psd = &(rf->halrf_psd_data);119120u32 i = 0, j = 0, k = 0;121u32 psd_reg, avg_org, point_temp, average_tmp, mode;122u64 data_tatal = 0, data_temp[64] = {0};123124psd->buf_size = 256;125126mode = average >> 16;127128if (mode == 2)129average_tmp = 1;130else131average_tmp = average & 0xffff;132133if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C))134psd_reg = R_0x910;135else136psd_reg = R_0x808;137138#if 0139dbg_print("[PSD]point=%d, start_point=%d, stop_point=%d, average=%d, average_tmp=%d, buf_size=%d\n",140point, start_point, stop_point, average, average_tmp, psd->buf_size);141#endif142143for (i = 0; i < psd->buf_size; i++)144psd->psd_data[i] = 0;145146if (dm->support_ic_type & ODM_RTL8710B)147avg_org = odm_get_bb_reg(dm, psd_reg, 0x30000);148else149avg_org = odm_get_bb_reg(dm, psd_reg, 0x3000);150151if (mode == 1) {152if (dm->support_ic_type & ODM_RTL8710B)153odm_set_bb_reg(dm, psd_reg, 0x30000, 0x1);154else155odm_set_bb_reg(dm, psd_reg, 0x3000, 0x1);156}157158#if 0159if (avg_temp == 0)160avg = 1;161else if (avg_temp == 1)162avg = 8;163else if (avg_temp == 2)164avg = 16;165else if (avg_temp == 3)166avg = 32;167#endif168169i = start_point;170while (i < stop_point) {171data_tatal = 0;172173if (i >= point)174point_temp = i - point;175else176point_temp = i;177178for (k = 0; k < average_tmp; k++) {179data_temp[k] = halrf_get_psd_data(dm, point_temp);180data_tatal = data_tatal + (data_temp[k] * data_temp[k]);181182#if 0183if ((k % 20) == 0)184dbg_print("\n ");185186dbg_print("0x%x ", data_temp[k]);187#endif188}189#if 0190/*dbg_print("\n");*/191#endif192193data_tatal = phydm_division64((data_tatal * 100), average_tmp);194psd->psd_data[j] = (u32)_sqrt(data_tatal);195196i++;197j++;198}199200#if 0201for (i = 0; i < psd->buf_size; i++) {202if ((i % 20) == 0)203dbg_print("\n ");204205dbg_print("0x%x ", psd->psd_data[i]);206}207dbg_print("\n\n");208#endif209210if (dm->support_ic_type & ODM_RTL8710B)211odm_set_bb_reg(dm, psd_reg, 0x30000, avg_org);212else213odm_set_bb_reg(dm, psd_reg, 0x3000, avg_org);214}215216void backup_bb_register(struct dm_struct *dm, u32 *bb_backup, u32 *backup_bb_reg, u32 counter)217{218u32 i ;219220for (i = 0; i < counter; i++)221bb_backup[i] = odm_get_bb_reg(dm, backup_bb_reg[i], MASKDWORD);222}223224void restore_bb_register(struct dm_struct *dm, u32 *bb_backup, u32 *backup_bb_reg, u32 counter)225{226u32 i ;227228for (i = 0; i < counter; i++)229odm_set_bb_reg(dm, backup_bb_reg[i], MASKDWORD, bb_backup[i]);230}231232233234void _halrf_psd_iqk_init(struct dm_struct *dm)235{236odm_set_bb_reg(dm, 0x1b04, MASKDWORD, 0x0);237odm_set_bb_reg(dm, 0x1b08, MASKDWORD, 0x80);238odm_set_bb_reg(dm, 0x1b0c, 0xc00, 0x3);239odm_set_bb_reg(dm, 0x1b14, MASKDWORD, 0x0);240odm_set_bb_reg(dm, 0x1b18, BIT(0), 0x1);241242if (dm->support_ic_type & ODM_RTL8197G)243odm_set_bb_reg(dm, 0x1b20, MASKDWORD, 0x00040008);244if (dm->support_ic_type & ODM_RTL8198F)245odm_set_bb_reg(dm, 0x1b20, MASKDWORD, 0x00000000);246247if (dm->support_ic_type & (ODM_RTL8197G | ODM_RTL8198F)) {248odm_set_bb_reg(dm, 0x1b24, MASKDWORD, 0x00030000);249odm_set_bb_reg(dm, 0x1b28, MASKDWORD, 0x00000000);250odm_set_bb_reg(dm, 0x1b2c, MASKDWORD, 0x00180018);251odm_set_bb_reg(dm, 0x1b30, MASKDWORD, 0x20000000);252/*odm_set_bb_reg(dm, 0x1b38, MASKDWORD, 0x20000000);*/253/*odm_set_bb_reg(dm, 0x1b3c, MASKDWORD, 0x20000000);*/254}255256odm_set_bb_reg(dm, 0x1b1c, 0xfff, 0xd21);257odm_set_bb_reg(dm, 0x1b1c, 0xfff00000, 0x821);258odm_set_bb_reg(dm, 0x1b28, MASKDWORD, 0x0);259odm_set_bb_reg(dm, 0x1bcc, 0x3f, 0x3f);260}261262263u32 halrf_get_iqk_psd_data(264struct dm_struct *dm,265u32 point)266{267struct _hal_rf_ *rf = &(dm->rf_table);268struct _halrf_psd_data *psd = &(rf->halrf_psd_data);269u32 psd_val, psd_val1, psd_val2, psd_point, i, delay_time = 0;270271#if (DEV_BUS_TYPE == RT_USB_INTERFACE) || (DEV_BUS_TYPE == RT_SDIO_INTERFACE)272if (dm->support_interface == ODM_ITRF_USB || dm->support_interface == ODM_ITRF_SDIO) {273if (dm->support_ic_type & ODM_RTL8822C)274delay_time = 1000;275else276delay_time = 0;277}278#endif279#if (DEV_BUS_TYPE == RT_PCI_INTERFACE)280if (dm->support_interface == ODM_ITRF_PCIE) {281if (dm->support_ic_type & ODM_RTL8822C)282delay_time = 1000;283else284delay_time = 150;285}286#endif287psd_point = odm_get_bb_reg(dm, R_0x1b2c, MASKDWORD);288289psd_point &= 0xF000FFFF;290291point &= 0xFFF;292293psd_point = psd_point | (point << 16);294295odm_set_bb_reg(dm, R_0x1b2c, MASKDWORD, psd_point);296297odm_set_bb_reg(dm, R_0x1b34, BIT(0), 0x1);298299odm_set_bb_reg(dm, R_0x1b34, BIT(0), 0x0);300301for (i = 0; i < delay_time; i++)302ODM_delay_us(1);303304if (dm->support_ic_type & (ODM_RTL8197G | ODM_RTL8198F)) {305if (dm->support_ic_type & ODM_RTL8197G)306odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x001a0001);307else308odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x00250001);309310psd_val1 = odm_get_bb_reg(dm, R_0x1bfc, MASKDWORD);311312psd_val1 = (psd_val1 & 0x001f0000) >> 16;313314if (dm->support_ic_type & ODM_RTL8197G)315odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x001b0001);316else317odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x002e0001);318319psd_val2 = odm_get_bb_reg(dm, R_0x1bfc, MASKDWORD);320321psd_val = (psd_val1 << 27) + (psd_val2 >> 5);322} else {323odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x00250001);324325psd_val1 = odm_get_bb_reg(dm, R_0x1bfc, MASKDWORD);326327psd_val1 = (psd_val1 & 0x07FF0000) >> 16;328329odm_set_bb_reg(dm, R_0x1bd4, MASKDWORD, 0x002e0001);330331psd_val2 = odm_get_bb_reg(dm, R_0x1bfc, MASKDWORD);332333psd_val = (psd_val1 << 21) + (psd_val2 >> 11);334}335336return psd_val;337}338339void halrf_iqk_psd(340struct dm_struct *dm,341u32 point,342u32 start_point,343u32 stop_point,344u32 average)345{346struct _hal_rf_ *rf = &(dm->rf_table);347struct _halrf_psd_data *psd = &(rf->halrf_psd_data);348349u32 i = 0, j = 0, k = 0;350u32 psd_reg, avg_org, point_temp, average_tmp = 32, mode, reg_tmp = 5;351u64 data_tatal = 0, data_temp[64] = {0};352s32 s_point_tmp;353354psd->buf_size = 256;355356mode = average >> 16;357358if (mode == 2) {359if (dm->support_ic_type & ODM_RTL8822C)360average_tmp = 1;361else {362reg_tmp = odm_get_bb_reg(dm, R_0x1b1c, 0x000e0000);363if (reg_tmp == 0)364average_tmp = 1;365else if (reg_tmp == 3)366average_tmp = 8;367else if (reg_tmp == 4)368average_tmp = 16;369else if (reg_tmp == 5)370average_tmp = 32;371odm_set_bb_reg(dm, R_0x1b1c, 0x000e0000, 0x0);372}373} else {374reg_tmp = odm_get_bb_reg(dm, R_0x1b1c, 0x000e0000);375if (reg_tmp == 0)376average_tmp = 1;377else if (reg_tmp == 3)378average_tmp = 8;379else if (reg_tmp == 4)380average_tmp = 16;381else if (reg_tmp == 5)382average_tmp = 32;383odm_set_bb_reg(dm, R_0x1b1c, 0x000e0000, 0x0);384}385386#if 0387DbgPrint("[PSD]point=%d, start_point=%d, stop_point=%d, average=0x%x, average_tmp=%d, buf_size=%d, mode=%d\n",388point, start_point, stop_point, average, average_tmp, psd->buf_size, mode);389#endif390391for (i = 0; i < psd->buf_size; i++)392psd->psd_data[i] = 0;393394i = start_point;395while (i < stop_point) {396data_tatal = 0;397398if (i >= point)399point_temp = i - point;400else401{402if (dm->support_ic_type & ODM_RTL8814B)403{404s_point_tmp = i - point - 1;405point_temp = s_point_tmp & 0xfff;406}407else408point_temp = i;409}410411for (k = 0; k < average_tmp; k++) {412data_temp[k] = halrf_get_iqk_psd_data(dm, point_temp);413/*data_tatal = data_tatal + (data_temp[k] * data_temp[k]);*/414data_tatal = data_tatal + data_temp[k];415416#if 0417if ((k % 20) == 0)418DbgPrint("\n ");419420DbgPrint("0x%x ", data_temp[k]);421#endif422}423424data_tatal = phydm_division64((data_tatal * 10), average_tmp);425psd->psd_data[j] = (u32)data_tatal;426427i++;428j++;429}430431if (dm->support_ic_type & (ODM_RTL8814B | ODM_RTL8198F | ODM_RTL8197G))432odm_set_bb_reg(dm, R_0x1b1c, 0x000e0000, reg_tmp);433434#if 0435DbgPrint("\n [iqk psd]psd result:\n");436437for (i = 0; i < psd->buf_size; i++) {438if ((i % 20) == 0)439DbgPrint("\n ");440441DbgPrint("0x%x ", psd->psd_data[i]);442}443DbgPrint("\n\n");444#endif445}446447448u32449halrf_psd_init(450void *dm_void)451{452enum rt_status ret_status = RT_STATUS_SUCCESS;453struct dm_struct *dm = (struct dm_struct *)dm_void;454struct _hal_rf_ *rf = &(dm->rf_table);455struct _halrf_psd_data *psd = &(rf->halrf_psd_data);456457#if 0458u32 bb_backup[12];459u32 backup_bb_reg[12] = {0x1b04, 0x1b08, 0x1b0c, 0x1b14, 0x1b18,4600x1b1c, 0x1b28, 0x1bcc, 0x1b2c, 0x1b34,4610x1bd4, 0x1bfc};462#endif463464if (psd->psd_progress) {465ret_status = RT_STATUS_PENDING;466} else {467psd->psd_progress = 1;468if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8198F | ODM_RTL8197G)) {469/*backup_bb_register(dm, bb_backup, backup_bb_reg, 12);*/470_halrf_psd_iqk_init(dm);471halrf_iqk_psd(dm, psd->point, psd->start_point, psd->stop_point, psd->average);472/*restore_bb_register(dm, bb_backup, backup_bb_reg, 12);*/473} else474halrf_psd(dm, psd->point, psd->start_point, psd->stop_point, psd->average);475psd->psd_progress = 0;476}477return ret_status;478}479480u32481halrf_psd_query(482void *dm_void,483u32 *outbuf,484u32 buf_size)485{486enum rt_status ret_status = RT_STATUS_SUCCESS;487struct dm_struct *dm = (struct dm_struct *)dm_void;488struct _hal_rf_ *rf = &(dm->rf_table);489struct _halrf_psd_data *psd = &(rf->halrf_psd_data);490491if (psd->psd_progress)492ret_status = RT_STATUS_PENDING;493else494odm_move_memory(dm, outbuf, psd->psd_data,495sizeof(u32) * psd->buf_size);496497return ret_status;498}499500u32501halrf_psd_init_query(502void *dm_void,503u32 *outbuf,504u32 point,505u32 start_point,506u32 stop_point,507u32 average,508u32 buf_size)509{510enum rt_status ret_status = RT_STATUS_SUCCESS;511struct dm_struct *dm = (struct dm_struct *)dm_void;512struct _hal_rf_ *rf = &(dm->rf_table);513struct _halrf_psd_data *psd = &(rf->halrf_psd_data);514515psd->point = point;516psd->start_point = start_point;517psd->stop_point = stop_point;518psd->average = average;519520if (psd->psd_progress) {521ret_status = RT_STATUS_PENDING;522} else {523psd->psd_progress = 1;524halrf_psd(dm, psd->point, psd->start_point, psd->stop_point, psd->average);525odm_move_memory(dm, outbuf, psd->psd_data, 0x400);526psd->psd_progress = 0;527}528529return ret_status;530}531532533