1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3 
4 /*++
5 
6 Module Name:
7 	HalPwrSeqCmd.c
8 
9 Abstract:
10 	Implement HW Power sequence configuration CMD handling routine for Realtek devices.
11 
12 Major Change History:
13 	When       Who               What
14 	---------- ---------------   -------------------------------
15 	2011-10-26 Lucas            Modify to be compatible with SD4-CE driver.
16 	2011-07-07 Roger            Create.
17 
18 --*/
19 
20 #include "../include/HalPwrSeqCmd.h"
21 
22 /*	Description: */
23 /*		This routine deals with the Power Configuration CMDs parsing
24  *		for RTL8723/RTL8188E Series IC.
25  *	Assumption:
26  *		We should follow specific format which was released from HW SD.
27  */
HalPwrSeqCmdParsing(struct adapter * padapter,u8 cut_vers,u8 fab_vers,u8 ifacetype,struct wl_pwr_cfg pwrseqcmd[])28 u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
29 		       u8 ifacetype, struct wl_pwr_cfg pwrseqcmd[])
30 {
31 	struct wl_pwr_cfg pwrcfgcmd = {0};
32 	u8 poll_bit = false;
33 	u32 aryidx = 0;
34 	u8 value = 0;
35 	u32 offset = 0;
36 	u32 poll_count = 0; /*  polling autoload done. */
37 	u32 max_poll_count = 5000;
38 
39 	do {
40 		pwrcfgcmd = pwrseqcmd[aryidx];
41 
42 		/* 2 Only Handle the command whose FAB, CUT, and Interface are matched */
43 		if ((GET_PWR_CFG_FAB_MASK(pwrcfgcmd) & fab_vers) &&
44 		    (GET_PWR_CFG_CUT_MASK(pwrcfgcmd) & cut_vers) &&
45 		    (GET_PWR_CFG_INTF_MASK(pwrcfgcmd) & ifacetype)) {
46 			switch (GET_PWR_CFG_CMD(pwrcfgcmd)) {
47 			case PWR_CMD_WRITE:
48 				offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
49 
50 				/*  Read the value from system register */
51 				value = rtw_read8(padapter, offset);
52 
53 				value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
54 				value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd));
55 
56 				/*  Write the value back to system register */
57 				rtw_write8(padapter, offset, value);
58 				break;
59 			case PWR_CMD_POLLING:
60 				poll_bit = false;
61 				offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
62 				do {
63 					value = rtw_read8(padapter, offset);
64 
65 					value &= GET_PWR_CFG_MASK(pwrcfgcmd);
66 					if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)))
67 						poll_bit = true;
68 					else
69 						udelay(10);
70 
71 					if (poll_count++ > max_poll_count) {
72 						DBG_88E("Fail to polling Offset[%#x]\n", offset);
73 						return false;
74 					}
75 				} while (!poll_bit);
76 				break;
77 			case PWR_CMD_DELAY:
78 				if (GET_PWR_CFG_VALUE(pwrcfgcmd) == PWRSEQ_DELAY_US)
79 					udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd));
80 				else
81 					udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd) * 1000);
82 				break;
83 			case PWR_CMD_END:
84 				/*  When this command is parsed, end the process */
85 				return true;
86 				break;
87 			default:
88 				break;
89 			}
90 		}
91 
92 		aryidx++;/* Add Array Index */
93 	} while (1);
94 	return true;
95 }
96