Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 
0003 #include <linux/of.h>
0004 #include "mt7603.h"
0005 #include "eeprom.h"
0006 
0007 static int
0008 mt7603_efuse_read(struct mt7603_dev *dev, u32 base, u16 addr, u8 *data)
0009 {
0010     u32 val;
0011     int i;
0012 
0013     val = mt76_rr(dev, base + MT_EFUSE_CTRL);
0014     val &= ~(MT_EFUSE_CTRL_AIN |
0015          MT_EFUSE_CTRL_MODE);
0016     val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf);
0017     val |= MT_EFUSE_CTRL_KICK;
0018     mt76_wr(dev, base + MT_EFUSE_CTRL, val);
0019 
0020     if (!mt76_poll(dev, base + MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000))
0021         return -ETIMEDOUT;
0022 
0023     udelay(2);
0024 
0025     val = mt76_rr(dev, base + MT_EFUSE_CTRL);
0026     if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT ||
0027         WARN_ON_ONCE(!(val & MT_EFUSE_CTRL_VALID))) {
0028         memset(data, 0xff, 16);
0029         return 0;
0030     }
0031 
0032     for (i = 0; i < 4; i++) {
0033         val = mt76_rr(dev, base + MT_EFUSE_RDATA(i));
0034         put_unaligned_le32(val, data + 4 * i);
0035     }
0036 
0037     return 0;
0038 }
0039 
0040 static int
0041 mt7603_efuse_init(struct mt7603_dev *dev)
0042 {
0043     u32 base = mt7603_reg_map(dev, MT_EFUSE_BASE);
0044     int len = MT7603_EEPROM_SIZE;
0045     void *buf;
0046     int ret, i;
0047 
0048     if (mt76_rr(dev, base + MT_EFUSE_BASE_CTRL) & MT_EFUSE_BASE_CTRL_EMPTY)
0049         return 0;
0050 
0051     dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, len, GFP_KERNEL);
0052     dev->mt76.otp.size = len;
0053     if (!dev->mt76.otp.data)
0054         return -ENOMEM;
0055 
0056     buf = dev->mt76.otp.data;
0057     for (i = 0; i + 16 <= len; i += 16) {
0058         ret = mt7603_efuse_read(dev, base, i, buf + i);
0059         if (ret)
0060             return ret;
0061     }
0062 
0063     return 0;
0064 }
0065 
0066 static bool
0067 mt7603_has_cal_free_data(struct mt7603_dev *dev, u8 *efuse)
0068 {
0069     if (!efuse[MT_EE_TEMP_SENSOR_CAL])
0070         return false;
0071 
0072     if (get_unaligned_le16(efuse + MT_EE_TX_POWER_0_START_2G) == 0)
0073         return false;
0074 
0075     if (get_unaligned_le16(efuse + MT_EE_TX_POWER_1_START_2G) == 0)
0076         return false;
0077 
0078     if (!efuse[MT_EE_CP_FT_VERSION])
0079         return false;
0080 
0081     if (!efuse[MT_EE_XTAL_FREQ_OFFSET])
0082         return false;
0083 
0084     if (!efuse[MT_EE_XTAL_WF_RFCAL])
0085         return false;
0086 
0087     return true;
0088 }
0089 
0090 static void
0091 mt7603_apply_cal_free_data(struct mt7603_dev *dev, u8 *efuse)
0092 {
0093     static const u8 cal_free_bytes[] = {
0094         MT_EE_TEMP_SENSOR_CAL,
0095         MT_EE_CP_FT_VERSION,
0096         MT_EE_XTAL_FREQ_OFFSET,
0097         MT_EE_XTAL_WF_RFCAL,
0098         /* Skip for MT7628 */
0099         MT_EE_TX_POWER_0_START_2G,
0100         MT_EE_TX_POWER_0_START_2G + 1,
0101         MT_EE_TX_POWER_1_START_2G,
0102         MT_EE_TX_POWER_1_START_2G + 1,
0103     };
0104     struct device_node *np = dev->mt76.dev->of_node;
0105     u8 *eeprom = dev->mt76.eeprom.data;
0106     int n = ARRAY_SIZE(cal_free_bytes);
0107     int i;
0108 
0109     if (!np || !of_property_read_bool(np, "mediatek,eeprom-merge-otp"))
0110         return;
0111 
0112     if (!mt7603_has_cal_free_data(dev, efuse))
0113         return;
0114 
0115     if (is_mt7628(dev))
0116         n -= 4;
0117 
0118     for (i = 0; i < n; i++) {
0119         int offset = cal_free_bytes[i];
0120 
0121         eeprom[offset] = efuse[offset];
0122     }
0123 }
0124 
0125 static int
0126 mt7603_eeprom_load(struct mt7603_dev *dev)
0127 {
0128     int ret;
0129 
0130     ret = mt76_eeprom_init(&dev->mt76, MT7603_EEPROM_SIZE);
0131     if (ret < 0)
0132         return ret;
0133 
0134     return mt7603_efuse_init(dev);
0135 }
0136 
0137 static int mt7603_check_eeprom(struct mt76_dev *dev)
0138 {
0139     u16 val = get_unaligned_le16(dev->eeprom.data);
0140 
0141     switch (val) {
0142     case 0x7628:
0143     case 0x7603:
0144     case 0x7600:
0145         return 0;
0146     default:
0147         return -EINVAL;
0148     }
0149 }
0150 
0151 static inline bool is_mt7688(struct mt7603_dev *dev)
0152 {
0153     return mt76_rr(dev, MT_EFUSE_BASE + 0x64) & BIT(4);
0154 }
0155 
0156 int mt7603_eeprom_init(struct mt7603_dev *dev)
0157 {
0158     u8 *eeprom;
0159     int ret;
0160 
0161     ret = mt7603_eeprom_load(dev);
0162     if (ret < 0)
0163         return ret;
0164 
0165     if (dev->mt76.otp.data) {
0166         if (mt7603_check_eeprom(&dev->mt76) == 0)
0167             mt7603_apply_cal_free_data(dev, dev->mt76.otp.data);
0168         else
0169             memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
0170                    MT7603_EEPROM_SIZE);
0171     }
0172 
0173     eeprom = (u8 *)dev->mt76.eeprom.data;
0174     dev->mphy.cap.has_2ghz = true;
0175     memcpy(dev->mphy.macaddr, eeprom + MT_EE_MAC_ADDR, ETH_ALEN);
0176 
0177     /* Check for 1SS devices */
0178     dev->mphy.antenna_mask = 3;
0179     if (FIELD_GET(MT_EE_NIC_CONF_0_RX_PATH, eeprom[MT_EE_NIC_CONF_0]) == 1 ||
0180         FIELD_GET(MT_EE_NIC_CONF_0_TX_PATH, eeprom[MT_EE_NIC_CONF_0]) == 1 ||
0181         is_mt7688(dev))
0182         dev->mphy.antenna_mask = 1;
0183 
0184     mt76_eeprom_override(&dev->mphy);
0185 
0186     return 0;
0187 }