Path: blob/master/ALFA-W1F1/RTL8814AU/hal/phydm/phydm_direct_bf.c
1307 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* The full GNU General Public License is included in this distribution in the14* file called LICENSE.15*16* Contact Information:17* wlanfae <[email protected]>18* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,19* Hsinchu 300, Taiwan.20*21* Larry Finger <[email protected]>22*23*****************************************************************************/2425/*@************************************************************26* include files27***************************************************************/2829#include "mp_precomp.h"30#include "phydm_precomp.h"31#ifdef CONFIG_DIRECTIONAL_BF32#ifdef PHYDM_COMPILE_IC_2SS33void phydm_iq_gen_en(void *dm_void)34{35struct dm_struct *dm = (struct dm_struct *)dm_void;36enum rf_path i = RF_PATH_A;37enum rf_path path = RF_PATH_A;3839#if (ODM_IC_11AC_SERIES_SUPPORT)40if (dm->support_ic_type & ODM_RTL8822B) {41for (i = RF_PATH_A; i <= RF_PATH_B; i++) {42/*RF mode table write enable*/43odm_set_rf_reg(dm, path, RF_0xef, BIT(19), 0x1);44/*Select RX mode*/45odm_set_rf_reg(dm, path, RF_0x33, 0xF, 3);46/*Set Table data*/47odm_set_rf_reg(dm, path, RF_0x3e, 0xfffff, 0x00036);48/*Set Table data*/49odm_set_rf_reg(dm, path, RF_0x3f, 0xfffff, 0x5AFCE);50/*RF mode table write disable*/51odm_set_rf_reg(dm, path, RF_0xef, BIT(19), 0x0);52}53}54#endif5556#if (ODM_IC_11N_SERIES_SUPPORT)57if (dm->support_ic_type & ODM_RTL8192F) {58/*RF mode table write enable*/59odm_set_rf_reg(dm, RF_PATH_A, RF_0xef, 0x80000, 0x1);60odm_set_rf_reg(dm, RF_PATH_B, RF_0xef, 0x80000, 0x1);61/* Path A */62odm_set_rf_reg(dm, RF_PATH_A, RF_0x30, 0xfffff, 0x08000);63odm_set_rf_reg(dm, RF_PATH_A, RF_0x31, 0xfffff, 0x0005f);64odm_set_rf_reg(dm, RF_PATH_A, RF_0x32, 0xfffff, 0x01042);65odm_set_rf_reg(dm, RF_PATH_A, RF_0x30, 0xfffff, 0x18000);66odm_set_rf_reg(dm, RF_PATH_A, RF_0x31, 0xfffff, 0x0004f);67odm_set_rf_reg(dm, RF_PATH_A, RF_0x32, 0xfffff, 0x71fc2);68/* Path B */69odm_set_rf_reg(dm, RF_PATH_B, RF_0x30, 0xfffff, 0x08000);70odm_set_rf_reg(dm, RF_PATH_B, RF_0x31, 0xfffff, 0x00050);71odm_set_rf_reg(dm, RF_PATH_B, RF_0x32, 0xfffff, 0x01042);72odm_set_rf_reg(dm, RF_PATH_B, RF_0x30, 0xfffff, 0x18000);73odm_set_rf_reg(dm, RF_PATH_B, RF_0x31, 0xfffff, 0x00040);74odm_set_rf_reg(dm, RF_PATH_B, RF_0x32, 0xfffff, 0x71fc2);75/*RF mode table write disable*/76odm_set_rf_reg(dm, RF_PATH_A, RF_0xef, 0x80000, 0x0);77odm_set_rf_reg(dm, RF_PATH_B, RF_0xef, 0x80000, 0x0);78}79#endif8081#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT82if (dm->support_ic_type & ODM_RTL8197G) {83/*RF mode table write enable*/84/* Path A */85odm_set_rf_reg(dm, RF_PATH_A, RF_0xef, 0x80000, 0x1);86odm_set_rf_reg(dm, RF_PATH_A, RF_0x30, 0xfffff, 0x18000);87odm_set_rf_reg(dm, RF_PATH_A, RF_0x31, 0xfffff, 0x000cf);88odm_set_rf_reg(dm, RF_PATH_A, RF_0x32, 0xfffff, 0x71fc2);89odm_set_rf_reg(dm, RF_PATH_A, RF_0xef, 0x80000, 0x0);9091/* Path B */92odm_set_rf_reg(dm, RF_PATH_B, RF_0xef, 0x80000, 0x1);93odm_set_rf_reg(dm, RF_PATH_B, RF_0x30, 0xfffff, 0x18000);94odm_set_rf_reg(dm, RF_PATH_B, RF_0x31, 0xfffff, 0x000cf);95odm_set_rf_reg(dm, RF_PATH_B, RF_0x32, 0xfffff, 0x71fc2);96odm_set_rf_reg(dm, RF_PATH_B, RF_0x30, 0xfffff, 0x18000);97odm_set_rf_reg(dm, RF_PATH_B, RF_0x31, 0xfffff, 0x000ef);98odm_set_rf_reg(dm, RF_PATH_B, RF_0x32, 0xfffff, 0x01042);99odm_set_rf_reg(dm, RF_PATH_B, RF_0xef, 0x80000, 0x0);100}101#endif102103}104105void phydm_dis_cdd(void *dm_void)106{107struct dm_struct *dm = (struct dm_struct *)dm_void;108109#if (ODM_IC_11AC_SERIES_SUPPORT)110if (dm->support_ic_type & ODM_IC_11AC_SERIES) {111odm_set_bb_reg(dm, R_0x808, 0x3ffff00, 0);112odm_set_bb_reg(dm, R_0x9ac, 0x1fff, 0);113odm_set_bb_reg(dm, R_0x9ac, BIT(13), 1);114}115#endif116#if (ODM_IC_11N_SERIES_SUPPORT)117if (dm->support_ic_type & ODM_IC_11N_SERIES) {118odm_set_bb_reg(dm, R_0x90c, 0xffffffff, 0x83321333);119/* Set Tx delay setting for CCK pathA,B*/120odm_set_bb_reg(dm, R_0xa2c, 0xf0000000, 0);121/*Enable Tx CDD for HT part when spatial expansion is applied*/122odm_set_bb_reg(dm, R_0xd00, BIT(8), 0);123/* Tx CDD for Legacy*/124odm_set_bb_reg(dm, R_0xd04, 0xf0000, 0);125/* Tx CDD for non-HT*/126odm_set_bb_reg(dm, R_0xd0c, 0x3c0, 0);127/* Tx CDD for HT SS1*/128odm_set_bb_reg(dm, R_0xd0c, 0xf8000, 0);129}130#endif131#ifdef PHYDM_IC_JGR3_SERIES_SUPPORT132if (dm->support_ic_type & ODM_IC_JGR3_SERIES) {133/* Tx CDD for Legacy Preamble*/134odm_set_bb_reg(dm, R_0x1cc0, 0xffffffff, 0x24800000);135/* Tx CDD for HT Preamble*/136odm_set_bb_reg(dm, R_0x1cb0, 0xffffffff, 0);137}138#endif139}140141void phydm_pathb_q_matrix_rotate_en(void *dm_void)142{143struct dm_struct *dm = (struct dm_struct *)dm_void;144145phydm_iq_gen_en(dm);146147/*#ifdef PHYDM_COMMON_API_SUPPORT*/148/*path selection is controlled by driver*/149#if 0150if (!phydm_api_trx_mode(dm, BB_PATH_AB, BB_PATH_AB, BB_PATH_AB))151return;152#endif153154phydm_dis_cdd(dm);155phydm_pathb_q_matrix_rotate(dm, 0);156157#if (ODM_IC_11AC_SERIES_SUPPORT)158if (dm->support_ic_type & ODM_IC_11AC_SERIES) {159/*Set Q matrix r_v11 =1*/160odm_set_bb_reg(dm, R_0x195c, MASKDWORD, 0x40000);161/*Set Q matrix enable*/162odm_set_bb_reg(dm, R_0x191c, BIT(7), 1);163}164#endif165}166167void phydm_pathb_q_matrix_rotate(void *dm_void, u16 idx)168{169struct dm_struct *dm = (struct dm_struct *)dm_void;170#if (ODM_IC_11AC_SERIES_SUPPORT)171u32 phase_table_0[ANGLE_NUM] = {0x40000, 0x376CF, 0x20000, 0x00000,1720xFE0000, 0xFC8930, 0xFC0000,1730xFC8930, 0xFDFFFF, 0x000000,1740x020000, 0x0376CF};175u32 phase_table_1[ANGLE_NUM] = {0x00000, 0x1FFFF, 0x376CF, 0x40000,1760x0376CF, 0x01FFFF, 0x000000,1770xFDFFFF, 0xFC8930, 0xFC0000,1780xFC8930, 0xFDFFFF};179#endif180#if (ODM_IC_11N_SERIES_SUPPORT)181u32 phase_table_n_0[ANGLE_NUM] = {0x00, 0x0B, 0x02, 0x00, 0x02, 0x02,1820x04, 0x02, 0x0D, 0x09, 0x04, 0x0B};183u32 phase_table_n_1[ANGLE_NUM] = {0x40000100, 0x377F00DD, 0x201D8880,1840x00000000, 0xE01D8B80, 0xC8BF0322,1850xC000FF00, 0xC8BF0322, 0xDFE2777F,1860xFFC003FF, 0x20227480, 0x377F00DD};187u32 phase_table_n_2[ANGLE_NUM] = {0x00, 0x1E, 0x3C, 0x4C, 0x3C, 0x1E,1880x0F, 0xD2, 0xC3, 0xC4, 0xC3, 0xD2};189#endif190if (idx >= ANGLE_NUM) {191pr_debug("[%s]warning Phase Set Error: %d\n", __func__, idx);192return;193}194195switch (dm->ic_ip_series) {196#if (ODM_IC_11AC_SERIES_SUPPORT == 1)197case PHYDM_IC_AC:198/*Set Q matrix r_v21*/199odm_set_bb_reg(dm, R_0x1954, 0xffffff, phase_table_0[idx]);200odm_set_bb_reg(dm, R_0x1950, 0xffffff, phase_table_1[idx]);201break;202#endif203204#if (ODM_IC_11N_SERIES_SUPPORT == 1)205case PHYDM_IC_N:206/*Set Q matrix r_v21*/207odm_set_bb_reg(dm, R_0xc4c, 0xff000000, phase_table_n_0[idx]);208odm_set_bb_reg(dm, R_0xc88, 0xffffffff, phase_table_n_1[idx]);209odm_set_bb_reg(dm, R_0xc9c, 0xff000000, phase_table_n_2[idx]);210break;211#endif212213default:214break;215}216}217218/*Before use this API, Fill correct Tx Des. and Disable STBC in advance*/219void phydm_set_direct_bfer(void *dm_void, u16 phs_idx, u8 su_idx)220{221struct dm_struct *dm = (struct dm_struct *)dm_void;222#if (RTL8822B_SUPPORT)223if (dm->support_ic_type & ODM_RTL8822B) {224#if 0225u8 phi[13] = {0x0, 0x5, 0xa, 0xf, 0x15, 0x1a, 0x1f, 0x25,2260x2a, 0x2f, 0x35, 0x3a, 0x0};227u8 psi[13] = {0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,2280x7, 0x7, 0x7, 0x7};229u16 psiphi[13] = {0x1c0, 0x1c5, 0x1ca, 0x1cf, 0x1d5, 0x1da,2300x1df, 0x1e5, 0x1ea, 0x1ef, 0x1f5, 0x1fa,2310x1c0}; //{Psi_4bit, Phi_6bit} of 0~360232#endif233u16 ns[3] = {52, 108, 234}; //20/40/80 MHz subcarrier number234u16 psiphi[13] = {0x1c0, 0x1c5, 0x1ca, 0x1cf, 0x1d5, 0x1da,2350x1df, 0x1e5, 0x1ea, 0x1ef, 0x1f5, 0x1fa,2360x1c0}; //{Psi_4bit, Phi_6bit} of 0~360237u16 psiphiR;238u8 i;239u8 snr = 0x12; // for 1SS BF240u8 nc = 0x0; //bit 2-0241u8 nr = 0x1; //bit 5-3242u8 ng = 0x0; //bit 7-6243u8 cb = 0x1; //bit 9-8; 1 => phi:6, psi:4;244u32 bw = odm_get_bb_reg(dm, R_0x8ac, 0x3); //bit 11-10245u8 userid = su_idx; //bit 12246u32 csi_report = 0x0;247u32 ndp_bw = odm_get_bb_reg(dm, R_0x8ac, 0x3); //bit 11-10248u8 ndp_sc = 0; //bit 11-10249u32 ndp_info = 0x0;250251u16 mem_num = 0;252u8 mem_move = 0;253u8 mem_sel = 0;254u16 mem_addr = 0;255u32 dw0, dw1;256u64 vm_info = 0;257u64 temp = 0;258u8 vm_cnt = 0;259260mem_num = ((8 + (6 + 4) * ns[bw]) >> 6) + 1; // SU codebook 1261262/* setting NDP BW/SC info*/263ndp_info = (ndp_bw & 0x3) | (ndp_bw & 0x3) << 6 |264(ndp_bw & 0x3) << 12 | (ndp_sc & 0xf) << 2 |265(ndp_sc & 0xf) << 8 | (ndp_sc & 0xf) << 14;266odm_set_bb_reg(dm, R_0xb58, 0x000FFFFC, ndp_info);267odm_set_bb_reg(dm, R_0x19f8, 0x00010000, 1);268ODM_delay_ms(1); // delay 1ms269odm_set_bb_reg(dm, R_0x19f8, 0x00010000, 0);270271/* setting CSI report info*/272csi_report = (userid & 0x1) << 12 | (bw & 0x3) << 10 |273(cb & 0x3) << 8 | (ng & 0x3) << 6 |274(nr & 0x7) << 3 | (nc & 0x7);275odm_set_bb_reg(dm, R_0x72c, 0x1FFF, csi_report);276odm_set_bb_reg(dm, R_0x71c, 0x80000000, 1);277PHYDM_DBG(dm, DBG_TXBF, "[%s] direct BF csi report 0x%x\n",278__func__, csi_report);279/*========================*/280281odm_set_bb_reg(dm, R_0x19b8, 0x40, 1); //0x19b8[6]:1 to csi_rpt282odm_set_bb_reg(dm, R_0x19e0, 0x3FC0, 0xFF); //gated_clk off283odm_set_bb_reg(dm, R_0x9e8, 0x2000000, 1); //abnormal txbf284odm_set_bb_reg(dm, R_0x9e8, 0x1000000, 0); //read phi psi285odm_set_bb_reg(dm, R_0x9e8, 0x70000000, su_idx); //SU user 0286odm_set_bb_reg(dm, R_0x1910, 0x8000, 0); //BFer287288dw0 = 0; // for 0x9ec289dw1 = 0; // for 0x1900290mem_addr = 0;291mem_sel = 0;292mem_move = 0;293vm_info = vm_info | (snr & 0xff); //V matrix info294vm_cnt = 8; // V matrix length counter295psiphiR = (psiphi[phs_idx] & 0x3ff);296297while (mem_addr < mem_num) {298while (vm_cnt <= 32) {299// shift only max. 32 bit300if (vm_cnt >= 20) {301temp = psiphiR << 20;302temp = temp << (vm_cnt - 20);303} else {304temp = psiphiR << vm_cnt;305}306vm_info |= temp;307vm_cnt += 10;308}309if (mem_sel == 0) {310dw0 = vm_info & 0xffffffff;311vm_info = vm_info >> 32;312vm_cnt -= 32;313mem_sel = 1;314mem_move = 0;315} else {316dw1 = vm_info & 0xffffffff;317vm_info = vm_info >> 32;318vm_cnt -= 32;319mem_sel = 0;320mem_move = 1;321}322if (mem_move == 1) {323odm_set_bb_reg(dm, 0x9e8, 0x1000000, 0);324//read phi psi325odm_set_bb_reg(dm, 0x1910, 0x3FF0000,326mem_addr);327odm_set_bb_reg(dm, 0x09ec, 0xFFFFFFFF, dw0);328odm_set_bb_reg(dm, 0x1900, 0xFFFFFFFF, dw1);329odm_set_bb_reg(dm, 0x9e8, 0x1000000, 1);330//write phi psi331mem_move = 0;332mem_addr += 1;333}334}335odm_set_bb_reg(dm, 0x9e8, 0x2000000, 0); //normal txbf336}337#endif338} //end function339340/*Before use this API, Disable STBC in advance*/341/*only 1SS rate can improve performance*/342void phydm_set_direct_bfer_txdesc_en(void *dm_void, u8 enable)343{344struct dm_struct *dm = (struct dm_struct *)dm_void;345#if (RTL8197G_SUPPORT)346if (dm->support_ic_type & ODM_RTL8197G) {347phydm_iq_gen_en(dm);348349/*#ifdef PHYDM_COMMON_API_SUPPORT*/350/*path selection is controlled by driver, use 1ss 2Tx*/351#if 0352if (!phydm_api_trx_mode(dm, BB_PATH_AB, BB_PATH_AB, BB_PATH_AB))353return;354#endif355356phydm_dis_cdd(dm);357if (enable)358odm_set_bb_reg(dm, R_0x1d90, 0x8000, 1);359else360odm_set_bb_reg(dm, R_0x1d90, 0x8000, 0);361}362#endif363} //end function364#endif365#endif366367368