xref: /openbmc/linux/drivers/net/wireless/ath/ath10k/hw.c (revision 1c2dd16a)
1 /*
2  * Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <linux/types.h>
18 #include "core.h"
19 #include "hw.h"
20 #include "hif.h"
21 #include "wmi-ops.h"
22 #include "bmi.h"
23 
24 const struct ath10k_hw_regs qca988x_regs = {
25 	.rtc_soc_base_address		= 0x00004000,
26 	.rtc_wmac_base_address		= 0x00005000,
27 	.soc_core_base_address		= 0x00009000,
28 	.wlan_mac_base_address		= 0x00020000,
29 	.ce_wrapper_base_address	= 0x00057000,
30 	.ce0_base_address		= 0x00057400,
31 	.ce1_base_address		= 0x00057800,
32 	.ce2_base_address		= 0x00057c00,
33 	.ce3_base_address		= 0x00058000,
34 	.ce4_base_address		= 0x00058400,
35 	.ce5_base_address		= 0x00058800,
36 	.ce6_base_address		= 0x00058c00,
37 	.ce7_base_address		= 0x00059000,
38 	.soc_reset_control_si0_rst_mask	= 0x00000001,
39 	.soc_reset_control_ce_rst_mask	= 0x00040000,
40 	.soc_chip_id_address		= 0x000000ec,
41 	.scratch_3_address		= 0x00000030,
42 	.fw_indicator_address		= 0x00009030,
43 	.pcie_local_base_address	= 0x00080000,
44 	.ce_wrap_intr_sum_host_msi_lsb	= 0x00000008,
45 	.ce_wrap_intr_sum_host_msi_mask	= 0x0000ff00,
46 	.pcie_intr_fw_mask		= 0x00000400,
47 	.pcie_intr_ce_mask_all		= 0x0007f800,
48 	.pcie_intr_clr_address		= 0x00000014,
49 };
50 
51 const struct ath10k_hw_regs qca6174_regs = {
52 	.rtc_soc_base_address			= 0x00000800,
53 	.rtc_wmac_base_address			= 0x00001000,
54 	.soc_core_base_address			= 0x0003a000,
55 	.wlan_mac_base_address			= 0x00010000,
56 	.ce_wrapper_base_address		= 0x00034000,
57 	.ce0_base_address			= 0x00034400,
58 	.ce1_base_address			= 0x00034800,
59 	.ce2_base_address			= 0x00034c00,
60 	.ce3_base_address			= 0x00035000,
61 	.ce4_base_address			= 0x00035400,
62 	.ce5_base_address			= 0x00035800,
63 	.ce6_base_address			= 0x00035c00,
64 	.ce7_base_address			= 0x00036000,
65 	.soc_reset_control_si0_rst_mask		= 0x00000000,
66 	.soc_reset_control_ce_rst_mask		= 0x00000001,
67 	.soc_chip_id_address			= 0x000000f0,
68 	.scratch_3_address			= 0x00000028,
69 	.fw_indicator_address			= 0x0003a028,
70 	.pcie_local_base_address		= 0x00080000,
71 	.ce_wrap_intr_sum_host_msi_lsb		= 0x00000008,
72 	.ce_wrap_intr_sum_host_msi_mask		= 0x0000ff00,
73 	.pcie_intr_fw_mask			= 0x00000400,
74 	.pcie_intr_ce_mask_all			= 0x0007f800,
75 	.pcie_intr_clr_address			= 0x00000014,
76 	.cpu_pll_init_address			= 0x00404020,
77 	.cpu_speed_address			= 0x00404024,
78 	.core_clk_div_address			= 0x00404028,
79 };
80 
81 const struct ath10k_hw_regs qca99x0_regs = {
82 	.rtc_soc_base_address			= 0x00080000,
83 	.rtc_wmac_base_address			= 0x00000000,
84 	.soc_core_base_address			= 0x00082000,
85 	.wlan_mac_base_address			= 0x00030000,
86 	.ce_wrapper_base_address		= 0x0004d000,
87 	.ce0_base_address			= 0x0004a000,
88 	.ce1_base_address			= 0x0004a400,
89 	.ce2_base_address			= 0x0004a800,
90 	.ce3_base_address			= 0x0004ac00,
91 	.ce4_base_address			= 0x0004b000,
92 	.ce5_base_address			= 0x0004b400,
93 	.ce6_base_address			= 0x0004b800,
94 	.ce7_base_address			= 0x0004bc00,
95 	/* Note: qca99x0 supports upto 12 Copy Engines. Other than address of
96 	 * CE0 and CE1 no other copy engine is directly referred in the code.
97 	 * It is not really necessary to assign address for newly supported
98 	 * CEs in this address table.
99 	 *	Copy Engine		Address
100 	 *	CE8			0x0004c000
101 	 *	CE9			0x0004c400
102 	 *	CE10			0x0004c800
103 	 *	CE11			0x0004cc00
104 	 */
105 	.soc_reset_control_si0_rst_mask		= 0x00000001,
106 	.soc_reset_control_ce_rst_mask		= 0x00000100,
107 	.soc_chip_id_address			= 0x000000ec,
108 	.scratch_3_address			= 0x00040050,
109 	.fw_indicator_address			= 0x00040050,
110 	.pcie_local_base_address		= 0x00000000,
111 	.ce_wrap_intr_sum_host_msi_lsb		= 0x0000000c,
112 	.ce_wrap_intr_sum_host_msi_mask		= 0x00fff000,
113 	.pcie_intr_fw_mask			= 0x00100000,
114 	.pcie_intr_ce_mask_all			= 0x000fff00,
115 	.pcie_intr_clr_address			= 0x00000010,
116 };
117 
118 const struct ath10k_hw_regs qca4019_regs = {
119 	.rtc_soc_base_address                   = 0x00080000,
120 	.soc_core_base_address                  = 0x00082000,
121 	.wlan_mac_base_address                  = 0x00030000,
122 	.ce_wrapper_base_address                = 0x0004d000,
123 	.ce0_base_address                       = 0x0004a000,
124 	.ce1_base_address                       = 0x0004a400,
125 	.ce2_base_address                       = 0x0004a800,
126 	.ce3_base_address                       = 0x0004ac00,
127 	.ce4_base_address                       = 0x0004b000,
128 	.ce5_base_address                       = 0x0004b400,
129 	.ce6_base_address                       = 0x0004b800,
130 	.ce7_base_address                       = 0x0004bc00,
131 	/* qca4019 supports upto 12 copy engines. Since base address
132 	 * of ce8 to ce11 are not directly referred in the code,
133 	 * no need have them in separate members in this table.
134 	 *      Copy Engine             Address
135 	 *      CE8                     0x0004c000
136 	 *      CE9                     0x0004c400
137 	 *      CE10                    0x0004c800
138 	 *      CE11                    0x0004cc00
139 	 */
140 	.soc_reset_control_si0_rst_mask         = 0x00000001,
141 	.soc_reset_control_ce_rst_mask          = 0x00000100,
142 	.soc_chip_id_address                    = 0x000000ec,
143 	.fw_indicator_address                   = 0x0004f00c,
144 	.ce_wrap_intr_sum_host_msi_lsb          = 0x0000000c,
145 	.ce_wrap_intr_sum_host_msi_mask         = 0x00fff000,
146 	.pcie_intr_fw_mask                      = 0x00100000,
147 	.pcie_intr_ce_mask_all                  = 0x000fff00,
148 	.pcie_intr_clr_address                  = 0x00000010,
149 };
150 
151 const struct ath10k_hw_values qca988x_values = {
152 	.rtc_state_val_on		= 3,
153 	.ce_count			= 8,
154 	.msi_assign_ce_max		= 7,
155 	.num_target_ce_config_wlan	= 7,
156 	.ce_desc_meta_data_mask		= 0xFFFC,
157 	.ce_desc_meta_data_lsb		= 2,
158 };
159 
160 const struct ath10k_hw_values qca6174_values = {
161 	.rtc_state_val_on		= 3,
162 	.ce_count			= 8,
163 	.msi_assign_ce_max		= 7,
164 	.num_target_ce_config_wlan	= 7,
165 	.ce_desc_meta_data_mask		= 0xFFFC,
166 	.ce_desc_meta_data_lsb		= 2,
167 };
168 
169 const struct ath10k_hw_values qca99x0_values = {
170 	.rtc_state_val_on		= 5,
171 	.ce_count			= 12,
172 	.msi_assign_ce_max		= 12,
173 	.num_target_ce_config_wlan	= 10,
174 	.ce_desc_meta_data_mask		= 0xFFF0,
175 	.ce_desc_meta_data_lsb		= 4,
176 };
177 
178 const struct ath10k_hw_values qca9888_values = {
179 	.rtc_state_val_on		= 3,
180 	.ce_count			= 12,
181 	.msi_assign_ce_max		= 12,
182 	.num_target_ce_config_wlan	= 10,
183 	.ce_desc_meta_data_mask		= 0xFFF0,
184 	.ce_desc_meta_data_lsb		= 4,
185 };
186 
187 const struct ath10k_hw_values qca4019_values = {
188 	.ce_count                       = 12,
189 	.num_target_ce_config_wlan      = 10,
190 	.ce_desc_meta_data_mask         = 0xFFF0,
191 	.ce_desc_meta_data_lsb          = 4,
192 };
193 
194 const struct ath10k_hw_clk_params qca6174_clk[ATH10K_HW_REFCLK_COUNT] = {
195 	{
196 		.refclk = 48000000,
197 		.div = 0xe,
198 		.rnfrac = 0x2aaa8,
199 		.settle_time = 2400,
200 		.refdiv = 0,
201 		.outdiv = 1,
202 	},
203 	{
204 		.refclk = 19200000,
205 		.div = 0x24,
206 		.rnfrac = 0x2aaa8,
207 		.settle_time = 960,
208 		.refdiv = 0,
209 		.outdiv = 1,
210 	},
211 	{
212 		.refclk = 24000000,
213 		.div = 0x1d,
214 		.rnfrac = 0x15551,
215 		.settle_time = 1200,
216 		.refdiv = 0,
217 		.outdiv = 1,
218 	},
219 	{
220 		.refclk = 26000000,
221 		.div = 0x1b,
222 		.rnfrac = 0x4ec4,
223 		.settle_time = 1300,
224 		.refdiv = 0,
225 		.outdiv = 1,
226 	},
227 	{
228 		.refclk = 37400000,
229 		.div = 0x12,
230 		.rnfrac = 0x34b49,
231 		.settle_time = 1870,
232 		.refdiv = 0,
233 		.outdiv = 1,
234 	},
235 	{
236 		.refclk = 38400000,
237 		.div = 0x12,
238 		.rnfrac = 0x15551,
239 		.settle_time = 1920,
240 		.refdiv = 0,
241 		.outdiv = 1,
242 	},
243 	{
244 		.refclk = 40000000,
245 		.div = 0x12,
246 		.rnfrac = 0x26665,
247 		.settle_time = 2000,
248 		.refdiv = 0,
249 		.outdiv = 1,
250 	},
251 	{
252 		.refclk = 52000000,
253 		.div = 0x1b,
254 		.rnfrac = 0x4ec4,
255 		.settle_time = 2600,
256 		.refdiv = 0,
257 		.outdiv = 1,
258 	},
259 };
260 
261 void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
262 				u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
263 {
264 	u32 cc_fix = 0;
265 	u32 rcc_fix = 0;
266 	enum ath10k_hw_cc_wraparound_type wraparound_type;
267 
268 	survey->filled |= SURVEY_INFO_TIME |
269 			  SURVEY_INFO_TIME_BUSY;
270 
271 	wraparound_type = ar->hw_params.cc_wraparound_type;
272 
273 	if (cc < cc_prev || rcc < rcc_prev) {
274 		switch (wraparound_type) {
275 		case ATH10K_HW_CC_WRAP_SHIFTED_ALL:
276 			if (cc < cc_prev) {
277 				cc_fix = 0x7fffffff;
278 				survey->filled &= ~SURVEY_INFO_TIME_BUSY;
279 			}
280 			break;
281 		case ATH10K_HW_CC_WRAP_SHIFTED_EACH:
282 			if (cc < cc_prev)
283 				cc_fix = 0x7fffffff;
284 
285 			if (rcc < rcc_prev)
286 				rcc_fix = 0x7fffffff;
287 			break;
288 		case ATH10K_HW_CC_WRAP_DISABLED:
289 			break;
290 		}
291 	}
292 
293 	cc -= cc_prev - cc_fix;
294 	rcc -= rcc_prev - rcc_fix;
295 
296 	survey->time = CCNT_TO_MSEC(ar, cc);
297 	survey->time_busy = CCNT_TO_MSEC(ar, rcc);
298 }
299 
300 /* The firmware does not support setting the coverage class. Instead this
301  * function monitors and modifies the corresponding MAC registers.
302  */
303 static void ath10k_hw_qca988x_set_coverage_class(struct ath10k *ar,
304 						 s16 value)
305 {
306 	u32 slottime_reg;
307 	u32 slottime;
308 	u32 timeout_reg;
309 	u32 ack_timeout;
310 	u32 cts_timeout;
311 	u32 phyclk_reg;
312 	u32 phyclk;
313 	u64 fw_dbglog_mask;
314 	u32 fw_dbglog_level;
315 
316 	mutex_lock(&ar->conf_mutex);
317 
318 	/* Only modify registers if the core is started. */
319 	if ((ar->state != ATH10K_STATE_ON) &&
320 	    (ar->state != ATH10K_STATE_RESTARTED))
321 		goto unlock;
322 
323 	/* Retrieve the current values of the two registers that need to be
324 	 * adjusted.
325 	 */
326 	slottime_reg = ath10k_hif_read32(ar, WLAN_MAC_BASE_ADDRESS +
327 					     WAVE1_PCU_GBL_IFS_SLOT);
328 	timeout_reg = ath10k_hif_read32(ar, WLAN_MAC_BASE_ADDRESS +
329 					    WAVE1_PCU_ACK_CTS_TIMEOUT);
330 	phyclk_reg = ath10k_hif_read32(ar, WLAN_MAC_BASE_ADDRESS +
331 					   WAVE1_PHYCLK);
332 	phyclk = MS(phyclk_reg, WAVE1_PHYCLK_USEC) + 1;
333 
334 	if (value < 0)
335 		value = ar->fw_coverage.coverage_class;
336 
337 	/* Break out if the coverage class and registers have the expected
338 	 * value.
339 	 */
340 	if (value == ar->fw_coverage.coverage_class &&
341 	    slottime_reg == ar->fw_coverage.reg_slottime_conf &&
342 	    timeout_reg == ar->fw_coverage.reg_ack_cts_timeout_conf &&
343 	    phyclk_reg == ar->fw_coverage.reg_phyclk)
344 		goto unlock;
345 
346 	/* Store new initial register values from the firmware. */
347 	if (slottime_reg != ar->fw_coverage.reg_slottime_conf)
348 		ar->fw_coverage.reg_slottime_orig = slottime_reg;
349 	if (timeout_reg != ar->fw_coverage.reg_ack_cts_timeout_conf)
350 		ar->fw_coverage.reg_ack_cts_timeout_orig = timeout_reg;
351 	ar->fw_coverage.reg_phyclk = phyclk_reg;
352 
353 	/* Calculat new value based on the (original) firmware calculation. */
354 	slottime_reg = ar->fw_coverage.reg_slottime_orig;
355 	timeout_reg = ar->fw_coverage.reg_ack_cts_timeout_orig;
356 
357 	/* Do some sanity checks on the slottime register. */
358 	if (slottime_reg % phyclk) {
359 		ath10k_warn(ar,
360 			    "failed to set coverage class: expected integer microsecond value in register\n");
361 
362 		goto store_regs;
363 	}
364 
365 	slottime = MS(slottime_reg, WAVE1_PCU_GBL_IFS_SLOT);
366 	slottime = slottime / phyclk;
367 	if (slottime != 9 && slottime != 20) {
368 		ath10k_warn(ar,
369 			    "failed to set coverage class: expected slot time of 9 or 20us in HW register. It is %uus.\n",
370 			    slottime);
371 
372 		goto store_regs;
373 	}
374 
375 	/* Recalculate the register values by adding the additional propagation
376 	 * delay (3us per coverage class).
377 	 */
378 
379 	slottime = MS(slottime_reg, WAVE1_PCU_GBL_IFS_SLOT);
380 	slottime += value * 3 * phyclk;
381 	slottime = min_t(u32, slottime, WAVE1_PCU_GBL_IFS_SLOT_MAX);
382 	slottime = SM(slottime, WAVE1_PCU_GBL_IFS_SLOT);
383 	slottime_reg = (slottime_reg & ~WAVE1_PCU_GBL_IFS_SLOT_MASK) | slottime;
384 
385 	/* Update ack timeout (lower halfword). */
386 	ack_timeout = MS(timeout_reg, WAVE1_PCU_ACK_CTS_TIMEOUT_ACK);
387 	ack_timeout += 3 * value * phyclk;
388 	ack_timeout = min_t(u32, ack_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_MAX);
389 	ack_timeout = SM(ack_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_ACK);
390 
391 	/* Update cts timeout (upper halfword). */
392 	cts_timeout = MS(timeout_reg, WAVE1_PCU_ACK_CTS_TIMEOUT_CTS);
393 	cts_timeout += 3 * value * phyclk;
394 	cts_timeout = min_t(u32, cts_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_MAX);
395 	cts_timeout = SM(cts_timeout, WAVE1_PCU_ACK_CTS_TIMEOUT_CTS);
396 
397 	timeout_reg = ack_timeout | cts_timeout;
398 
399 	ath10k_hif_write32(ar,
400 			   WLAN_MAC_BASE_ADDRESS + WAVE1_PCU_GBL_IFS_SLOT,
401 			   slottime_reg);
402 	ath10k_hif_write32(ar,
403 			   WLAN_MAC_BASE_ADDRESS + WAVE1_PCU_ACK_CTS_TIMEOUT,
404 			   timeout_reg);
405 
406 	/* Ensure we have a debug level of WARN set for the case that the
407 	 * coverage class is larger than 0. This is important as we need to
408 	 * set the registers again if the firmware does an internal reset and
409 	 * this way we will be notified of the event.
410 	 */
411 	fw_dbglog_mask = ath10k_debug_get_fw_dbglog_mask(ar);
412 	fw_dbglog_level = ath10k_debug_get_fw_dbglog_level(ar);
413 
414 	if (value > 0) {
415 		if (fw_dbglog_level > ATH10K_DBGLOG_LEVEL_WARN)
416 			fw_dbglog_level = ATH10K_DBGLOG_LEVEL_WARN;
417 		fw_dbglog_mask = ~0;
418 	}
419 
420 	ath10k_wmi_dbglog_cfg(ar, fw_dbglog_mask, fw_dbglog_level);
421 
422 store_regs:
423 	/* After an error we will not retry setting the coverage class. */
424 	spin_lock_bh(&ar->data_lock);
425 	ar->fw_coverage.coverage_class = value;
426 	spin_unlock_bh(&ar->data_lock);
427 
428 	ar->fw_coverage.reg_slottime_conf = slottime_reg;
429 	ar->fw_coverage.reg_ack_cts_timeout_conf = timeout_reg;
430 
431 unlock:
432 	mutex_unlock(&ar->conf_mutex);
433 }
434 
435 /**
436  * ath10k_hw_qca6174_enable_pll_clock() - enable the qca6174 hw pll clock
437  * @ar: the ath10k blob
438  *
439  * This function is very hardware specific, the clock initialization
440  * steps is very sensitive and could lead to unknown crash, so they
441  * should be done in sequence.
442  *
443  * *** Be aware if you planned to refactor them. ***
444  *
445  * Return: 0 if successfully enable the pll, otherwise EINVAL
446  */
447 static int ath10k_hw_qca6174_enable_pll_clock(struct ath10k *ar)
448 {
449 	int ret, wait_limit;
450 	u32 clk_div_addr, pll_init_addr, speed_addr;
451 	u32 addr, reg_val, mem_val;
452 	struct ath10k_hw_params *hw;
453 	const struct ath10k_hw_clk_params *hw_clk;
454 
455 	hw = &ar->hw_params;
456 
457 	if (ar->regs->core_clk_div_address == 0 ||
458 	    ar->regs->cpu_pll_init_address == 0 ||
459 	    ar->regs->cpu_speed_address == 0)
460 		return -EINVAL;
461 
462 	clk_div_addr = ar->regs->core_clk_div_address;
463 	pll_init_addr = ar->regs->cpu_pll_init_address;
464 	speed_addr = ar->regs->cpu_speed_address;
465 
466 	/* Read efuse register to find out the right hw clock configuration */
467 	addr = (RTC_SOC_BASE_ADDRESS | EFUSE_OFFSET);
468 	ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
469 	if (ret)
470 		return -EINVAL;
471 
472 	/* sanitize if the hw refclk index is out of the boundary */
473 	if (MS(reg_val, EFUSE_XTAL_SEL) > ATH10K_HW_REFCLK_COUNT)
474 		return -EINVAL;
475 
476 	hw_clk = &hw->hw_clk[MS(reg_val, EFUSE_XTAL_SEL)];
477 
478 	/* Set the rnfrac and outdiv params to bb_pll register */
479 	addr = (RTC_SOC_BASE_ADDRESS | BB_PLL_CONFIG_OFFSET);
480 	ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
481 	if (ret)
482 		return -EINVAL;
483 
484 	reg_val &= ~(BB_PLL_CONFIG_FRAC_MASK | BB_PLL_CONFIG_OUTDIV_MASK);
485 	reg_val |= (SM(hw_clk->rnfrac, BB_PLL_CONFIG_FRAC) |
486 		    SM(hw_clk->outdiv, BB_PLL_CONFIG_OUTDIV));
487 	ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
488 	if (ret)
489 		return -EINVAL;
490 
491 	/* Set the correct settle time value to pll_settle register */
492 	addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_SETTLE_OFFSET);
493 	ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
494 	if (ret)
495 		return -EINVAL;
496 
497 	reg_val &= ~WLAN_PLL_SETTLE_TIME_MASK;
498 	reg_val |= SM(hw_clk->settle_time, WLAN_PLL_SETTLE_TIME);
499 	ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
500 	if (ret)
501 		return -EINVAL;
502 
503 	/* Set the clock_ctrl div to core_clk_ctrl register */
504 	addr = (RTC_SOC_BASE_ADDRESS | SOC_CORE_CLK_CTRL_OFFSET);
505 	ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
506 	if (ret)
507 		return -EINVAL;
508 
509 	reg_val &= ~SOC_CORE_CLK_CTRL_DIV_MASK;
510 	reg_val |= SM(1, SOC_CORE_CLK_CTRL_DIV);
511 	ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
512 	if (ret)
513 		return -EINVAL;
514 
515 	/* Set the clock_div register */
516 	mem_val = 1;
517 	ret = ath10k_bmi_write_memory(ar, clk_div_addr, &mem_val,
518 				      sizeof(mem_val));
519 	if (ret)
520 		return -EINVAL;
521 
522 	/* Configure the pll_control register */
523 	addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
524 	ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
525 	if (ret)
526 		return -EINVAL;
527 
528 	reg_val |= (SM(hw_clk->refdiv, WLAN_PLL_CONTROL_REFDIV) |
529 		    SM(hw_clk->div, WLAN_PLL_CONTROL_DIV) |
530 		    SM(1, WLAN_PLL_CONTROL_NOPWD));
531 	ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
532 	if (ret)
533 		return -EINVAL;
534 
535 	/* busy wait (max 1s) the rtc_sync status register indicate ready */
536 	wait_limit = 100000;
537 	addr = (RTC_WMAC_BASE_ADDRESS | RTC_SYNC_STATUS_OFFSET);
538 	do {
539 		ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
540 		if (ret)
541 			return -EINVAL;
542 
543 		if (!MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
544 			break;
545 
546 		wait_limit--;
547 		udelay(10);
548 
549 	} while (wait_limit > 0);
550 
551 	if (MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
552 		return -EINVAL;
553 
554 	/* Unset the pll_bypass in pll_control register */
555 	addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
556 	ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
557 	if (ret)
558 		return -EINVAL;
559 
560 	reg_val &= ~WLAN_PLL_CONTROL_BYPASS_MASK;
561 	reg_val |= SM(0, WLAN_PLL_CONTROL_BYPASS);
562 	ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
563 	if (ret)
564 		return -EINVAL;
565 
566 	/* busy wait (max 1s) the rtc_sync status register indicate ready */
567 	wait_limit = 100000;
568 	addr = (RTC_WMAC_BASE_ADDRESS | RTC_SYNC_STATUS_OFFSET);
569 	do {
570 		ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
571 		if (ret)
572 			return -EINVAL;
573 
574 		if (!MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
575 			break;
576 
577 		wait_limit--;
578 		udelay(10);
579 
580 	} while (wait_limit > 0);
581 
582 	if (MS(reg_val, RTC_SYNC_STATUS_PLL_CHANGING))
583 		return -EINVAL;
584 
585 	/* Enable the hardware cpu clock register */
586 	addr = (RTC_SOC_BASE_ADDRESS | SOC_CPU_CLOCK_OFFSET);
587 	ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
588 	if (ret)
589 		return -EINVAL;
590 
591 	reg_val &= ~SOC_CPU_CLOCK_STANDARD_MASK;
592 	reg_val |= SM(1, SOC_CPU_CLOCK_STANDARD);
593 	ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
594 	if (ret)
595 		return -EINVAL;
596 
597 	/* unset the nopwd from pll_control register */
598 	addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
599 	ret = ath10k_bmi_read_soc_reg(ar, addr, &reg_val);
600 	if (ret)
601 		return -EINVAL;
602 
603 	reg_val &= ~WLAN_PLL_CONTROL_NOPWD_MASK;
604 	ret = ath10k_bmi_write_soc_reg(ar, addr, reg_val);
605 	if (ret)
606 		return -EINVAL;
607 
608 	/* enable the pll_init register */
609 	mem_val = 1;
610 	ret = ath10k_bmi_write_memory(ar, pll_init_addr, &mem_val,
611 				      sizeof(mem_val));
612 	if (ret)
613 		return -EINVAL;
614 
615 	/* set the target clock frequency to speed register */
616 	ret = ath10k_bmi_write_memory(ar, speed_addr, &hw->target_cpu_freq,
617 				      sizeof(hw->target_cpu_freq));
618 	if (ret)
619 		return -EINVAL;
620 
621 	return 0;
622 }
623 
624 const struct ath10k_hw_ops qca988x_ops = {
625 	.set_coverage_class = ath10k_hw_qca988x_set_coverage_class,
626 };
627 
628 static int ath10k_qca99x0_rx_desc_get_l3_pad_bytes(struct htt_rx_desc *rxd)
629 {
630 	return MS(__le32_to_cpu(rxd->msdu_end.qca99x0.info1),
631 		  RX_MSDU_END_INFO1_L3_HDR_PAD);
632 }
633 
634 const struct ath10k_hw_ops qca99x0_ops = {
635 	.rx_desc_get_l3_pad_bytes = ath10k_qca99x0_rx_desc_get_l3_pad_bytes,
636 };
637 
638 const struct ath10k_hw_ops qca6174_ops = {
639 	.set_coverage_class = ath10k_hw_qca988x_set_coverage_class,
640 	.enable_pll_clk = ath10k_hw_qca6174_enable_pll_clock,
641 };
642