developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 1 | From 031841be718eb6736dec9c52744664433ed2a34e Mon Sep 17 00:00:00 2001 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2 | From: StanleyYP Wang <StanleyYP.Wang@mediatek.com> |
| 3 | Date: Fri, 24 Nov 2023 09:49:08 +0800 |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 4 | Subject: [PATCH 044/223] mtk: mt76: mt7996: add adie efuse merge support |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 5 | |
| 6 | Merge adie-dependent parameters in efuse into eeprom after FT. |
| 7 | Note that Eagle BE14000 is not considered yet. |
| 8 | Add efuse dump command. |
| 9 | |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 10 | Change-Id: Ib088b90147c75d7437f40dd3569e3584c6ff9ab0 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 11 | Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com> |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 12 | --- |
| 13 | mt7996/debugfs.c | 41 +++++++++++++ |
| 14 | mt7996/eeprom.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++ |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 15 | mt7996/main.c | 4 +- |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 16 | mt7996/testmode.c | 8 ++- |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 17 | 4 files changed, 193 insertions(+), 4 deletions(-) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 18 | |
| 19 | diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 20 | index 1f4bad62..70a97d29 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 21 | --- a/mt7996/debugfs.c |
| 22 | +++ b/mt7996/debugfs.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 23 | @@ -881,6 +881,46 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_muru_disable, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 24 | mt7996_fw_debug_muru_disable_get, |
| 25 | mt7996_fw_debug_muru_disable_set, "%lld\n"); |
| 26 | |
| 27 | +static ssize_t |
| 28 | +mt7996_efuse_get(struct file *file, char __user *user_buf, |
| 29 | + size_t count, loff_t *ppos) |
| 30 | +{ |
| 31 | + struct mt7996_dev *dev = file->private_data; |
| 32 | + struct mt76_dev *mdev = &dev->mt76; |
| 33 | + u8 *buff = mdev->otp.data; |
| 34 | + int i; |
| 35 | + ssize_t ret; |
| 36 | + u32 block_num; |
| 37 | + |
| 38 | + mdev->otp.size = MT7996_EEPROM_SIZE; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 39 | + if (is_mt7996(&dev->mt76) && dev->chip_sku == MT7996_VAR_TYPE_444) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 40 | + mdev->otp.size += 3 * MT_EE_CAL_UNIT; |
| 41 | + |
| 42 | + if (!mdev->otp.data) { |
| 43 | + mdev->otp.data = devm_kzalloc(mdev->dev, mdev->otp.size, GFP_KERNEL); |
| 44 | + if (!mdev->otp.data) |
| 45 | + return -ENOMEM; |
| 46 | + |
| 47 | + block_num = DIV_ROUND_UP(mdev->otp.size, MT7996_EEPROM_BLOCK_SIZE); |
| 48 | + for (i = 0; i < block_num; i++) { |
| 49 | + buff = mdev->otp.data + i * MT7996_EEPROM_BLOCK_SIZE; |
| 50 | + ret = mt7996_mcu_get_eeprom(dev, i * MT7996_EEPROM_BLOCK_SIZE, buff); |
| 51 | + if (ret && ret != -EINVAL) |
| 52 | + return ret; |
| 53 | + } |
| 54 | + } |
| 55 | + |
| 56 | + ret = simple_read_from_buffer(user_buf, count, ppos, mdev->otp.data, mdev->otp.size); |
| 57 | + |
| 58 | + return ret; |
| 59 | +} |
| 60 | + |
| 61 | +static const struct file_operations mt7996_efuse_ops = { |
| 62 | + .read = mt7996_efuse_get, |
| 63 | + .open = simple_open, |
| 64 | + .llseek = default_llseek, |
| 65 | +}; |
| 66 | + |
| 67 | int mt7996_init_debugfs(struct mt7996_phy *phy) |
| 68 | { |
| 69 | struct mt7996_dev *dev = phy->dev; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 70 | @@ -907,6 +947,7 @@ int mt7996_init_debugfs(struct mt7996_phy *phy) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 71 | debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir, |
| 72 | mt7996_twt_stats); |
| 73 | debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval); |
| 74 | + debugfs_create_file("otp", 0400, dir, dev, &mt7996_efuse_ops); |
| 75 | |
| 76 | if (phy->mt76->cap.has_5ghz) { |
| 77 | debugfs_create_u32("dfs_hw_pattern", 0400, dir, |
| 78 | diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 79 | index 7575dcb9..be87afe8 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 80 | --- a/mt7996/eeprom.c |
| 81 | +++ b/mt7996/eeprom.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 82 | @@ -546,6 +546,146 @@ static int mt7996_eeprom_load_precal(struct mt7996_dev *dev) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 83 | return mt76_get_of_data_from_nvmem(mdev, dev->cal, "precal", size); |
| 84 | } |
| 85 | |
| 86 | +static int mt7996_apply_cal_free_data(struct mt7996_dev *dev) |
| 87 | +{ |
| 88 | +#define MT_EE_CAL_FREE_MAX_SIZE 30 |
| 89 | +#define MT_EE_7977BN_OFFSET (0x1200 - 0x500) |
| 90 | +#define MT_EE_END_OFFSET 0xffff |
| 91 | + enum adie_type { |
| 92 | + ADIE_7975, |
| 93 | + ADIE_7976, |
| 94 | + ADIE_7977, |
| 95 | + ADIE_7978, |
| 96 | + ADIE_7979, |
| 97 | + }; |
| 98 | + static const u16 adie_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = { |
| 99 | + [ADIE_7975] = {0x5cd, 0x5cf, 0x5d1, 0x5d3, 0x6c0, 0x6c1, 0x6c2, 0x6c3, |
| 100 | + 0x7a1, 0x7a6, 0x7a8, 0x7aa, -1}, |
| 101 | + [ADIE_7976] = {0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x53, 0x55, 0x57, 0x59, |
| 102 | + 0x70, 0x71, 0x790, 0x791, 0x794, 0x795, 0x7a6, 0x7a8, 0x7aa, -1}, |
| 103 | + [ADIE_7977] = {0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x53, 0x55, 0x57, 0x59, |
| 104 | + 0x69, 0x6a, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, -1}, |
| 105 | + [ADIE_7978] = {0x91, 0x95, 0x100, 0x102, 0x104, 0x106, 0x107, |
| 106 | + 0x108, 0x109, 0x10a, 0x10b, 0x10c, 0x10e, 0x110, -1}, |
| 107 | + [ADIE_7979] = {0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x53, 0x55, 0x57, 0x59, |
| 108 | + 0x69, 0x6a, 0x7a, 0x7b, 0x7c, 0x7e, 0x80, -1}, |
| 109 | + }; |
| 110 | + static const u16 eep_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = { |
| 111 | + [ADIE_7975] = {0x451, 0x453, 0x455, 0x457, 0x44c, 0x44d, 0x44e, 0x44f, |
| 112 | + 0xba1, 0xba6, 0xba8, 0xbaa, -1}, |
| 113 | + [ADIE_7976] = {0x44c, 0x44d, 0x44e, 0x44f, 0x450, |
| 114 | + 0x451, 0x453, 0x455, 0x457, 0x459, |
| 115 | + 0x470, 0x471, 0xb90, 0xb91, 0xb94, 0xb95, |
| 116 | + 0xba6, 0xba8, 0xbaa, -1}, |
| 117 | + [ADIE_7977] = {0x124c, 0x124d, 0x124e, 0x124f, 0x1250, |
| 118 | + 0x1251, 0x1253, 0x1255, 0x1257, 0x1259, |
| 119 | + 0x1269, 0x126a, 0x127a, 0x127b, 0x127c, 0x127d, 0x127e, -1}, |
| 120 | + [ADIE_7978] = {0xb91, 0xb95, 0x480, 0x482, 0x484, 0x486, 0x487, 0x488, 0x489, |
| 121 | + 0x48a, 0x48b, 0x48c, 0x48e, 0x490, -1}, |
| 122 | + [ADIE_7979] = {0x124c, 0x124d, 0x124e, 0x124f, 0x1250, 0x1251, |
| 123 | + 0x1253, 0x1255, 0x1257, 0x1259, 0x1269, 0x126a, |
| 124 | + 0x127a, 0x127b, 0x127c, 0x127e, 0x1280, -1}, |
| 125 | + }; |
| 126 | + static const u16 adie_base_7996[] = { |
| 127 | + 0x400, 0x1e00, 0x1200 |
| 128 | + }; |
| 129 | + static const u16 adie_base_7992[] = { |
| 130 | + 0x400, 0x1200, 0x0 |
| 131 | + }; |
| 132 | + static const u16 *adie_offs[__MT_MAX_BAND]; |
| 133 | + static const u16 *eep_offs[__MT_MAX_BAND]; |
| 134 | + static const u16 *adie_base; |
| 135 | + u8 *eeprom = dev->mt76.eeprom.data; |
| 136 | + u8 buf[MT7996_EEPROM_BLOCK_SIZE]; |
| 137 | + int adie_id, band, i, ret; |
| 138 | + |
| 139 | + switch (mt76_chip(&dev->mt76)) { |
| 140 | + case 0x7990: |
| 141 | + adie_base = adie_base_7996; |
| 142 | + /* adie 0 */ |
| 143 | + if (dev->fem_type == MT7996_FEM_INT) |
| 144 | + adie_id = ADIE_7975; |
| 145 | + else |
| 146 | + adie_id = ADIE_7976; |
| 147 | + adie_offs[0] = adie_offs_list[adie_id]; |
| 148 | + eep_offs[0] = eep_offs_list[adie_id]; |
| 149 | + |
| 150 | + /* adie 1 */ |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 151 | + if (dev->chip_sku != MT7996_VAR_TYPE_404) { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 152 | + adie_offs[1] = adie_offs_list[ADIE_7977]; |
| 153 | + eep_offs[1] = eep_offs_list[ADIE_7977]; |
| 154 | + } |
| 155 | + |
| 156 | + /* adie 2 */ |
| 157 | + adie_offs[2] = adie_offs_list[ADIE_7977]; |
| 158 | + eep_offs[2] = eep_offs_list[ADIE_7977]; |
| 159 | + break; |
| 160 | + case 0x7992: |
| 161 | + adie_base = adie_base_7992; |
| 162 | + /* adie 0 */ |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 163 | + if (dev->chip_sku == MT7992_VAR_TYPE_44 && |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 164 | + dev->fem_type != MT7996_FEM_EXT) |
| 165 | + adie_id = ADIE_7975; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 166 | + else if (dev->chip_sku == MT7992_VAR_TYPE_24) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 167 | + adie_id = ADIE_7978; |
| 168 | + else |
| 169 | + adie_id = ADIE_7976; |
| 170 | + adie_offs[0] = adie_offs_list[adie_id]; |
| 171 | + eep_offs[0] = eep_offs_list[adie_id]; |
| 172 | + |
| 173 | + /* adie 1 */ |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 174 | + if (dev->chip_sku == MT7992_VAR_TYPE_44 && |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 175 | + dev->fem_type != MT7996_FEM_INT) |
| 176 | + adie_id = ADIE_7977; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 177 | + else if (dev->chip_sku != MT7992_VAR_TYPE_23) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 178 | + adie_id = ADIE_7979; |
| 179 | + else |
| 180 | + break; |
| 181 | + adie_offs[1] = adie_offs_list[adie_id]; |
| 182 | + eep_offs[1] = eep_offs_list[adie_id]; |
| 183 | + break; |
| 184 | + default: |
| 185 | + return -EINVAL; |
| 186 | + } |
| 187 | + |
| 188 | + for (band = 0; band < __MT_MAX_BAND; band++) { |
| 189 | + u16 adie_offset, eep_offset; |
| 190 | + u32 block_num, prev_block_num = -1; |
| 191 | + |
| 192 | + if (!adie_offs[band]) |
| 193 | + continue; |
| 194 | + |
| 195 | + for (i = 0; i < MT_EE_CAL_FREE_MAX_SIZE; i++) { |
| 196 | + adie_offset = adie_offs[band][i] + adie_base[band]; |
| 197 | + eep_offset = eep_offs[band][i]; |
| 198 | + block_num = adie_offset / MT7996_EEPROM_BLOCK_SIZE; |
| 199 | + |
| 200 | + if (adie_offs[band][i] == MT_EE_END_OFFSET) |
| 201 | + break; |
| 202 | + |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 203 | + if (is_mt7996(&dev->mt76) && dev->chip_sku == MT7996_VAR_TYPE_444 && |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 204 | + band == MT_BAND1) |
| 205 | + eep_offset -= MT_EE_7977BN_OFFSET; |
| 206 | + |
| 207 | + if (prev_block_num != block_num) { |
| 208 | + ret = mt7996_mcu_get_eeprom(dev, adie_offset, buf); |
| 209 | + if (ret) { |
| 210 | + if (ret != -EINVAL) |
| 211 | + return ret; |
| 212 | + |
| 213 | + prev_block_num = -1; |
| 214 | + continue; |
| 215 | + } |
| 216 | + } |
| 217 | + |
| 218 | + eeprom[eep_offset] = buf[adie_offset % MT7996_EEPROM_BLOCK_SIZE]; |
| 219 | + prev_block_num = block_num; |
| 220 | + } |
| 221 | + } |
| 222 | + |
| 223 | + return 0; |
| 224 | +} |
| 225 | + |
| 226 | int mt7996_eeprom_init(struct mt7996_dev *dev) |
| 227 | { |
| 228 | int ret; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 229 | @@ -556,6 +696,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev) |
| 230 | |
| 231 | mt7996_eeprom_load_precal(dev); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 232 | |
| 233 | + ret = mt7996_apply_cal_free_data(dev); |
| 234 | + if (ret) |
| 235 | + return ret; |
| 236 | + |
| 237 | ret = mt7996_eeprom_parse_hw_cap(dev, &dev->phy); |
| 238 | if (ret < 0) |
| 239 | return ret; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 240 | diff --git a/mt7996/main.c b/mt7996/main.c |
| 241 | index dc00cc2f..ea4679dd 100644 |
| 242 | --- a/mt7996/main.c |
| 243 | +++ b/mt7996/main.c |
| 244 | @@ -1485,10 +1485,10 @@ mt7996_background_radar_handle_7975_ifem(struct ieee80211_hw *hw, |
| 245 | switch (mt76_chip(&dev->mt76)) { |
| 246 | case 0x7990: |
| 247 | is_ifem_adie = dev->fem_type == MT7996_FEM_INT && |
| 248 | - dev->chip_sku != MT7996_SKU_233; |
| 249 | + dev->chip_sku != MT7996_VAR_TYPE_233; |
| 250 | break; |
| 251 | case 0x7992: |
| 252 | - is_ifem_adie = dev->chip_sku == MT7992_SKU_44 && |
| 253 | + is_ifem_adie = dev->chip_sku == MT7992_VAR_TYPE_44 && |
| 254 | dev->fem_type != MT7996_FEM_EXT; |
| 255 | break; |
| 256 | default: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 257 | diff --git a/mt7996/testmode.c b/mt7996/testmode.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 258 | index 5c0eb3cb..5a8b6d0a 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 259 | --- a/mt7996/testmode.c |
| 260 | +++ b/mt7996/testmode.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 261 | @@ -2128,8 +2128,12 @@ mt7996_tm_write_back_to_efuse(struct mt7996_dev *dev) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 262 | memcpy(req.data, eeprom + i, MT76_TM_EEPROM_BLOCK_SIZE); |
| 263 | |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 264 | ret = mt7996_mcu_get_eeprom(dev, i, read_buf, sizeof(read_buf)); |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 265 | - if (ret < 0) |
| 266 | - return ret; |
| 267 | + if (ret) { |
| 268 | + if (ret != -EINVAL) |
| 269 | + return ret; |
| 270 | + |
| 271 | + memset(read_buf, 0, MT76_TM_EEPROM_BLOCK_SIZE); |
| 272 | + } |
| 273 | |
| 274 | if (!memcmp(req.data, read_buf, MT76_TM_EEPROM_BLOCK_SIZE)) |
| 275 | continue; |
| 276 | -- |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame^] | 277 | 2.45.2 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 278 | |