OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | /* Copyright Statement: |
2 | * |
||
3 | * This software/firmware and related documentation ("MediaTek Software") are |
||
4 | * protected under relevant copyright laws. The information contained herein |
||
5 | * is confidential and proprietary to MediaTek Inc. and/or its licensors. |
||
6 | * Without the prior written permission of MediaTek inc. and/or its licensors, |
||
7 | * any reproduction, modification, use or disclosure of MediaTek Software, |
||
8 | * and information contained herein, in whole or in part, shall be strictly prohibited. |
||
9 | * |
||
10 | * MediaTek Inc. (C) 2010. All rights reserved. |
||
11 | * |
||
12 | * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
||
13 | * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
||
14 | * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON |
||
15 | * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
||
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
||
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
||
18 | * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
||
19 | * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
||
20 | * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH |
||
21 | * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES |
||
22 | * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES |
||
23 | * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK |
||
24 | * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR |
||
25 | * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND |
||
26 | * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
||
27 | * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
||
28 | * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO |
||
29 | * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
||
30 | * |
||
31 | * The following software/firmware and/or related documentation ("MediaTek Software") |
||
32 | * have been modified by MediaTek Inc. All revisions are subject to any receiver's |
||
33 | * applicable license agreements with MediaTek Inc. |
||
34 | */ |
||
35 | |||
36 | #include <linux/version.h> |
||
37 | #include <linux/kernel.h> |
||
38 | #include <linux/sched.h> |
||
39 | #include <linux/kthread.h> |
||
40 | #include <linux/delay.h> |
||
41 | #include <linux/module.h> |
||
42 | #include <linux/init.h> |
||
43 | #include <linux/proc_fs.h> |
||
44 | #include <linux/string.h> |
||
45 | #include <linux/uaccess.h> |
||
46 | // #include <mach/mt6575_gpt.h> /* --- by chhung */ |
||
47 | #include "dbg.h" |
||
48 | #include "mt6575_sd.h" |
||
49 | #include <linux/seq_file.h> |
||
50 | |||
51 | /* mode select */ |
||
52 | u32 dma_size[4]={ |
||
53 | 512, |
||
54 | 512, |
||
55 | 512, |
||
56 | 512 |
||
57 | }; |
||
58 | msdc_mode drv_mode[4]={ |
||
59 | MODE_SIZE_DEP, /* using DMA or not depend on the size */ |
||
60 | MODE_SIZE_DEP, |
||
61 | MODE_SIZE_DEP, |
||
62 | MODE_SIZE_DEP |
||
63 | }; |
||
64 | |||
65 | #if defined (MT6575_SD_DEBUG) |
||
66 | static char cmd_buf[256]; |
||
67 | |||
68 | /* for debug zone */ |
||
69 | static unsigned int sd_debug_zone[4]={ |
||
70 | 0, |
||
71 | 0, |
||
72 | 0, |
||
73 | |||
74 | }; |
||
75 | |||
76 | |||
77 | /* for driver profile */ |
||
78 | #define TICKS_ONE_MS (13000) |
||
79 | u32 gpt_enable = 0; |
||
80 | u32 sdio_pro_enable = 0; /* make sure gpt is enabled */ |
||
81 | u32 sdio_pro_time = 0; /* no more than 30s */ |
||
82 | struct sdio_profile sdio_perfomance = {0}; |
||
83 | |||
84 | #if 0 /* --- chhung */ |
||
85 | void msdc_init_gpt(void) |
||
86 | { |
||
87 | GPT_CONFIG config; |
||
88 | |||
89 | config.num = GPT6; |
||
90 | config.mode = GPT_FREE_RUN; |
||
91 | config.clkSrc = GPT_CLK_SRC_SYS; |
||
92 | config.clkDiv = GPT_CLK_DIV_1; /* 13MHz GPT6 */ |
||
93 | |||
94 | if (GPT_Config(config) == FALSE ) |
||
95 | return; |
||
96 | |||
97 | GPT_Start(GPT6); |
||
98 | } |
||
99 | #endif /* end of --- */ |
||
100 | |||
101 | u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32) |
||
102 | { |
||
103 | u32 ret = 0; |
||
104 | |||
105 | if (new_H32 == old_H32) { |
||
106 | ret = new_L32 - old_L32; |
||
107 | } else if(new_H32 == (old_H32 + 1)) { |
||
108 | if (new_L32 > old_L32) { |
||
109 | printk("msdc old_L<0x%x> new_L<0x%x>\n", old_L32, new_L32); |
||
110 | } |
||
111 | ret = (0xffffffff - old_L32); |
||
112 | ret += new_L32; |
||
113 | } else { |
||
114 | printk("msdc old_H<0x%x> new_H<0x%x>\n", old_H32, new_H32); |
||
115 | } |
||
116 | |||
117 | return ret; |
||
118 | } |
||
119 | |||
120 | void msdc_sdio_profile(struct sdio_profile* result) |
||
121 | { |
||
122 | struct cmd_profile* cmd; |
||
123 | u32 i; |
||
124 | |||
125 | printk("sdio === performance dump ===\n"); |
||
126 | printk("sdio === total execute tick<%d> time<%dms> Tx<%dB> Rx<%dB>\n", |
||
127 | result->total_tc, result->total_tc / TICKS_ONE_MS, |
||
128 | result->total_tx_bytes, result->total_rx_bytes); |
||
129 | |||
130 | /* CMD52 Dump */ |
||
131 | cmd = &result->cmd52_rx; |
||
132 | printk("sdio === CMD52 Rx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc, |
||
133 | cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count); |
||
134 | cmd = &result->cmd52_tx; |
||
135 | printk("sdio === CMD52 Tx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc, |
||
136 | cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count); |
||
137 | |||
138 | /* CMD53 Rx bytes + block mode */ |
||
139 | for (i=0; i<512; i++) { |
||
140 | cmd = &result->cmd53_rx_byte[i]; |
||
141 | if (cmd->count) { |
||
142 | printk("sdio<%6d><%3dB>_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, |
||
143 | cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count, |
||
144 | cmd->tot_bytes, (cmd->tot_bytes/10)*13 / (cmd->tot_tc/10)); |
||
145 | } |
||
146 | } |
||
147 | for (i=0; i<100; i++) { |
||
148 | cmd = &result->cmd53_rx_blk[i]; |
||
149 | if (cmd->count) { |
||
150 | printk("sdio<%6d><%3d>B_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, |
||
151 | cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count, |
||
152 | cmd->tot_bytes, (cmd->tot_bytes/10)*13 / (cmd->tot_tc/10)); |
||
153 | } |
||
154 | } |
||
155 | |||
156 | /* CMD53 Tx bytes + block mode */ |
||
157 | for (i=0; i<512; i++) { |
||
158 | cmd = &result->cmd53_tx_byte[i]; |
||
159 | if (cmd->count) { |
||
160 | printk("sdio<%6d><%3dB>_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, |
||
161 | cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count, |
||
162 | cmd->tot_bytes, (cmd->tot_bytes/10)*13 / (cmd->tot_tc/10)); |
||
163 | } |
||
164 | } |
||
165 | for (i=0; i<100; i++) { |
||
166 | cmd = &result->cmd53_tx_blk[i]; |
||
167 | if (cmd->count) { |
||
168 | printk("sdio<%6d><%3d>B_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc, |
||
169 | cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count, |
||
170 | cmd->tot_bytes, (cmd->tot_bytes/10)*13 / (cmd->tot_tc/10)); |
||
171 | } |
||
172 | } |
||
173 | |||
174 | printk("sdio === performance dump done ===\n"); |
||
175 | } |
||
176 | |||
177 | //========= sdio command table =========== |
||
178 | void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks) |
||
179 | { |
||
180 | struct sdio_profile* result = &sdio_perfomance; |
||
181 | struct cmd_profile* cmd; |
||
182 | u32 block; |
||
183 | |||
184 | if (sdio_pro_enable == 0) { |
||
185 | return; |
||
186 | } |
||
187 | |||
188 | if (opcode == 52) { |
||
189 | cmd = bRx ? &result->cmd52_rx : &result->cmd52_tx; |
||
190 | } else if (opcode == 53) { |
||
191 | if (sizes < 512) { |
||
192 | cmd = bRx ? &result->cmd53_rx_byte[sizes] : &result->cmd53_tx_byte[sizes]; |
||
193 | } else { |
||
194 | block = sizes / 512; |
||
195 | if (block >= 99) { |
||
196 | printk("cmd53 error blocks\n"); |
||
197 | while(1); |
||
198 | } |
||
199 | cmd = bRx ? &result->cmd53_rx_blk[block] : &result->cmd53_tx_blk[block]; |
||
200 | } |
||
201 | } else { |
||
202 | return; |
||
203 | } |
||
204 | |||
205 | /* update the members */ |
||
206 | if (ticks > cmd->max_tc){ |
||
207 | cmd->max_tc = ticks; |
||
208 | } |
||
209 | if (cmd->min_tc == 0 || ticks < cmd->min_tc) { |
||
210 | cmd->min_tc = ticks; |
||
211 | } |
||
212 | cmd->tot_tc += ticks; |
||
213 | cmd->tot_bytes += sizes; |
||
214 | cmd->count ++; |
||
215 | |||
216 | if (bRx) { |
||
217 | result->total_rx_bytes += sizes; |
||
218 | } else { |
||
219 | result->total_tx_bytes += sizes; |
||
220 | } |
||
221 | result->total_tc += ticks; |
||
222 | |||
223 | /* dump when total_tc > 30s */ |
||
224 | if (result->total_tc >= sdio_pro_time * TICKS_ONE_MS * 1000) { |
||
225 | msdc_sdio_profile(result); |
||
226 | memset(result, 0 , sizeof(struct sdio_profile)); |
||
227 | } |
||
228 | } |
||
229 | |||
230 | //========== driver proc interface =========== |
||
231 | static int msdc_debug_proc_read(struct seq_file *s, void *p) |
||
232 | { |
||
233 | seq_printf(s, "\n=========================================\n"); |
||
234 | seq_printf(s, "Index<0> + Id + Zone\n"); |
||
235 | seq_printf(s, "-> PWR<9> WRN<8> | FIO<7> OPS<6> FUN<5> CFG<4> | INT<3> RSP<2> CMD<1> DMA<0>\n"); |
||
236 | seq_printf(s, "-> echo 0 3 0x3ff >msdc_bebug -> host[3] debug zone set to 0x3ff\n"); |
||
237 | seq_printf(s, "-> MSDC[0] Zone: 0x%.8x\n", sd_debug_zone[0]); |
||
238 | seq_printf(s, "-> MSDC[1] Zone: 0x%.8x\n", sd_debug_zone[1]); |
||
239 | seq_printf(s, "-> MSDC[2] Zone: 0x%.8x\n", sd_debug_zone[2]); |
||
240 | seq_printf(s, "-> MSDC[3] Zone: 0x%.8x\n", sd_debug_zone[3]); |
||
241 | |||
242 | seq_printf(s, "Index<1> + ID:4|Mode:4 + DMA_SIZE\n"); |
||
243 | seq_printf(s, "-> 0)PIO 1)DMA 2)SIZE\n"); |
||
244 | seq_printf(s, "-> echo 1 22 0x200 >msdc_bebug -> host[2] size mode, dma when >= 512\n"); |
||
245 | seq_printf(s, "-> MSDC[0] mode<%d> size<%d>\n", drv_mode[0], dma_size[0]); |
||
246 | seq_printf(s, "-> MSDC[1] mode<%d> size<%d>\n", drv_mode[1], dma_size[1]); |
||
247 | seq_printf(s, "-> MSDC[2] mode<%d> size<%d>\n", drv_mode[2], dma_size[2]); |
||
248 | seq_printf(s, "-> MSDC[3] mode<%d> size<%d>\n", drv_mode[3], dma_size[3]); |
||
249 | |||
250 | seq_printf(s, "Index<3> + SDIO_PROFILE + TIME\n"); |
||
251 | seq_printf(s, "-> echo 3 1 0x1E >msdc_bebug -> enable sdio_profile, 30s\n"); |
||
252 | seq_printf(s, "-> SDIO_PROFILE<%d> TIME<%ds>\n", sdio_pro_enable, sdio_pro_time); |
||
253 | seq_printf(s, "=========================================\n\n"); |
||
254 | |||
255 | return 0; |
||
256 | } |
||
257 | |||
258 | static ssize_t msdc_debug_proc_write(struct file *file, |
||
259 | const char __user *buf, size_t count, loff_t *data) |
||
260 | { |
||
261 | int ret; |
||
262 | |||
263 | int cmd, p1, p2; |
||
264 | int id, zone; |
||
265 | int mode, size; |
||
266 | |||
267 | if (count == 0)return -1; |
||
268 | if(count > 255)count = 255; |
||
269 | |||
270 | ret = copy_from_user(cmd_buf, buf, count); |
||
271 | if (ret < 0)return -1; |
||
272 | |||
273 | cmd_buf[count] = '\0'; |
||
274 | printk("msdc Write %s\n", cmd_buf); |
||
275 | |||
276 | sscanf(cmd_buf, "%x %x %x", &cmd, &p1, &p2); |
||
277 | |||
278 | if(cmd == SD_TOOL_ZONE) { |
||
279 | id = p1; zone = p2; zone &= 0x3ff; |
||
280 | printk("msdc host_id<%d> zone<0x%.8x>\n", id, zone); |
||
281 | if(id >=0 && id<=3){ |
||
282 | sd_debug_zone[id] = zone; |
||
283 | } |
||
284 | else if(id == 4){ |
||
285 | sd_debug_zone[0] = sd_debug_zone[1] = zone; |
||
286 | sd_debug_zone[2] = sd_debug_zone[3] = zone; |
||
287 | } |
||
288 | else{ |
||
289 | printk("msdc host_id error when set debug zone\n"); |
||
290 | } |
||
291 | } else if (cmd == SD_TOOL_DMA_SIZE) { |
||
292 | id = p1>>4; mode = (p1&0xf); size = p2; |
||
293 | if(id >=0 && id<=3){ |
||
294 | drv_mode[id] = mode; |
||
295 | dma_size[id] = p2; |
||
296 | } |
||
297 | else if(id == 4){ |
||
298 | drv_mode[0] = drv_mode[1] = mode; |
||
299 | drv_mode[2] = drv_mode[3] = mode; |
||
300 | dma_size[0] = dma_size[1] = p2; |
||
301 | dma_size[2] = dma_size[3] = p2; |
||
302 | } |
||
303 | else{ |
||
304 | printk("msdc host_id error when select mode\n"); |
||
305 | } |
||
306 | } else if (cmd == SD_TOOL_SDIO_PROFILE) { |
||
307 | if (p1 == 1) { /* enable profile */ |
||
308 | if (gpt_enable == 0) { |
||
309 | // msdc_init_gpt(); /* --- by chhung */ |
||
310 | gpt_enable = 1; |
||
311 | } |
||
312 | sdio_pro_enable = 1; |
||
313 | if (p2 == 0) p2 = 1; if (p2 >= 30) p2 = 30; |
||
314 | sdio_pro_time = p2 ; |
||
315 | } else if (p1 == 0) { |
||
316 | /* todo */ |
||
317 | sdio_pro_enable = 0; |
||
318 | } |
||
319 | } |
||
320 | |||
321 | return count; |
||
322 | } |
||
323 | |||
324 | static int msdc_debug_show(struct inode *inode, struct file *file) |
||
325 | { |
||
326 | return single_open(file, msdc_debug_proc_read, NULL); |
||
327 | } |
||
328 | |||
329 | static const struct file_operations msdc_debug_fops = { |
||
330 | .owner = THIS_MODULE, |
||
331 | .open = msdc_debug_show, |
||
332 | .read = seq_read, |
||
333 | .write = msdc_debug_proc_write, |
||
334 | .llseek = seq_lseek, |
||
335 | .release = single_release, |
||
336 | }; |
||
337 | |||
338 | int msdc_debug_proc_init(void) |
||
339 | { |
||
340 | struct proc_dir_entry *de = proc_create("msdc_debug", 0667, NULL, &msdc_debug_fops); |
||
341 | |||
342 | if (!de || IS_ERR(de)) |
||
343 | printk("!! Create MSDC debug PROC fail !!\n"); |
||
344 | |||
345 | return 0 ; |
||
346 | } |
||
347 | EXPORT_SYMBOL_GPL(msdc_debug_proc_init); |
||
348 | #endif |