xref: /linux/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c (revision 96ac6d435100450f0565708d9b885ea2a7400e0a)
1 /* SPDX-License-Identifier: ISC */
2 
3 #include "mt7603.h"
4 #include "eeprom.h"
5 
6 static int
7 mt7603_efuse_read(struct mt7603_dev *dev, u32 base, u16 addr, u8 *data)
8 {
9 	u32 val;
10 	int i;
11 
12 	val = mt76_rr(dev, base + MT_EFUSE_CTRL);
13 	val &= ~(MT_EFUSE_CTRL_AIN |
14 		 MT_EFUSE_CTRL_MODE);
15 	val |= FIELD_PREP(MT_EFUSE_CTRL_AIN, addr & ~0xf);
16 	val |= MT_EFUSE_CTRL_KICK;
17 	mt76_wr(dev, base + MT_EFUSE_CTRL, val);
18 
19 	if (!mt76_poll(dev, base + MT_EFUSE_CTRL, MT_EFUSE_CTRL_KICK, 0, 1000))
20 		return -ETIMEDOUT;
21 
22 	udelay(2);
23 
24 	val = mt76_rr(dev, base + MT_EFUSE_CTRL);
25 	if ((val & MT_EFUSE_CTRL_AOUT) == MT_EFUSE_CTRL_AOUT ||
26 	    WARN_ON_ONCE(!(val & MT_EFUSE_CTRL_VALID))) {
27 		memset(data, 0xff, 16);
28 		return 0;
29 	}
30 
31 	for (i = 0; i < 4; i++) {
32 		val = mt76_rr(dev, base + MT_EFUSE_RDATA(i));
33 		put_unaligned_le32(val, data + 4 * i);
34 	}
35 
36 	return 0;
37 }
38 
39 static int
40 mt7603_efuse_init(struct mt7603_dev *dev)
41 {
42 	u32 base = mt7603_reg_map(dev, MT_EFUSE_BASE);
43 	int len = MT7603_EEPROM_SIZE;
44 	void *buf;
45 	int ret, i;
46 
47 	if (mt76_rr(dev, base + MT_EFUSE_BASE_CTRL) & MT_EFUSE_BASE_CTRL_EMPTY)
48 		return 0;
49 
50 	dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, len, GFP_KERNEL);
51 	dev->mt76.otp.size = len;
52 	if (!dev->mt76.otp.data)
53 		return -ENOMEM;
54 
55 	buf = dev->mt76.otp.data;
56 	for (i = 0; i + 16 <= len; i += 16) {
57 		ret = mt7603_efuse_read(dev, base, i, buf + i);
58 		if (ret)
59 			return ret;
60 	}
61 
62 	return 0;
63 }
64 
65 static bool
66 mt7603_has_cal_free_data(struct mt7603_dev *dev, u8 *efuse)
67 {
68 	if (!efuse[MT_EE_TEMP_SENSOR_CAL])
69 		return false;
70 
71 	if (get_unaligned_le16(efuse + MT_EE_TX_POWER_0_START_2G) == 0)
72 		return false;
73 
74 	if (get_unaligned_le16(efuse + MT_EE_TX_POWER_1_START_2G) == 0)
75 		return false;
76 
77 	if (!efuse[MT_EE_CP_FT_VERSION])
78 		return false;
79 
80 	if (!efuse[MT_EE_XTAL_FREQ_OFFSET])
81 		return false;
82 
83 	if (!efuse[MT_EE_XTAL_WF_RFCAL])
84 		return false;
85 
86 	return true;
87 }
88 
89 static void
90 mt7603_apply_cal_free_data(struct mt7603_dev *dev, u8 *efuse)
91 {
92 	static const u8 cal_free_bytes[] = {
93 		MT_EE_TEMP_SENSOR_CAL,
94 		MT_EE_CP_FT_VERSION,
95 		MT_EE_XTAL_FREQ_OFFSET,
96 		MT_EE_XTAL_WF_RFCAL,
97 		/* Skip for MT7628 */
98 		MT_EE_TX_POWER_0_START_2G,
99 		MT_EE_TX_POWER_0_START_2G + 1,
100 		MT_EE_TX_POWER_1_START_2G,
101 		MT_EE_TX_POWER_1_START_2G + 1,
102 	};
103 	u8 *eeprom = dev->mt76.eeprom.data;
104 	int n = ARRAY_SIZE(cal_free_bytes);
105 	int i;
106 
107 	if (!mt7603_has_cal_free_data(dev, efuse))
108 		return;
109 
110 	if (is_mt7628(dev))
111 		n -= 4;
112 
113 	for (i = 0; i < n; i++) {
114 		int offset = cal_free_bytes[i];
115 
116 		eeprom[offset] = efuse[offset];
117 	}
118 }
119 
120 static int
121 mt7603_eeprom_load(struct mt7603_dev *dev)
122 {
123 	int ret;
124 
125 	ret = mt76_eeprom_init(&dev->mt76, MT7603_EEPROM_SIZE);
126 	if (ret < 0)
127 		return ret;
128 
129 	return mt7603_efuse_init(dev);
130 }
131 
132 static int mt7603_check_eeprom(struct mt76_dev *dev)
133 {
134 	u16 val = get_unaligned_le16(dev->eeprom.data);
135 
136 	switch (val) {
137 	case 0x7628:
138 	case 0x7603:
139 		return 0;
140 	default:
141 		return -EINVAL;
142 	}
143 }
144 
145 int mt7603_eeprom_init(struct mt7603_dev *dev)
146 {
147 	int ret;
148 
149 	ret = mt7603_eeprom_load(dev);
150 	if (ret < 0)
151 		return ret;
152 
153 	if (dev->mt76.otp.data) {
154 		if (mt7603_check_eeprom(&dev->mt76) == 0)
155 			mt7603_apply_cal_free_data(dev, dev->mt76.otp.data);
156 		else
157 			memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data,
158 			       MT7603_EEPROM_SIZE);
159 	}
160 
161 	dev->mt76.cap.has_2ghz = true;
162 	memcpy(dev->mt76.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
163 	       ETH_ALEN);
164 
165 	mt76_eeprom_override(&dev->mt76);
166 
167 	return 0;
168 }
169