Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 66a34c66 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau
Browse files

mt76x0: phy: add phy/vco temperature compensation



Introduce phy/vco temperature calibration.
Moreover fix configuration of register 67 on bank0
during temperature reading and use mt76_poll utility routine
to poll core34 register.
Furthermore temperature compensation needs to be disabled
if the device supports tssi compensation.
This issue has never been hit since temperature reading is not
actually used by usb code.

Fixes: 10de7a8b ("mt76x0: phy files")
Signed-off-by: default avatarLorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 4afeb396
Loading
Loading
Loading
Loading
+23 −25
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@
 * GNU General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/etherdevice.h>

#include "mt76x0.h"
#include "mcu.h"
#include "eeprom.h"
@@ -23,8 +26,6 @@
#include "initvals_phy.h"
#include "../mt76x02_phy.h"

#include <linux/etherdevice.h>

static int
mt76x0_rf_csr_wr(struct mt76x02_dev *dev, u32 offset, u8 value)
{
@@ -782,45 +783,41 @@ void mt76x0_agc_restore(struct mt76x02_dev *dev)
static void mt76x0_temp_sensor(struct mt76x02_dev *dev)
{
	u8 rf_b7_73, rf_b0_66, rf_b0_67;
	int cycle, temp;
	u32 val;
	s32 sval;
	s8 val;

	rf_b7_73 = rf_rr(dev, MT_RF(7, 73));
	rf_b0_66 = rf_rr(dev, MT_RF(0, 66));
	rf_b0_67 = rf_rr(dev, MT_RF(0, 73));
	rf_b0_67 = rf_rr(dev, MT_RF(0, 67));

	rf_wr(dev, MT_RF(7, 73), 0x02);
	rf_wr(dev, MT_RF(0, 66), 0x23);
	rf_wr(dev, MT_RF(0, 73), 0x01);
	rf_wr(dev, MT_RF(0, 67), 0x01);

	mt76_wr(dev, MT_BBP(CORE, 34), 0x00080055);

	for (cycle = 0; cycle < 2000; cycle++) {
		val = mt76_rr(dev, MT_BBP(CORE, 34));
		if (!(val & 0x10))
			break;
		udelay(3);
	}

	if (cycle >= 2000) {
		val &= 0x10;
		mt76_wr(dev, MT_BBP(CORE, 34), val);
	if (!mt76_poll(dev, MT_BBP(CORE, 34), BIT(4), 0, 2000)) {
		mt76_clear(dev, MT_BBP(CORE, 34), BIT(4));
		goto done;
	}

	sval = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
	if (!(sval & 0x80))
		sval &= 0x7f; /* Positive */
	else
		sval |= 0xffffff00; /* Negative */
	val = mt76_rr(dev, MT_BBP(CORE, 35));
	val = (35 * (val - dev->cal.rx.temp_offset)) / 10 + 25;

	temp = (35 * (sval - dev->cal.rx.temp_offset)) / 10 + 25;
	if (abs(val - dev->cal.temp_vco) > 20) {
		mt76x02_mcu_calibrate(dev, MCU_CAL_VCO,
				      dev->mt76.chandef.chan->hw_value,
				      false);
		dev->cal.temp_vco = val;
	}
	if (abs(val - dev->cal.temp) > 30) {
		mt76x0_phy_calibrate(dev, false);
		dev->cal.temp = val;
	}

done:
	rf_wr(dev, MT_RF(7, 73), rf_b7_73);
	rf_wr(dev, MT_RF(0, 66), rf_b0_66);
	rf_wr(dev, MT_RF(0, 73), rf_b0_67);
	rf_wr(dev, MT_RF(0, 67), rf_b0_67);
}

static void mt76x0_dynamic_vga_tuning(struct mt76x02_dev *dev)
@@ -848,6 +845,7 @@ static void mt76x0_phy_calibration_work(struct work_struct *work)
					       cal_work.work);

	mt76x0_dynamic_vga_tuning(dev);
	if (!mt76x0_tssi_enabled(dev))
		mt76x0_temp_sensor(dev);

	ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
+2 −1
Original line number Diff line number Diff line
@@ -55,7 +55,8 @@ struct mt76x02_calibration {
	s8 agc_gain_adjust;
	s8 low_gain;

	u8 temp;
	s8 temp_vco;
	s8 temp;

	bool init_cal_done;
	bool tssi_cal_done;