Search Linux Wireless

Re: [PATCH] rtw88: set power trim according to efuse PG values

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Apr 15, 2020 at 5:59 PM <yhchuang@xxxxxxxxxxx> wrote:
>
> From: Tzu-En Huang <tehuang@xxxxxxxxxxx>
>
> 8822C devices have power trim, thermal and PA bias values
> programmed in efuse. Driver should configure the RF components
> according to the values.
>
> If the power trim is not configured, then the devices might have
> distortion on the output tx power.
>
> Signed-off-by: Tzu-En Huang <tehuang@xxxxxxxxxxx>
> Signed-off-by: Yan-Hsuan Chuang <yhchuang@xxxxxxxxxxx>
> ---
>  drivers/net/wireless/realtek/rtw88/efuse.c    |  21 ++++
>  drivers/net/wireless/realtek/rtw88/efuse.h    |   3 +
>  drivers/net/wireless/realtek/rtw88/rtw8822c.c | 111 ++++++++++++++++++
>  drivers/net/wireless/realtek/rtw88/rtw8822c.h |  28 +++++
>  4 files changed, 163 insertions(+)
>
> diff --git a/drivers/net/wireless/realtek/rtw88/efuse.c b/drivers/net/wireless/realtek/rtw88/efuse.c
> index 212c8376a8c9..f037fa586915 100644
> --- a/drivers/net/wireless/realtek/rtw88/efuse.c
> +++ b/drivers/net/wireless/realtek/rtw88/efuse.c
> @@ -116,6 +116,27 @@ static int rtw_dump_physical_efuse_map(struct rtw_dev *rtwdev, u8 *map)
>         return 0;
>  }
>
> +int rtw_read8_physical_efuse(struct rtw_dev *rtwdev, u16 addr, u8 *data)
> +{
> +       u32 efuse_ctl, cnt;
> +
> +       rtw_write32_mask(rtwdev, REG_EFUSE_CTRL, 0x3ff00, addr);
> +       rtw_write32_clr(rtwdev, REG_EFUSE_CTRL, BIT_EF_FLAG);
> +       cnt = 1000;
> +       do {
> +               mdelay(1);
> +               efuse_ctl = rtw_read32(rtwdev, REG_EFUSE_CTRL);
> +               if (--cnt == 0) {
> +                       *data = EFUSE_READ_FAIL;
> +                       return -EBUSY;
> +               }
> +       } while (!(efuse_ctl & BIT_EF_FLAG));

I believe this can be replaced by read_poll_timeout().

The rest of the patch looks OK to me.

> +
> +       *data = rtw_read8(rtwdev, REG_EFUSE_CTRL);
> +
> +       return 0;
> +}
> +
>  int rtw_parse_efuse_map(struct rtw_dev *rtwdev)
>  {
>         struct rtw_chip_info *chip = rtwdev->chip;
> +}
> +
> +static void rtw8822c_power_trim(struct rtw_dev *rtwdev)
> +{
> +       u8 pg_pwr = 0xff, i, path, idx;
> +       s8 bb_gain[2][8] = {0};
> +       u16 rf_efuse_2g[3] = {PPG_2GL_TXAB, PPG_2GM_TXAB, PPG_2GH_TXAB};
> +       u16 rf_efuse_5g[2][5] = {{PPG_5GL1_TXA, PPG_5GL2_TXA, PPG_5GM1_TXA,
> +                                 PPG_5GM2_TXA, PPG_5GH1_TXA},
> +                                {PPG_5GL1_TXB, PPG_5GL2_TXB, PPG_5GM1_TXB,
> +                                 PPG_5GM2_TXB, PPG_5GH1_TXB} };
> +       bool set = false;
> +
> +       for (i = 0; i < ARRAY_SIZE(rf_efuse_2g); i++) {
> +               rtw_read8_physical_efuse(rtwdev, rf_efuse_2g[i], &pg_pwr);
> +               if (pg_pwr == EFUSE_READ_FAIL)
> +                       continue;
> +               set = true;
> +               bb_gain[RF_PATH_A][i] = FIELD_GET(PPG_2G_A_MASK, pg_pwr);
> +               bb_gain[RF_PATH_B][i] = FIELD_GET(PPG_2G_B_MASK, pg_pwr);
> +       }
> +
> +       for (i = 0; i < ARRAY_SIZE(rf_efuse_5g[0]); i++) {
> +               for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
> +                       rtw_read8_physical_efuse(rtwdev, rf_efuse_5g[path][i],
> +                                                &pg_pwr);
> +                       if (pg_pwr == EFUSE_READ_FAIL)
> +                               continue;
> +                       set = true;
> +                       idx = i + ARRAY_SIZE(rf_efuse_2g);
> +                       bb_gain[path][idx] = FIELD_GET(PPG_5G_MASK, pg_pwr);
> +               }
> +       }
> +       if (set)
> +               rtw8822c_set_power_trim(rtwdev, bb_gain);
> +}
> +
> +static void rtw8822c_thermal_trim(struct rtw_dev *rtwdev)
> +{
> +       u16 rf_efuse[2] = {PPG_THERMAL_A, PPG_THERMAL_B};
> +       u8 pg_therm = 0xff, thermal[2] = {0}, path;
> +
> +       for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
> +               rtw_read8_physical_efuse(rtwdev, rf_efuse[path], &pg_therm);
> +               if (pg_therm == EFUSE_READ_FAIL)
> +                       return;
> +               /* Efuse value of BIT(0) shall be move to BIT(3), and the value
> +                * of BIT(1) to BIT(3) should be right shifted 1 bit.
> +                */
> +               thermal[path] = FIELD_GET(GENMASK(3, 1), pg_therm);
> +               thermal[path] |= FIELD_PREP(BIT(3), pg_therm & BIT(0));
> +               rtw_write_rf(rtwdev, path, 0x43, RF_THEMAL_MASK, thermal[path]);
> +       }
> +}
> +
> +static void rtw8822c_pa_bias(struct rtw_dev *rtwdev)
> +{
> +       u16 rf_efuse_2g[2] = {PPG_PABIAS_2GA, PPG_PABIAS_2GB};
> +       u16 rf_efuse_5g[2] = {PPG_PABIAS_5GA, PPG_PABIAS_5GB};
> +       u8 pg_pa_bias = 0xff, path;
> +
> +       for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
> +               rtw_read8_physical_efuse(rtwdev, rf_efuse_2g[path],
> +                                        &pg_pa_bias);
> +               if (pg_pa_bias == EFUSE_READ_FAIL)
> +                       return;
> +               pg_pa_bias = FIELD_GET(PPG_PABIAS_MASK, pg_pa_bias);
> +               rtw_write_rf(rtwdev, path, 0x60, RF_PABIAS_2G_MASK, pg_pa_bias);
> +       }
> +       for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
> +               rtw_read8_physical_efuse(rtwdev, rf_efuse_5g[path],
> +                                        &pg_pa_bias);
> +               pg_pa_bias = FIELD_GET(PPG_PABIAS_MASK, pg_pa_bias);
> +               rtw_write_rf(rtwdev, path, 0x60, RF_PABIAS_5G_MASK, pg_pa_bias);
> +       }
> +}
> +
>  static void rtw8822c_rf_init(struct rtw_dev *rtwdev)
>  {
>         rtw8822c_rf_dac_cal(rtwdev);
>         rtw8822c_rf_x2_check(rtwdev);
> +       rtw8822c_thermal_trim(rtwdev);
> +       rtw8822c_power_trim(rtwdev);
> +       rtw8822c_pa_bias(rtwdev);
>  }
>
> 2.17.1
>



[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux