xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/ssv6xxx/smac/sar.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (c) 2015 South Silicon Valley Microelectronics Inc.
3  * Copyright (c) 2015 iComm Corporation
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  * See the GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #include <ssv6200_reg.h>
18 #include <ssv6200_aux.h>
19 #include <linux/fs.h>
20 #include "dev.h"
21 #include "sar.h"
22 
23 WIFI_FLASH_CCFG flash_cfg = {
24     //16bytes
25     0x6051, 0x3009, 0x20170519, 0x1, 0x0, 0x0,
26     {   //16bytes
27         {0x47c000, 0x47c000, 0x47c000, 0x9, 0x1d, 0x0},
28         //16bytes
29         {0x79807980, 0x79807980, 0x79807980, 0x9, 0x1d, 0x0}
30     }
31 };
32 WIFI_FLASH_CCFG *pflash_cfg;
33 
34 struct t_sar_info sar_info[] = {
35     { SAR_LVL_INVALID, 0x0047c000, NULL},
36     { SAR_LVL_INVALID, 0x79807980, NULL}
37 };
38 
39 int sar_info_size = sizeof(sar_info) / sizeof(sar_info[0]);
40 
flash_hexdump(void)41 void flash_hexdump(void)
42 {
43     unsigned i;
44     const u8 *buf = (const char *)pflash_cfg;
45     size_t len = sizeof(flash_cfg);
46     printk("-----------------------------\n");
47     printk("0x00h:");
48     if (buf == NULL) {
49         printk(" [NULL]");
50     } else {
51         for (i = 0; i < len; i++) {
52             printk(" %02x", buf[i]);
53             if ((i + 1) % 16 == 0) {
54                 printk("\n");
55                 if (i + 1 < len)
56                     printk("0x%02xh:", i + 1);
57             }
58         }
59     }
60     printk("-----------------------------\n");
61 }
62 
get_sar_lvl(u32 sar)63 static u8 get_sar_lvl(u32 sar)
64 {
65     static u32 prev_sar = 0;
66     int i;
67     u8 changed = 0x0;
68 
69     if (sar == prev_sar)
70         return changed;
71 
72     printk("[thermal_sar] %d\n", (int)sar);
73 
74     for (i = 0; i < sar_info_size; i++) {
75         if (sar_info[i].lvl == SAR_LVL_INVALID) {//if driver loaded under LT/HT env, it would cause wrong settings at this time.
76             sar_info[i].lvl = SAR_LVL_RT;
77             sar_info[i].value = sar_info[i].p->rt;
78             changed |= BIT(i);
79         }
80         else if (sar_info[i].lvl == SAR_LVL_RT) {
81             if (sar < prev_sar) {
82                 if (sar <= (u32)(sar_info[i].p->lt_ts - 2)) { //we need check if (g_tt_lt - 1) < SAR_MIN
83                     sar_info[i].lvl = SAR_LVL_LT;
84                     sar_info[i].value = sar_info[i].p->lt;
85                     changed |= BIT(i);
86                 }
87             }
88             else if (sar > prev_sar){
89                 if (sar >= (u32)(sar_info[i].p->ht_ts + 2)) { //we need check if (g_tt_lt + 1) > SAR_MAX
90                     sar_info[i].lvl = SAR_LVL_HT;
91                     sar_info[i].value = sar_info[i].p->ht;
92                     changed |= BIT(i);
93                 }
94             }
95         }
96         else if (sar_info[i].lvl == SAR_LVL_LT) {
97             if (sar >= (u32)(sar_info[i].p->lt_ts + 2)) {
98                 sar_info[i].lvl = SAR_LVL_RT;
99                 sar_info[i].value = sar_info[i].p->rt;
100                 changed |= BIT(i);
101             }
102         }
103         else if (sar_info[i].lvl == SAR_LVL_HT) {
104             if (sar <= (u32)(sar_info[i].p->ht_ts - 2)) {
105                 sar_info[i].lvl = SAR_LVL_RT;
106                 sar_info[i].value = sar_info[i].p->rt;
107                 changed |= BIT(i);
108             }
109         }
110     }
111     if (changed) {
112         printk("changed: 0x%x\n", changed);
113 	}
114     prev_sar = sar;
115     return changed;
116 }
117 
sar_monitor(u32 curr_sar,struct ssv_softc * sc)118 void sar_monitor(u32 curr_sar, struct ssv_softc *sc)
119 {
120     //static u32 prev_sar_lvl = SAR_LVL_INVALID; //sar = 0, temparature < -25C
121     u8 changed;
122     changed = get_sar_lvl(curr_sar);
123 
124     if (changed & BIT(SAR_TXGAIN_INDEX)) {
125         printk("TXGAIN: 0x%08x\n", sar_info[SAR_TXGAIN_INDEX].value);
126         SMAC_REG_WRITE(sc->sh, ADR_TX_GAIN_FACTOR, sar_info[SAR_TXGAIN_INDEX].value);
127     }
128     if (changed & BIT(SAR_XTAL_INDEX)) {
129         printk("XTAL: 0x%08x\n", sar_info[SAR_XTAL_INDEX].value);
130         SMAC_REG_WRITE(sc->sh, ADR_SYN_KVCO_XO_FINE_TUNE_CBANK, sar_info[SAR_XTAL_INDEX].value);
131     }
132 }
133 
134 /*
135     SET_RG_SARADC_THERMAL(1);     //ce010030[26]
136     SET_RG_EN_SARADC(1);          //ce010030[30]
137     while(!GET_SAR_ADC_FSM_RDY);  //ce010094[23]
138     sar_code = GET_RG_SARADC_BIT; //ce010094[21:16]
139     SET_RG_SARADC_THERMAL(0);
140     SET_RG_EN_SARADC(0);
141 */
thermal_monitor(struct work_struct * work)142 void thermal_monitor(struct work_struct *work)
143 {
144     struct ssv_softc *sc = container_of(work, struct ssv_softc, thermal_monitor_work.work);
145     u32 curr_sar;
146 
147     u32 temp;
148     if (sc->ps_status == PWRSV_PREPARE) {
149         printk("sar PWRSV_PREPARE\n");
150         return;
151     }
152 
153     mutex_lock(&sc->mutex);
154     SMAC_REG_READ(sc->sh, ADR_RX_11B_CCA_1, &temp);
155     if (temp == RX_11B_CCA_IN_SCAN) {
156         printk("in scan\n");
157         mutex_unlock(&sc->mutex);
158         queue_delayed_work(sc->thermal_wq, &sc->thermal_monitor_work, THERMAL_MONITOR_TIME);
159         return;
160     }
161     SMAC_REG_READ(sc->sh, ADR_RX_ADC_REGISTER, &temp);
162     //printk("ori %08x:%08x\n", ADR_RX_ADC_REGISTER, temp);
163     SMAC_REG_SET_BITS(sc->sh, ADR_RX_ADC_REGISTER, (1 << RG_SARADC_THERMAL_SFT),
164               RG_SARADC_THERMAL_MSK);
165     SMAC_REG_SET_BITS(sc->sh, ADR_RX_ADC_REGISTER, (1 <<  RG_EN_SARADC_SFT),
166               RG_EN_SARADC_MSK);
167 
168     do {
169         msleep(1);
170         SMAC_REG_READ(sc->sh, ADR_READ_ONLY_FLAGS_1, &temp);
171     } while (((temp & SAR_ADC_FSM_RDY_MSK) >> SAR_ADC_FSM_RDY_SFT) != 1);
172     //printk("SAR_ADC_FSM_RDY_STAT %d\n", (temp & SAR_ADC_FSM_RDY_MSK) >> SAR_ADC_FSM_RDY_SFT);
173     curr_sar = (temp & RG_SARADC_BIT_MSK) >> RG_SARADC_BIT_SFT;
174     SMAC_REG_READ(sc->sh, ADR_RX_ADC_REGISTER, &temp);
175 
176     //printk("new %08x:%08x\n", ADR_RX_ADC_REGISTER, temp);
177 
178     SMAC_REG_SET_BITS(sc->sh, ADR_RX_ADC_REGISTER, (0 << RG_SARADC_THERMAL_SFT),
179               RG_SARADC_THERMAL_MSK);
180     SMAC_REG_SET_BITS(sc->sh, ADR_RX_ADC_REGISTER, (0 <<  RG_EN_SARADC_SFT),
181               RG_EN_SARADC_MSK);
182     sar_monitor(curr_sar, sc);
183 
184     mutex_unlock(&sc->mutex);
185 
186     queue_delayed_work(sc->thermal_wq, &sc->thermal_monitor_work, THERMAL_MONITOR_TIME);
187 }
188 
get_flash_info(struct ssv_softc * sc)189 int get_flash_info(struct ssv_softc *sc)
190 {
191     struct file *fp = (struct file *)NULL;
192     mm_segment_t fs;
193     int i, ret;
194 
195     pflash_cfg = &flash_cfg;
196 
197     if (sc->sh->cfg.flash_bin_path[0] != 0x00) {
198         fp = filp_open(sc->sh->cfg.flash_bin_path, O_RDONLY, 0);
199 		 if (IS_ERR(fp) || fp == NULL) {
200              fp = filp_open(SEC_CFG_BIN_NAME, O_RDONLY, 0);
201          }
202     }
203     else{
204         fp = filp_open(DEFAULT_CFG_BIN_NAME, O_RDONLY, 0);
205 		if (IS_ERR(fp) || fp == NULL) {
206 			fp = filp_open(SEC_CFG_BIN_NAME, O_RDONLY, 0);
207 		}
208     }
209     if (IS_ERR(fp) || fp == NULL) {
210         printk("flash_file %s not found, disable sar\n",DEFAULT_CFG_BIN_NAME);
211         //WARN_ON(1);
212         ret = 0;
213         return ret;
214     }
215 
216     fs = get_fs();
217     set_fs(KERNEL_DS);
218     fp->f_op->read(fp, (char *)pflash_cfg, sizeof(flash_cfg), &fp->f_pos);
219     set_fs(fs);
220 
221     filp_close(fp, NULL);
222     ret = 1;
223 
224     flash_hexdump();
225     for (i = 0; i < sar_info_size; i++) {
226         sar_info[i].p = &flash_cfg.sar_rlh[i];
227         printk("rt = %x, lt = %x, ht = %x\n", sar_info[i].p->rt, sar_info[i].p->lt, sar_info[i].p->ht);
228         printk("lt_ts = %x, ht_ts = %x\n", sar_info[i].p->lt_ts, sar_info[i].p->ht_ts);
229     }
230     return ret;
231 }
232 
233