1 // SPDX-License-Identifier: ISC
8 mt7603_efuse_read(struct mt7603_dev
*dev
, u32 base
, u16 addr
, u8
*data
)
13 val
= mt76_rr(dev
, base
+ MT_EFUSE_CTRL
);
14 val
&= ~(MT_EFUSE_CTRL_AIN
|
16 val
|= FIELD_PREP(MT_EFUSE_CTRL_AIN
, addr
& ~0xf);
17 val
|= MT_EFUSE_CTRL_KICK
;
18 mt76_wr(dev
, base
+ MT_EFUSE_CTRL
, val
);
20 if (!mt76_poll(dev
, base
+ MT_EFUSE_CTRL
, MT_EFUSE_CTRL_KICK
, 0, 1000))
25 val
= mt76_rr(dev
, base
+ MT_EFUSE_CTRL
);
26 if ((val
& MT_EFUSE_CTRL_AOUT
) == MT_EFUSE_CTRL_AOUT
||
27 WARN_ON_ONCE(!(val
& MT_EFUSE_CTRL_VALID
))) {
28 memset(data
, 0xff, 16);
32 for (i
= 0; i
< 4; i
++) {
33 val
= mt76_rr(dev
, base
+ MT_EFUSE_RDATA(i
));
34 put_unaligned_le32(val
, data
+ 4 * i
);
41 mt7603_efuse_init(struct mt7603_dev
*dev
)
43 u32 base
= mt7603_reg_map(dev
, MT_EFUSE_BASE
);
44 int len
= MT7603_EEPROM_SIZE
;
48 if (mt76_rr(dev
, base
+ MT_EFUSE_BASE_CTRL
) & MT_EFUSE_BASE_CTRL_EMPTY
)
51 dev
->mt76
.otp
.data
= devm_kzalloc(dev
->mt76
.dev
, len
, GFP_KERNEL
);
52 dev
->mt76
.otp
.size
= len
;
53 if (!dev
->mt76
.otp
.data
)
56 buf
= dev
->mt76
.otp
.data
;
57 for (i
= 0; i
+ 16 <= len
; i
+= 16) {
58 ret
= mt7603_efuse_read(dev
, base
, i
, buf
+ i
);
67 mt7603_has_cal_free_data(struct mt7603_dev
*dev
, u8
*efuse
)
69 if (!efuse
[MT_EE_TEMP_SENSOR_CAL
])
72 if (get_unaligned_le16(efuse
+ MT_EE_TX_POWER_0_START_2G
) == 0)
75 if (get_unaligned_le16(efuse
+ MT_EE_TX_POWER_1_START_2G
) == 0)
78 if (!efuse
[MT_EE_CP_FT_VERSION
])
81 if (!efuse
[MT_EE_XTAL_FREQ_OFFSET
])
84 if (!efuse
[MT_EE_XTAL_WF_RFCAL
])
91 mt7603_apply_cal_free_data(struct mt7603_dev
*dev
, u8
*efuse
)
93 static const u8 cal_free_bytes
[] = {
94 MT_EE_TEMP_SENSOR_CAL
,
96 MT_EE_XTAL_FREQ_OFFSET
,
99 MT_EE_TX_POWER_0_START_2G
,
100 MT_EE_TX_POWER_0_START_2G
+ 1,
101 MT_EE_TX_POWER_1_START_2G
,
102 MT_EE_TX_POWER_1_START_2G
+ 1,
104 struct device_node
*np
= dev
->mt76
.dev
->of_node
;
105 u8
*eeprom
= dev
->mt76
.eeprom
.data
;
106 int n
= ARRAY_SIZE(cal_free_bytes
);
109 if (!np
|| !of_property_read_bool(np
, "mediatek,eeprom-merge-otp"))
112 if (!mt7603_has_cal_free_data(dev
, efuse
))
118 for (i
= 0; i
< n
; i
++) {
119 int offset
= cal_free_bytes
[i
];
121 eeprom
[offset
] = efuse
[offset
];
126 mt7603_eeprom_load(struct mt7603_dev
*dev
)
130 ret
= mt76_eeprom_init(&dev
->mt76
, MT7603_EEPROM_SIZE
);
134 return mt7603_efuse_init(dev
);
137 static int mt7603_check_eeprom(struct mt76_dev
*dev
)
139 u16 val
= get_unaligned_le16(dev
->eeprom
.data
);
151 static inline bool is_mt7688(struct mt7603_dev
*dev
)
153 return mt76_rr(dev
, MT_EFUSE_BASE
+ 0x64) & BIT(4);
156 int mt7603_eeprom_init(struct mt7603_dev
*dev
)
161 ret
= mt7603_eeprom_load(dev
);
165 if (dev
->mt76
.otp
.data
) {
166 if (mt7603_check_eeprom(&dev
->mt76
) == 0)
167 mt7603_apply_cal_free_data(dev
, dev
->mt76
.otp
.data
);
169 memcpy(dev
->mt76
.eeprom
.data
, dev
->mt76
.otp
.data
,
173 eeprom
= (u8
*)dev
->mt76
.eeprom
.data
;
174 dev
->mphy
.cap
.has_2ghz
= true;
175 memcpy(dev
->mphy
.macaddr
, eeprom
+ MT_EE_MAC_ADDR
, ETH_ALEN
);
177 /* Check for 1SS devices */
178 dev
->mphy
.antenna_mask
= 3;
179 if (FIELD_GET(MT_EE_NIC_CONF_0_RX_PATH
, eeprom
[MT_EE_NIC_CONF_0
]) == 1 ||
180 FIELD_GET(MT_EE_NIC_CONF_0_TX_PATH
, eeprom
[MT_EE_NIC_CONF_0
]) == 1 ||
182 dev
->mphy
.antenna_mask
= 1;
184 mt76_eeprom_override(&dev
->mphy
);