diff mbox series

[7/7] rtw88: 8821c: add phy calibration

Message ID 20200520052335.22466-8-yhchuang@realtek.com (mailing list archive)
State Changes Requested
Delegated to: Kalle Valo
Headers show
Series None | expand

Commit Message

Tony Chuang May 20, 2020, 5:23 a.m. UTC
From: Tzu-En Huang <tehuang@realtek.com>

In order to get a better tramit EVM, we need to perform calibration
after association.
The calibration needed for 8821c is called iq calibration, which is
done in firmware. Implement the callback function for triggering
firmware to do it.

Signed-off-by: Tzu-En Huang <tehuang@realtek.com>
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
---
 drivers/net/wireless/realtek/rtw88/rtw8821c.c | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

Comments

Sebastian Andrzej Siewior May 28, 2020, 4:27 p.m. UTC | #1
On 2020-05-20 13:23:35 [+0800], yhchuang@realtek.com wrote:
> From: Tzu-En Huang <tehuang@realtek.com>
> 
> In order to get a better tramit EVM, we need to perform calibration

s/tramit/transmit/ ?

> after association.
> The calibration needed for 8821c is called iq calibration, which is
> done in firmware. Implement the callback function for triggering
> firmware to do it.
> 
> Signed-off-by: Tzu-En Huang <tehuang@realtek.com>
> Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
> ---
>  drivers/net/wireless/realtek/rtw88/rtw8821c.c | 34 +++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
> index 7169e6fb9ca9..749569eab912 100644
> --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
> +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
> @@ -555,6 +555,39 @@ static void rtw8821c_false_alarm_statistics(struct rtw_dev *rtwdev)
>  	rtw_write32_clr(rtwdev, 0xb58, BIT(0));
>  }
>  
> +static void rtw8821c_do_iqk(struct rtw_dev *rtwdev)
> +{
> +	static int do_iqk_cnt;
> +	struct rtw_iqk_para para = {.clear = 0, .segment_iqk = 0};
> +	u32 rf_reg, iqk_fail_mask;
> +	int counter;
> +	bool reload;
> +
> +	if (rtw_is_assoc(rtwdev))
> +		para.segment_iqk = 1;
> +
> +	rtw_fw_do_iqk(rtwdev, &para);
> +
> +	for (counter = 0; counter < 300; counter++) {
> +		rf_reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK);
> +		if (rf_reg == 0xabcde)
> +			break;
> +		msleep(20);
> +	}
> +	rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0);
> +
> +	reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16));
> +	iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7, 0));
> +	rtw_dbg(rtwdev, RTW_DBG_PHY,
> +		"iqk counter=%d reload=%d do_iqk_cnt=%d n_iqk_fail(mask)=0x%02x\n",
> +		counter, reload, ++do_iqk_cnt, iqk_fail_mask);
> +}
> +
> +static void rtw8821c_phy_calibration(struct rtw_dev *rtwdev)
> +{
> +	rtw8821c_do_iqk(rtwdev);

Why this extra step? You could name it rtw8821c_phy_calibration_iqk().

> +}
> +

