developer | 617abbd | 2024-04-23 14:50:01 +0800 | [diff] [blame^] | 1 | From a4eb2ef1c0960faae461ab4585f4572eda428ed2 Mon Sep 17 00:00:00 2001 |
| 2 | From: StanleyYP Wang <StanleyYP.Wang@mediatek.com> |
| 3 | Date: Thu, 20 Jul 2023 17:27:22 +0800 |
| 4 | Subject: [PATCH 014/116] mtk: wifi: mt76: mt7996: add support for different |
| 5 | variants |
| 6 | |
| 7 | Add fem type (2i5i, 2i5e, 2e5e, ...) |
| 8 | Add Kite default bin for each fem type since loading wrong default bin |
| 9 | will fail to setup interface |
| 10 | Add eeprom fem type check |
| 11 | |
| 12 | Add adie 7976c efuse check |
| 13 | Efuse offset 0x470 will be set to 0xc after final test if 7976c adie is used |
| 14 | Chip manufactoring factories may transfer, which leads to different adie chip versions, |
| 15 | so we add this efuse check to avoid 7976c recognition failure. |
| 16 | |
| 17 | CR-Id: WCNCR00274293 |
| 18 | Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com> |
| 19 | Change-Id: I98caec6675670e3d1c0ee953bef2aeb71c3cf74e |
| 20 | |
| 21 | GPIO ADie Combination of BE5040 should be considered as don't care |
| 22 | instead of 0 |
| 23 | |
| 24 | CR-Id: WCNCR00274293 |
| 25 | Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com> |
| 26 | |
| 27 | Only check eeprom chip id when fem type (= MT7996_FEM_UNSET) is not determined yet |
| 28 | Without this fix, mt7996_check_eeprom will return EINVAL in mt7996_eeprom_check_fw_mode |
| 29 | |
| 30 | CR-Id: WCNCR00274293 |
| 31 | Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com> |
| 32 | --- |
| 33 | mt7996/eeprom.c | 40 +++++++++++++++++++++++++++++-- |
| 34 | mt7996/eeprom.h | 1 + |
| 35 | mt7996/init.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ |
| 36 | mt7996/mcu.c | 7 +++++- |
| 37 | mt7996/mt7996.h | 43 ++++++++++++++++++++++++++++++--- |
| 38 | mt7996/regs.h | 7 ++++++ |
| 39 | 6 files changed, 155 insertions(+), 6 deletions(-) |
| 40 | |
| 41 | diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c |
| 42 | index 4a8237118..3260d1fef 100644 |
| 43 | --- a/mt7996/eeprom.c |
| 44 | +++ b/mt7996/eeprom.c |
| 45 | @@ -9,14 +9,33 @@ |
| 46 | |
| 47 | static int mt7996_check_eeprom(struct mt7996_dev *dev) |
| 48 | { |
| 49 | +#define FEM_INT 0 |
| 50 | +#define FEM_EXT 3 |
| 51 | u8 *eeprom = dev->mt76.eeprom.data; |
| 52 | + u8 i, fem[__MT_MAX_BAND], fem_type; |
| 53 | u16 val = get_unaligned_le16(eeprom); |
| 54 | |
| 55 | + for (i = 0; i < __MT_MAX_BAND; i++) |
| 56 | + fem[i] = eeprom[MT_EE_WIFI_CONF + 6 + i] & MT_EE_WIFI_PA_LNA_CONFIG; |
| 57 | + |
| 58 | switch (val) { |
| 59 | case 0x7990: |
| 60 | return is_mt7996(&dev->mt76) ? 0 : -EINVAL; |
| 61 | case 0x7992: |
| 62 | - return is_mt7992(&dev->mt76) ? 0 : -EINVAL; |
| 63 | + if (dev->fem_type == MT7996_FEM_UNSET) |
| 64 | + return is_mt7992(&dev->mt76) ? 0 : -EINVAL; |
| 65 | + |
| 66 | + if (fem[0] == FEM_EXT && fem[1] == FEM_EXT) |
| 67 | + fem_type = MT7996_FEM_EXT; |
| 68 | + else if (fem[0] == FEM_INT && fem[1] == FEM_INT) |
| 69 | + fem_type = MT7996_FEM_INT; |
| 70 | + else if (fem[0] == FEM_INT && fem[1] == FEM_EXT) |
| 71 | + fem_type = MT7996_FEM_MIX; |
| 72 | + else |
| 73 | + return -EINVAL; |
| 74 | + |
| 75 | + return (is_mt7992(&dev->mt76) ? 0 : -EINVAL) | |
| 76 | + (dev->fem_type == fem_type ? 0 : -EINVAL); |
| 77 | default: |
| 78 | return -EINVAL; |
| 79 | } |
| 80 | @@ -26,9 +45,22 @@ static char *mt7996_eeprom_name(struct mt7996_dev *dev) |
| 81 | { |
| 82 | switch (mt76_chip(&dev->mt76)) { |
| 83 | case 0x7990: |
| 84 | + if (dev->chip_sku == MT7996_SKU_404) |
| 85 | + return MT7996_EEPROM_DEFAULT_404; |
| 86 | return MT7996_EEPROM_DEFAULT; |
| 87 | case 0x7992: |
| 88 | - return MT7992_EEPROM_DEFAULT; |
| 89 | + if (dev->chip_sku == MT7992_SKU_23) { |
| 90 | + if (dev->fem_type == MT7996_FEM_INT) |
| 91 | + return MT7992_EEPROM_DEFAULT_23; |
| 92 | + return MT7992_EEPROM_DEFAULT_23_EXT; |
| 93 | + } else if (dev->chip_sku == MT7992_SKU_44) { |
| 94 | + if (dev->fem_type == MT7996_FEM_INT) |
| 95 | + return MT7992_EEPROM_DEFAULT; |
| 96 | + else if (dev->fem_type == MT7996_FEM_MIX) |
| 97 | + return MT7992_EEPROM_DEFAULT_MIX; |
| 98 | + return MT7992_EEPROM_DEFAULT_EXT; |
| 99 | + } |
| 100 | + return MT7992_EEPROM_DEFAULT_24; |
| 101 | default: |
| 102 | return MT7996_EEPROM_DEFAULT; |
| 103 | } |
| 104 | @@ -219,6 +251,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev) |
| 105 | { |
| 106 | int ret; |
| 107 | |
| 108 | + ret = mt7996_get_chip_sku(dev); |
| 109 | + if (ret) |
| 110 | + return ret; |
| 111 | + |
| 112 | ret = mt7996_eeprom_load(dev); |
| 113 | if (ret < 0) { |
| 114 | if (ret != -EINVAL) |
| 115 | diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h |
| 116 | index 412d6e2f8..72c38ad3b 100644 |
| 117 | --- a/mt7996/eeprom.h |
| 118 | +++ b/mt7996/eeprom.h |
| 119 | @@ -29,6 +29,7 @@ enum mt7996_eeprom_field { |
| 120 | #define MT_EE_WIFI_CONF0_BAND_SEL GENMASK(2, 0) |
| 121 | #define MT_EE_WIFI_CONF1_BAND_SEL GENMASK(5, 3) |
| 122 | #define MT_EE_WIFI_CONF2_BAND_SEL GENMASK(2, 0) |
| 123 | +#define MT_EE_WIFI_PA_LNA_CONFIG GENMASK(1, 0) |
| 124 | |
| 125 | #define MT_EE_WIFI_CONF1_TX_PATH_BAND0 GENMASK(5, 3) |
| 126 | #define MT_EE_WIFI_CONF2_TX_PATH_BAND1 GENMASK(2, 0) |
| 127 | diff --git a/mt7996/init.c b/mt7996/init.c |
| 128 | index ab2e17ec4..d58335a37 100644 |
| 129 | --- a/mt7996/init.c |
| 130 | +++ b/mt7996/init.c |
| 131 | @@ -885,6 +885,65 @@ out: |
| 132 | #endif |
| 133 | } |
| 134 | |
| 135 | +int mt7996_get_chip_sku(struct mt7996_dev *dev) |
| 136 | +{ |
| 137 | +#define MT7976C_CHIP_VER 0x8a10 |
| 138 | +#define MT7976C_HL_CHIP_VER 0x8b00 |
| 139 | +#define MT7976C_PS_CHIP_VER 0x8c10 |
| 140 | +#define MT7976C_EFUSE_OFFSET 0x470 |
| 141 | +#define MT7976C_EFUSE_VALUE 0xc |
| 142 | + u32 regval, val = mt76_rr(dev, MT_PAD_GPIO); |
| 143 | + u16 adie_chip_id, adie_chip_ver; |
| 144 | + u8 adie_comb, adie_num, adie_idx = 0; |
| 145 | + |
| 146 | + switch (mt76_chip(&dev->mt76)) { |
| 147 | + case 0x7990: |
| 148 | + adie_comb = FIELD_GET(MT_PAD_GPIO_ADIE_COMB, val); |
| 149 | + if (adie_comb <= 1) |
| 150 | + dev->chip_sku = MT7996_SKU_444; |
| 151 | + else |
| 152 | + dev->chip_sku = MT7996_SKU_404; |
| 153 | + break; |
| 154 | + case 0x7992: |
| 155 | + adie_comb = FIELD_GET(MT_PAD_GPIO_ADIE_COMB_7992, val); |
| 156 | + adie_num = FIELD_GET(MT_PAD_GPIO_ADIE_NUM_7992, val); |
| 157 | + adie_idx = !adie_num; |
| 158 | + if (adie_num) |
| 159 | + dev->chip_sku = MT7992_SKU_23; |
| 160 | + else if (adie_comb) |
| 161 | + dev->chip_sku = MT7992_SKU_44; |
| 162 | + else |
| 163 | + dev->chip_sku = MT7992_SKU_24; |
| 164 | + break; |
| 165 | + default: |
| 166 | + return -EINVAL; |
| 167 | + } |
| 168 | + |
| 169 | + if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state)) { |
| 170 | + u8 buf[MT7996_EEPROM_BLOCK_SIZE]; |
| 171 | + u8 idx = MT7976C_EFUSE_OFFSET % MT7996_EEPROM_BLOCK_SIZE; |
| 172 | + bool is_7976c; |
| 173 | + |
| 174 | + mt7996_mcu_rf_regval(dev, MT_ADIE_CHIP_ID(adie_idx), ®val, false); |
| 175 | + adie_chip_id = FIELD_GET(MT_ADIE_CHIP_ID_MASK, regval); |
| 176 | + adie_chip_ver = FIELD_GET(MT_ADIE_VERSION_MASK, regval); |
| 177 | + mt7996_mcu_get_eeprom(dev, MT7976C_EFUSE_OFFSET, buf); |
| 178 | + is_7976c = (adie_chip_ver == MT7976C_CHIP_VER) || |
| 179 | + (adie_chip_ver == MT7976C_HL_CHIP_VER) || |
| 180 | + (adie_chip_ver == MT7976C_PS_CHIP_VER) || |
| 181 | + (buf[idx] == MT7976C_EFUSE_VALUE); |
| 182 | + if (adie_chip_id == 0x7975 || (adie_chip_id == 0x7976 && is_7976c) || |
| 183 | + adie_chip_id == 0x7979) |
| 184 | + dev->fem_type = MT7996_FEM_INT; |
| 185 | + else if (adie_chip_id == 0x7977 && adie_comb == 1) |
| 186 | + dev->fem_type = MT7996_FEM_MIX; |
| 187 | + else |
| 188 | + dev->fem_type = MT7996_FEM_EXT; |
| 189 | + } |
| 190 | + |
| 191 | + return 0; |
| 192 | +} |
| 193 | + |
| 194 | static int mt7996_init_hardware(struct mt7996_dev *dev) |
| 195 | { |
| 196 | int ret, idx; |
| 197 | @@ -900,6 +959,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev) |
| 198 | INIT_LIST_HEAD(&dev->wed_rro.poll_list); |
| 199 | spin_lock_init(&dev->wed_rro.lock); |
| 200 | |
| 201 | + ret = mt7996_get_chip_sku(dev); |
| 202 | + if (ret) |
| 203 | + return ret; |
| 204 | + |
| 205 | ret = mt7996_dma_init(dev); |
| 206 | if (ret) |
| 207 | return ret; |
| 208 | diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| 209 | index 10637226c..9e94e03d8 100644 |
| 210 | --- a/mt7996/mcu.c |
| 211 | +++ b/mt7996/mcu.c |
| 212 | @@ -14,7 +14,12 @@ |
| 213 | char *_fw; \ |
| 214 | switch (mt76_chip(&(_dev)->mt76)) { \ |
| 215 | case 0x7992: \ |
| 216 | - _fw = MT7992_##name; \ |
| 217 | + if ((_dev)->chip_sku == MT7992_SKU_23) \ |
| 218 | + _fw = MT7992_##name##_23; \ |
| 219 | + else if ((_dev)->chip_sku == MT7992_SKU_24) \ |
| 220 | + _fw = MT7992_##name##_24; \ |
| 221 | + else \ |
| 222 | + _fw = MT7992_##name; \ |
| 223 | break; \ |
| 224 | case 0x7990: \ |
| 225 | default: \ |
| 226 | diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
| 227 | index 58fa6b458..b7197dcb7 100644 |
| 228 | --- a/mt7996/mt7996.h |
| 229 | +++ b/mt7996/mt7996.h |
| 230 | @@ -39,8 +39,24 @@ |
| 231 | #define MT7992_FIRMWARE_DSP "mediatek/mt7996/mt7992_dsp.bin" |
| 232 | #define MT7992_ROM_PATCH "mediatek/mt7996/mt7992_rom_patch.bin" |
| 233 | |
| 234 | +#define MT7992_FIRMWARE_WA_24 "mediatek/mt7996/mt7992_wa_24.bin" |
| 235 | +#define MT7992_FIRMWARE_WM_24 "mediatek/mt7996/mt7992_wm_24.bin" |
| 236 | +#define MT7992_FIRMWARE_DSP_24 "mediatek/mt7996/mt7992_dsp_24.bin" |
| 237 | +#define MT7992_ROM_PATCH_24 "mediatek/mt7996/mt7992_rom_patch_24.bin" |
| 238 | + |
| 239 | +#define MT7992_FIRMWARE_WA_23 "mediatek/mt7996/mt7992_wa_23.bin" |
| 240 | +#define MT7992_FIRMWARE_WM_23 "mediatek/mt7996/mt7992_wm_23.bin" |
| 241 | +#define MT7992_FIRMWARE_DSP_23 "mediatek/mt7996/mt7992_dsp_23.bin" |
| 242 | +#define MT7992_ROM_PATCH_23 "mediatek/mt7996/mt7992_rom_patch_23.bin" |
| 243 | + |
| 244 | #define MT7996_EEPROM_DEFAULT "mediatek/mt7996/mt7996_eeprom.bin" |
| 245 | -#define MT7992_EEPROM_DEFAULT "mediatek/mt7996/mt7992_eeprom.bin" |
| 246 | +#define MT7996_EEPROM_DEFAULT_404 "mediatek/mt7996/mt7996_eeprom_dual_404.bin" |
| 247 | +#define MT7992_EEPROM_DEFAULT "mediatek/mt7996/mt7992_eeprom_2i5i.bin" |
| 248 | +#define MT7992_EEPROM_DEFAULT_EXT "mediatek/mt7996/mt7992_eeprom_2e5e.bin" |
| 249 | +#define MT7992_EEPROM_DEFAULT_MIX "mediatek/mt7996/mt7992_eeprom_2i5e.bin" |
| 250 | +#define MT7992_EEPROM_DEFAULT_24 "mediatek/mt7996/mt7992_eeprom_24_2i5i.bin" |
| 251 | +#define MT7992_EEPROM_DEFAULT_23 "mediatek/mt7996/mt7992_eeprom_23_2i5i.bin" |
| 252 | +#define MT7992_EEPROM_DEFAULT_23_EXT "mediatek/mt7996/mt7992_eeprom_23_2e5e.bin" |
| 253 | #define MT7996_EEPROM_SIZE 7680 |
| 254 | #define MT7996_EEPROM_BLOCK_SIZE 16 |
| 255 | #define MT7996_TOKEN_SIZE 16384 |
| 256 | @@ -89,6 +105,24 @@ struct mt7996_sta; |
| 257 | struct mt7996_dfs_pulse; |
| 258 | struct mt7996_dfs_pattern; |
| 259 | |
| 260 | +enum mt7996_fem_type { |
| 261 | + MT7996_FEM_UNSET, |
| 262 | + MT7996_FEM_EXT, |
| 263 | + MT7996_FEM_INT, |
| 264 | + MT7996_FEM_MIX, |
| 265 | +}; |
| 266 | + |
| 267 | +enum mt7996_sku_type { |
| 268 | + MT7996_SKU_404, |
| 269 | + MT7996_SKU_444, |
| 270 | +}; |
| 271 | + |
| 272 | +enum mt7992_sku_type { |
| 273 | + MT7992_SKU_23, |
| 274 | + MT7992_SKU_24, |
| 275 | + MT7992_SKU_44, |
| 276 | +}; |
| 277 | + |
| 278 | enum mt7996_ram_type { |
| 279 | MT7996_RAM_TYPE_WM, |
| 280 | MT7996_RAM_TYPE_WA, |
| 281 | @@ -261,6 +295,9 @@ struct mt7996_dev { |
| 282 | struct cfg80211_chan_def rdd2_chandef; |
| 283 | struct mt7996_phy *rdd2_phy; |
| 284 | |
| 285 | + u8 chip_sku; |
| 286 | + u8 fem_type; |
| 287 | + |
| 288 | u16 chainmask; |
| 289 | u8 chainshift[__MT_MAX_BAND]; |
| 290 | u32 hif_idx; |
| 291 | @@ -409,8 +446,7 @@ mt7996_band_valid(struct mt7996_dev *dev, u8 band) |
| 292 | return band <= MT_BAND1; |
| 293 | |
| 294 | /* tri-band support */ |
| 295 | - if (band <= MT_BAND2 && |
| 296 | - mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) <= 1) |
| 297 | + if (band <= MT_BAND2 && dev->chip_sku) |
| 298 | return true; |
| 299 | |
| 300 | return band == MT_BAND0 || band == MT_BAND2; |
| 301 | @@ -441,6 +477,7 @@ int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx, |
| 302 | int n_desc, int ring_base, struct mtk_wed_device *wed); |
| 303 | void mt7996_init_txpower(struct mt7996_phy *phy); |
| 304 | int mt7996_txbf_init(struct mt7996_dev *dev); |
| 305 | +int mt7996_get_chip_sku(struct mt7996_dev *dev); |
| 306 | void mt7996_reset(struct mt7996_dev *dev); |
| 307 | int mt7996_run(struct ieee80211_hw *hw); |
| 308 | int mt7996_mcu_init(struct mt7996_dev *dev); |
| 309 | diff --git a/mt7996/regs.h b/mt7996/regs.h |
| 310 | index 47b429d8b..cf12c5e02 100644 |
| 311 | --- a/mt7996/regs.h |
| 312 | +++ b/mt7996/regs.h |
| 313 | @@ -662,6 +662,13 @@ enum offs_rev { |
| 314 | |
| 315 | #define MT_PAD_GPIO 0x700056f0 |
| 316 | #define MT_PAD_GPIO_ADIE_COMB GENMASK(16, 15) |
| 317 | +#define MT_PAD_GPIO_ADIE_COMB_7992 GENMASK(17, 16) |
| 318 | +#define MT_PAD_GPIO_ADIE_NUM_7992 BIT(15) |
| 319 | + |
| 320 | +/* ADIE */ |
| 321 | +#define MT_ADIE_CHIP_ID(_idx) (0x0f00002c + ((_idx) << 28)) |
| 322 | +#define MT_ADIE_VERSION_MASK GENMASK(15, 0) |
| 323 | +#define MT_ADIE_CHIP_ID_MASK GENMASK(31, 16) |
| 324 | |
| 325 | #define MT_HW_REV 0x70010204 |
| 326 | #define MT_HW_REV1 0x8a00 |
| 327 | -- |
| 328 | 2.39.2 |
| 329 | |