]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
brcmsmac: change lcnphy receive i/q calibration routine
[karo-tx-linux.git] / drivers / net / wireless / brcm80211 / brcmsmac / phy / phy_lcn.c
index 3d6b16ce46878979fd5104d1472fdaa9769b0e7e..236e8d90a5bc7460291e95b2cec26a9b9ccd96e2 100644 (file)
@@ -1137,8 +1137,9 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
        gain0_15 = ((biq1 & 0xf) << 12) |
                   ((tia & 0xf) << 8) |
                   ((lna2 & 0x3) << 6) |
-                  ((lna2 &
-                    0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
+                  ((lna2 & 0x3) << 4) |
+                  ((lna1 & 0x3) << 2) |
+                  ((lna1 & 0x3) << 0);
 
        mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
        mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
@@ -1328,6 +1329,43 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
        return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
 }
 
+static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain,
+                                     u16 tia_gain, u16 lna2_gain)
+{
+       u32 i_thresh_l, q_thresh_l;
+       u32 i_thresh_h, q_thresh_h;
+       struct lcnphy_iq_est iq_est_h, iq_est_l;
+
+       wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain,
+                                              lna2_gain, 0);
+
+       wlc_lcnphy_rx_gain_override_enable(pi, true);
+       wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
+       udelay(500);
+       write_radio_reg(pi, RADIO_2064_REG112, 0);
+       if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
+               return false;
+
+       wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
+       udelay(500);
+       write_radio_reg(pi, RADIO_2064_REG112, 0);
+       if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
+               return false;
+
+       i_thresh_l = (iq_est_l.i_pwr << 1);
+       i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr;
+
+       q_thresh_l = (iq_est_l.q_pwr << 1);
+       q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr;
+       if ((iq_est_h.i_pwr > i_thresh_l) &&
+           (iq_est_h.i_pwr < i_thresh_h) &&
+           (iq_est_h.q_pwr > q_thresh_l) &&
+           (iq_est_h.q_pwr < q_thresh_h))
+               return true;
+
+       return false;
+}
+
 static bool
 wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
                     const struct lcnphy_rx_iqcomp *iqcomp,
@@ -1342,8 +1380,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
            RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
            rfoverride3_old, rfoverride3val_old, rfoverride4_old,
            rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
-       int tia_gain;
-       u32 received_power, rx_pwr_threshold;
+       int tia_gain, lna2_gain, biq1_gain;
+       bool set_gain;
        u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
        u16 values_to_save[11];
        s16 *ptr;
@@ -1368,126 +1406,125 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
                goto cal_done;
        }
 
-       if (module == 1) {
+       WARN_ON(module != 1);
+       tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+       wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
 
-               tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
-               wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+       for (i = 0; i < 11; i++)
+               values_to_save[i] =
+                       read_radio_reg(pi, rxiq_cal_rf_reg[i]);
+       Core1TxControl_old = read_phy_reg(pi, 0x631);
+
+       or_phy_reg(pi, 0x631, 0x0015);
+
+       RFOverride0_old = read_phy_reg(pi, 0x44c);
+       RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
+       rfoverride2_old = read_phy_reg(pi, 0x4b0);
+       rfoverride2val_old = read_phy_reg(pi, 0x4b1);
+       rfoverride3_old = read_phy_reg(pi, 0x4f9);
+       rfoverride3val_old = read_phy_reg(pi, 0x4fa);
+       rfoverride4_old = read_phy_reg(pi, 0x938);
+       rfoverride4val_old = read_phy_reg(pi, 0x939);
+       afectrlovr_old = read_phy_reg(pi, 0x43b);
+       afectrlovrval_old = read_phy_reg(pi, 0x43c);
+       old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+       old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
 
-               for (i = 0; i < 11; i++)
-                       values_to_save[i] =
-                               read_radio_reg(pi, rxiq_cal_rf_reg[i]);
-               Core1TxControl_old = read_phy_reg(pi, 0x631);
-
-               or_phy_reg(pi, 0x631, 0x0015);
-
-               RFOverride0_old = read_phy_reg(pi, 0x44c);
-               RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
-               rfoverride2_old = read_phy_reg(pi, 0x4b0);
-               rfoverride2val_old = read_phy_reg(pi, 0x4b1);
-               rfoverride3_old = read_phy_reg(pi, 0x4f9);
-               rfoverride3val_old = read_phy_reg(pi, 0x4fa);
-               rfoverride4_old = read_phy_reg(pi, 0x938);
-               rfoverride4val_old = read_phy_reg(pi, 0x939);
-               afectrlovr_old = read_phy_reg(pi, 0x43b);
-               afectrlovrval_old = read_phy_reg(pi, 0x43c);
-               old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
-               old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
-
-               tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
-               if (tx_gain_override_old) {
-                       wlc_lcnphy_get_tx_gain(pi, &old_gains);
-                       tx_gain_index_old = pi_lcn->lcnphy_current_index;
-               }
+       tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+       if (tx_gain_override_old) {
+               wlc_lcnphy_get_tx_gain(pi, &old_gains);
+               tx_gain_index_old = pi_lcn->lcnphy_current_index;
+       }
 
-               wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
+       wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
 
-               mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
-               mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
+       mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+       mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
 
-               mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
-               mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+       mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+       mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
 
-               write_radio_reg(pi, RADIO_2064_REG116, 0x06);
-               write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
-               write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
-               write_radio_reg(pi, RADIO_2064_REG098, 0x03);
-               write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
-               mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
-               write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
-               write_radio_reg(pi, RADIO_2064_REG114, 0x01);
-               write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
-               write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
-
-               mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
-               mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
-               mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
-               mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
-               mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
-               mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
-               mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
-               mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
-               mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
-               mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
-
-               mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
-               mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
-
-               wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
-               write_phy_reg(pi, 0x6da, 0xffff);
-               or_phy_reg(pi, 0x6db, 0x3);
-               wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
-               wlc_lcnphy_rx_gain_override_enable(pi, true);
-
-               tia_gain = 8;
-               rx_pwr_threshold = 950;
-               while (tia_gain > 0) {
-                       tia_gain -= 1;
-                       wlc_lcnphy_set_rx_gain_by_distribution(pi,
-                                                              0, 0, 2, 2,
-                                                              (u16)
-                                                              tia_gain, 1, 0);
-                       udelay(500);
+       write_radio_reg(pi, RADIO_2064_REG116, 0x06);
+       write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
+       write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
+       write_radio_reg(pi, RADIO_2064_REG098, 0x03);
+       write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
+       mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
+       write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
+       write_radio_reg(pi, RADIO_2064_REG114, 0x01);
+       write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
+       write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
+
+       mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
+       mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
+       mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
+       mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
+       mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
+       mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
+       mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
+       mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
+       mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
+       mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
 
-                       received_power =
-                               wlc_lcnphy_measure_digital_power(pi, 2000);
-                       if (received_power < rx_pwr_threshold)
-                               break;
-               }
-               result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
+       mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
+       mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
 
-               wlc_lcnphy_stop_tx_tone(pi);
+       write_phy_reg(pi, 0x6da, 0xffff);
+       or_phy_reg(pi, 0x6db, 0x3);
+
+       wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
+       for (lna2_gain = 3; lna2_gain >= 0; lna2_gain--) {
+               for (tia_gain = 4; tia_gain >= 0; tia_gain--) {
+                       for (biq1_gain = 6; biq1_gain >= 0; biq1_gain--) {
+                               set_gain = wlc_lcnphy_rx_iq_cal_gain(pi,
+                                                                    (u16)
+                                                                    biq1_gain,
+                                                                    (u16)
+                                                                    tia_gain,
+                                                                    (u16)
+                                                                    lna2_gain);
+                               if (!set_gain)
+                                       continue;
+
+                               result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024);
+                               goto stop_tone;
+                       }
+               }
+       }
 
-               write_phy_reg(pi, 0x631, Core1TxControl_old);
+stop_tone:
+       wlc_lcnphy_stop_tx_tone(pi);
 
-               write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
-               write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
-               write_phy_reg(pi, 0x4b0, rfoverride2_old);
-               write_phy_reg(pi, 0x4b1, rfoverride2val_old);
-               write_phy_reg(pi, 0x4f9, rfoverride3_old);
-               write_phy_reg(pi, 0x4fa, rfoverride3val_old);
-               write_phy_reg(pi, 0x938, rfoverride4_old);
-               write_phy_reg(pi, 0x939, rfoverride4val_old);
-               write_phy_reg(pi, 0x43b, afectrlovr_old);
-               write_phy_reg(pi, 0x43c, afectrlovrval_old);
-               write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
-               write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
+       write_phy_reg(pi, 0x631, Core1TxControl_old);
+
+       write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
+       write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
+       write_phy_reg(pi, 0x4b0, rfoverride2_old);
+       write_phy_reg(pi, 0x4b1, rfoverride2val_old);
+       write_phy_reg(pi, 0x4f9, rfoverride3_old);
+       write_phy_reg(pi, 0x4fa, rfoverride3val_old);
+       write_phy_reg(pi, 0x938, rfoverride4_old);
+       write_phy_reg(pi, 0x939, rfoverride4val_old);
+       write_phy_reg(pi, 0x43b, afectrlovr_old);
+       write_phy_reg(pi, 0x43c, afectrlovrval_old);
+       write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
+       write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
 
-               wlc_lcnphy_clear_trsw_override(pi);
+       wlc_lcnphy_clear_trsw_override(pi);
 
-               mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
+       mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
 
-               for (i = 0; i < 11; i++)
-                       write_radio_reg(pi, rxiq_cal_rf_reg[i],
-                                       values_to_save[i]);
+       for (i = 0; i < 11; i++)
+               write_radio_reg(pi, rxiq_cal_rf_reg[i],
+                               values_to_save[i]);
 
-               if (tx_gain_override_old)
-                       wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
-               else
-                       wlc_lcnphy_disable_tx_gain_override(pi);
+       if (tx_gain_override_old)
+               wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
+       else
+               wlc_lcnphy_disable_tx_gain_override(pi);
 
-               wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
-               wlc_lcnphy_rx_gain_override_enable(pi, false);
-       }
+       wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
+       wlc_lcnphy_rx_gain_override_enable(pi, false);
 
 cal_done:
        kfree(ptr);
@@ -4283,13 +4320,10 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
        u16 pa_gain;
        u16 gm_gain;
 
-       if (CHSPEC_IS5G(pi->radio_chanspec))
-               pa_gain = 0x70;
-       else
-               pa_gain = 0x70;
-
        if (pi->sh->boardflags & BFL_FEM)
                pa_gain = 0x10;
+       else
+               pa_gain = 0x60;
        tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
        tab.tbl_width = 32;
        tab.tbl_len = 1;