Sebastian
Tony Chuang May 29, 2020, 6:31 a.m. UTC | #2
> On 2020-05-20 13:23:35 [+0800], yhchuang@realtek.com wrote:
> > From: Tzu-En Huang <tehuang@realtek.com>
> >
> > In order to get a better tramit EVM, we need to perform calibration
> 
> s/tramit/transmit/ ?
> 
> > after association.
> > The calibration needed for 8821c is called iq calibration, which is
> > done in firmware. Implement the callback function for triggering
> > firmware to do it.
> >
> > Signed-off-by: Tzu-En Huang <tehuang@realtek.com>
> > Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
> > ---
> >  drivers/net/wireless/realtek/rtw88/rtw8821c.c | 34
> +++++++++++++++++++
> >  1 file changed, 34 insertions(+)
> >
> > diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
> b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
> > index 7169e6fb9ca9..749569eab912 100644
> > --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
> > +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
> > @@ -555,6 +555,39 @@ static void rtw8821c_false_alarm_statistics(struct
> rtw_dev *rtwdev)
> >  	rtw_write32_clr(rtwdev, 0xb58, BIT(0));
> >  }
> >
> > +static void rtw8821c_do_iqk(struct rtw_dev *rtwdev)
> > +{
> > +	static int do_iqk_cnt;
> > +	struct rtw_iqk_para para = {.clear = 0, .segment_iqk = 0};
> > +	u32 rf_reg, iqk_fail_mask;
> > +	int counter;
> > +	bool reload;
> > +
> > +	if (rtw_is_assoc(rtwdev))
> > +		para.segment_iqk = 1;
> > +
> > +	rtw_fw_do_iqk(rtwdev, &para);
> > +
> > +	for (counter = 0; counter < 300; counter++) {
> > +		rf_reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK,
> RFREG_MASK);
> > +		if (rf_reg == 0xabcde)
> > +			break;
> > +		msleep(20);
> > +	}
> > +	rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0);
> > +
> > +	reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16));
> > +	iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7,
> 0));
> > +	rtw_dbg(rtwdev, RTW_DBG_PHY,
> > +		"iqk counter=%d reload=%d do_iqk_cnt=%d
> n_iqk_fail(mask)=0x%02x\n",
> > +		counter, reload, ++do_iqk_cnt, iqk_fail_mask);
> > +}
> > +
> > +static void rtw8821c_phy_calibration(struct rtw_dev *rtwdev)
> > +{
> > +	rtw8821c_do_iqk(rtwdev);
> 
> Why this extra step? You could name it rtw8821c_phy_calibration_iqk().
> 

This is hooked at rtw_chip_ops::phy_calibration(). For 8821C, only IQK is
required. So just keep the name consistent.

Yan-Hsuan
Sebastian Andrzej Siewior May 29, 2020, 7:05 a.m. UTC | #3
On 2020-05-29 06:31:23 [+0000], Tony Chuang wrote:
> > > +static void rtw8821c_phy_calibration(struct rtw_dev *rtwdev)
> > > +{
> > > +	rtw8821c_do_iqk(rtwdev);
> > 
> > Why this extra step? You could name it rtw8821c_phy_calibration_iqk().
> > 
> 
> This is hooked at rtw_chip_ops::phy_calibration(). For 8821C, only IQK is
> required. So just keep the name consistent.

Ah okay.

> Yan-Hsuan

Sebastian
diff mbox series

Patch

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
index 7169e6fb9ca9..749569eab912 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
@@ -555,6 +555,39 @@  static void rtw8821c_false_alarm_statistics(struct rtw_dev *rtwdev)
 	rtw_write32_clr(rtwdev, 0xb58, BIT(0));
 }
 
+static void rtw8821c_do_iqk(struct rtw_dev *rtwdev)
+{
+	static int do_iqk_cnt;
+	struct rtw_iqk_para para = {.clear = 0, .segment_iqk = 0};
+	u32 rf_reg, iqk_fail_mask;
+	int counter;
+	bool reload;
+
+	if (rtw_is_assoc(rtwdev))
+		para.segment_iqk = 1;
+
+	rtw_fw_do_iqk(rtwdev, &para);
+
+	for (counter = 0; counter < 300; counter++) {
+		rf_reg = rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK);
+		if (rf_reg == 0xabcde)
+			break;
+		msleep(20);
+	}
+	rtw_write_rf(rtwdev, RF_PATH_A, RF_DTXLOK, RFREG_MASK, 0x0);
+
+	reload = !!rtw_read32_mask(rtwdev, REG_IQKFAILMSK, BIT(16));
+	iqk_fail_mask = rtw_read32_mask(rtwdev, REG_IQKFAILMSK, GENMASK(7, 0));
+	rtw_dbg(rtwdev, RTW_DBG_PHY,
+		"iqk counter=%d reload=%d do_iqk_cnt=%d n_iqk_fail(mask)=0x%02x\n",
+		counter, reload, ++do_iqk_cnt, iqk_fail_mask);
+}
+
+static void rtw8821c_phy_calibration(struct rtw_dev *rtwdev)
+{
+	rtw8821c_do_iqk(rtwdev);
+}
+
 static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
 	{0x0086,
 	 RTW_PWR_CUT_ALL_MSK,
@@ -993,6 +1026,7 @@  static struct rtw_chip_ops rtw8821c_ops = {
 	.set_tx_power_index	= rtw8821c_set_tx_power_index,
 	.cfg_ldo25		= rtw8821c_cfg_ldo25,
 	.false_alarm_statistics	= rtw8821c_false_alarm_statistics,
+	.phy_calibration	= rtw8821c_phy_calibration,
 };
 
 struct rtw_chip_info rtw8821c_hw_spec = {