• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Sunxi SD/MMC panic host driver
3 *
4 * Copyright (C) 2019 AllWinnertech Ltd.
5 * Author: lixiang <lixiang@allwinnertech>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 */
16 
17 #include <linux/clk.h>
18 #include <linux/reset/sunxi.h>
19 
20 #include <linux/gpio.h>
21 #include <linux/platform_device.h>
22 #include <linux/spinlock.h>
23 #include <linux/scatterlist.h>
24 #include <linux/dma-mapping.h>
25 #include <linux/slab.h>
26 #include <linux/reset.h>
27 
28 #include <linux/of_address.h>
29 #include <linux/of_gpio.h>
30 #include <linux/of_platform.h>
31 #include <linux/regulator/consumer.h>
32 #include <linux/delay.h>
33 
34 #include <linux/mmc/host.h>
35 #include <linux/mmc/sd.h>
36 #include <linux/mmc/sdio.h>
37 #include <linux/mmc/mmc.h>
38 #include <linux/mmc/core.h>
39 #include <linux/mmc/card.h>
40 #include <linux/mmc/slot-gpio.h>
41 
42 #include "sunxi-mmc.h"
43 #include "sunxi-mmc-export.h"
44 
45 
46 #ifdef CONFIG_SUNXI_PANICPART
47 #include <linux/sunxi-panicpart.h>
48 #endif
49 
50 #define NCAT
51 //#define MMC_DEBUG
52 #define SUNXI_TEST_SIZE	(512*4)
53 
54 #define MWR_TO_NS		(250*1000*1000)
55 #define MWR_RFAIL	-1
56 #define MWR_ROK	0
57 
58 #if 0
59 #define mmc_mreadl(reg_base, reg) \
60 	({\
61 		int val = readl(reg_base + SDXC_##reg);\
62 		printk("%x\n", val);\
63 		val;\
64 	})
65 #define mmc_mwritel(reg_base, reg, value) \
66 ({\
67 	int val = 0;\
68 	writel((value), reg_base + SDXC_##reg);\
69 	val = readl(reg_base + SDXC_##reg);\
70 	printk("%x\n", val);\
71 	val;\
72 })
73 
74 #else
75 
76 #define mmc_mreadl(reg_base, reg) \
77 	({\
78 		int val = readl(reg_base + SDXC_##reg);\
79 		/*printk("%x\n", val);*/\
80 		val;\
81 	})
82 #define mmc_mwritel(reg_base, reg, value) \
83 ({\
84 	int val = 0;\
85 	writel((value), reg_base + SDXC_##reg);\
86 	/*val = readl(reg_base + SDXC_##reg);*/\
87 	/*printk("%x\n", val);*/\
88 	val;\
89 })
90 #endif
91 
92 
93 
94 #ifndef NCAT
95 #define SUNXI_SMHC_BASE  0x1c11000
96 #define SUNXI_CCMU_BASE  0x1c20000
97 #else
98 #define SUNXI_SMHC_BASE  0x4022000
99 #define SUNXI_CCMU_BASE		0x3001000
100 #endif
101 
102 
103 #define SDXC_REG_EDSD		(0x010C)
104 #define SDXC_REG_CSDC		(0x0054)
105 #define SDXC_REG_SD_NTSR	(0x005C)
106 #define SDXC_REG_THLD		(0x0100)
107 #define SDXC_REG_DRV_DL		(0x0140)
108 #define SDXC_REG_SAMP_DL	(0x0144)
109 #define SDXC_REG_DS_DL		(0x0148)
110 
111 
112 #define SDXC_DAT_STARV_ERR	SDXC_VOLTAGE_CHANGE_DONE
113 
114 
115 #ifndef NCAT
116 #define SUNXI_MMC_GATR		(0x60)
117 #define SUNXI_MMC_MODR		(0x90)
118 #define SUNXI_MMC_RST		(0x2C0)
119 #else
120 #define SUNXI_MMC_GATR		(0x84c)
121 #define SUNXI_MMC_MODR		(0x838)
122 #define SUNXI_MMC_RST		(0x84c)
123 #endif
124 
125 
126 #ifdef MMC_DEBUG
127 #define mmcinfo(fmt...) printk(KERN_INFO "[mmc]: "fmt)
128 #define mmcdbg(fmt...)  printk(KERN_DEBUG "[mmc]: "fmt)
129 #define mmcerr(fmt...)  printk(KERN_ERR "[mmc]: "fmt)
130 #else
131 #define mmcinfo(fmt...) printk(KERN_INFO "[mmc]: "fmt)
132 #define mmcdbg(fmt...)
133 #define mmcerr(fmt...)	printk(KERN_ERR "[mmc]: "fmt)
134 #endif
135 
136 
137 
138 struct sunxi_mmc_mbak_regs {
139 	u32 gctrl;
140 	u32 clkc;
141 	u32 timeout;
142 	u32 buswid;
143 	u32 waterlvl;
144 	u32 funcsel;
145 	u32 debugc;
146 	u32 idmacc;
147 	u32 dlba;
148 	u32 imask;
149 	u32 drv_dl;
150 	u32 samp_dl;
151 	u32 ds_dl;
152 	u32 edsd;
153 	u32 csdc;
154 	u32 sd_ntsr;
155 };
156 
157 static struct sunxi_mmc_mbak_regs gmbak_regs;
158 static char *gccmu_base_reg;
159 static char *ghost_base_reg;
160 
161 #ifdef CONFIG_SUNXI_PANICPART
162 static int init_cnt;
163 #endif
164 
165 #ifdef NCAT
sunxi_mmc_mbusrst_host(char * host)166 static void sunxi_mmc_mbusrst_host(char *host)
167 {
168 	char *ccmu_reg = gccmu_base_reg;
169 
170 	u32 rval = 0;
171 	rval = readl(ccmu_reg + SUNXI_MMC_GATR);
172 	rval &= ~((1u<<2)|(1u<<18));
173 	writel(rval, ccmu_reg + SUNXI_MMC_GATR);
174 
175 	rval = readl(ccmu_reg + SUNXI_MMC_MODR);
176 	rval &= ~((1<<31));
177 	writel(rval, ccmu_reg + SUNXI_MMC_MODR);
178 
179 	rval = readl(ccmu_reg + SUNXI_MMC_MODR);
180 	rval |= (1<<31);
181 	writel(rval, ccmu_reg + SUNXI_MMC_MODR);
182 
183 	rval = readl(ccmu_reg + SUNXI_MMC_GATR);
184 	rval |= ((1u<<2)|(1u<<18));
185 	writel(rval, ccmu_reg + SUNXI_MMC_GATR);
186 }
187 #else
188 
sunxi_mmc_mbusrst_host(char * host)189 static void sunxi_mmc_mbusrst_host(char *host)
190 {
191 	char *ccmu_reg = gccmu_base_reg;
192 	u32 rval = 0;
193 
194 	rval = readl(ccmu_reg + SUNXI_MMC_GATR);
195 	rval &= ~(1u<<10);
196 	writel(rval, ccmu_reg + SUNXI_MMC_GATR);
197 
198 	rval = readl(ccmu_reg + SUNXI_MMC_RST);
199 	rval &= ~(1u<<10);
200 	writel(rval, ccmu_reg + SUNXI_MMC_RST);
201 
202 	rval = readl(ccmu_reg + SUNXI_MMC_MODR);
203 	rval &= ~((1<<31));
204 	writel(rval, ccmu_reg + SUNXI_MMC_MODR);
205 
206 	rval = readl(ccmu_reg + SUNXI_MMC_MODR);
207 	rval |= (1<<31);
208 	writel(rval, ccmu_reg + SUNXI_MMC_MODR);
209 
210 	rval = readl(ccmu_reg + SUNXI_MMC_RST);
211 	rval |= (1u<<10);
212 	writel(rval, ccmu_reg + SUNXI_MMC_RST);
213 
214 	rval = readl(ccmu_reg + SUNXI_MMC_GATR);
215 	rval |= (1u<<10);
216 	writel(rval, ccmu_reg + SUNXI_MMC_GATR);
217 }
218 #endif
219 
220 
221 static const char mtsdat[512] = {
222 	0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
223 	0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
224 	0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
225 	0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
226 	0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
227 	0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
228 	0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
229 	0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
230 	0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
231 	0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
232 	0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
233 	0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
234 	0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
235 	0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
236 	0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
237 	0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
238 
239 	0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
240 	0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
241 	0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
242 	0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
243 	0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
244 	0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
245 	0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
246 	0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
247 	0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
248 	0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
249 	0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
250 	0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
251 	0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
252 	0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
253 	0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
254 	0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
255 
256 	0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
257 	0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
258 	0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
259 	0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
260 	0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
261 	0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
262 	0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
263 	0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
264 	0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
265 	0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
266 	0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
267 	0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
268 	0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
269 	0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
270 	0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
271 	0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
272 
273 	0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
274 	0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
275 	0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
276 	0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
277 	0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
278 	0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
279 	0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
280 	0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
281 	0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
282 	0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
283 	0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
284 	0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
285 	0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
286 	0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
287 	0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
288 	0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
289 };
290 
buf_dumphex32(char * name,const char * base,int len)291 static void buf_dumphex32(char *name, const char *base, int len)
292 {
293 #ifdef MMC_DEBUG
294 	u32 i;
295 
296 	pr_cont("dump %s\n", name);
297 
298 	for (i = 0; i < len; i += 4) {
299 		if (!(i&0xf))
300 			pr_cont("\n0x%p : ", base + i);
301 		pr_cont("0x%08x ", *((u32 *)&base[i]));
302 	}
303 	pr_cont("\n");
304 #endif
305 }
306 
sunxi_mmc_regs_save(char * host)307 static void sunxi_mmc_regs_save(char *host)
308 {
309 	struct sunxi_mmc_mbak_regs *bak_regs = &gmbak_regs;
310 
311 	/*save public register */
312 	bak_regs->gctrl = mmc_mreadl(host, REG_GCTRL);
313 	bak_regs->clkc = mmc_mreadl(host, REG_CLKCR);
314 	bak_regs->timeout = mmc_mreadl(host, REG_TMOUT);
315 	bak_regs->buswid = mmc_mreadl(host, REG_WIDTH);
316 	bak_regs->debugc = 0xdeb;
317 
318 	bak_regs->drv_dl = mmc_mreadl(host, REG_DRV_DL);
319 	bak_regs->samp_dl = mmc_mreadl(host, REG_SAMP_DL);
320 	bak_regs->ds_dl = mmc_mreadl(host, REG_DS_DL);
321 	bak_regs->sd_ntsr = mmc_mreadl(host, REG_SD_NTSR);
322 	bak_regs->edsd = mmc_mreadl(host, REG_EDSD);
323 	bak_regs->csdc = mmc_mreadl(host, REG_CSDC);
324 }
325 
sunxi_mmc_regs_restore(char * host)326 static void sunxi_mmc_regs_restore(char *host)
327 {
328 	struct sunxi_mmc_mbak_regs *bak_regs = &gmbak_regs;
329 	char *ccmu_reg = gccmu_base_reg;
330 	u32 rval = 0;
331 
332 	/*restore public register */
333 	mmc_mwritel(host, REG_GCTRL, bak_regs->gctrl);
334 	mmc_mwritel(host, REG_CLKCR, bak_regs->clkc);
335 	mmc_mwritel(host, REG_TMOUT, bak_regs->timeout);
336 	mmc_mwritel(host, REG_WIDTH, bak_regs->buswid);
337 	mmc_mwritel(host, REG_DBGC, bak_regs->debugc);
338 
339 	rval = readl(ccmu_reg + SUNXI_MMC_MODR);
340 	rval &= ~((1<<31));
341 	writel(rval, ccmu_reg + SUNXI_MMC_MODR);
342 	mmc_mwritel(host, REG_DRV_DL, bak_regs->drv_dl);
343 	rval = readl(ccmu_reg + SUNXI_MMC_MODR);
344 	rval |= (1<<31);
345 	writel(rval, ccmu_reg + SUNXI_MMC_MODR);
346 
347 	mmc_mwritel(host, REG_SAMP_DL, bak_regs->samp_dl);
348 	mmc_mwritel(host, REG_DS_DL, bak_regs->ds_dl);
349 	mmc_mwritel(host, REG_SD_NTSR, bak_regs->sd_ntsr);
350 	mmc_mwritel(host, REG_EDSD, bak_regs->edsd);
351 	mmc_mwritel(host, REG_CSDC, bak_regs->csdc);
352 }
353 
sunxi_mmc_mupdate_clk(char * host)354 static int sunxi_mmc_mupdate_clk(char *host)
355 {
356 	u32 rval;
357 	int i = 0;
358 
359 	rval = mmc_mreadl(host, REG_CLKCR);
360 	rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON | SDXC_MASK_DATA0);
361 
362 	rval |= SDXC_CARD_CLOCK_ON;
363 	rval |= SDXC_LOW_POWER_ON;
364 	rval |= SDXC_MASK_DATA0;
365 
366 	mmc_mwritel(host, REG_CLKCR, rval);
367 
368 	mmcdbg("%s REG_CLKCR:%x\n", __func__,
369 		mmc_mreadl(host, REG_CLKCR));
370 
371 	rval = SDXC_START | SDXC_UPCLK_ONLY | SDXC_WAIT_PRE_OVER;
372 	mmc_mwritel(host, REG_CMDR, rval);
373 
374 	do {
375 		rval = mmc_mreadl(host, REG_CMDR);
376 		ndelay(1);
377 	} while (((i++) < MWR_TO_NS) && (rval & SDXC_START));
378 
379 	/* clear irq status bits set by the command */
380 	mmc_mwritel(host, REG_RINTR,
381 		   mmc_mreadl(host, REG_RINTR) & ~SDXC_SDIO_INTERRUPT);
382 
383 	if (rval & SDXC_START) {
384 		mmcerr("fatal err update clk timeout\n");
385 		return -EIO;
386 	}
387 
388 	mmc_mwritel(host, REG_CLKCR,
389 			   mmc_mreadl(host, REG_CLKCR) & ~SDXC_MASK_DATA0);
390 
391 	return 0;
392 }
393 
394 
395 
sunxi_mmc_rcover_host(char * host)396 static void sunxi_mmc_rcover_host(char *host)
397 {
398 	sunxi_mmc_regs_save(host);
399 	sunxi_mmc_mbusrst_host(host);
400 	sunxi_mmc_regs_restore(host);
401 	sunxi_mmc_mupdate_clk(host);
402 }
403 
sunxi_mmc_mchk_r1_rdy(char * reg,int to_ns)404 static int sunxi_mmc_mchk_r1_rdy(char *reg, int to_ns)
405 {
406 	int i = 0;
407 	/*wait busy over*/
408 	for (i = 0; i < to_ns; i++) {
409 		if (!(mmc_mreadl(reg, REG_STAS) & SDXC_CARD_DATA_BUSY))
410 			break;
411 		ndelay(1);
412 	}
413 
414 	if ((mmc_mreadl(reg, REG_STAS) & SDXC_CARD_DATA_BUSY)) {
415 		printk("dead Wait r1 rdy failed\n");
416 		return MWR_RFAIL;
417 	}
418 	return MWR_ROK;
419 }
420 
421 
sunxi_mmc_raw_write(char * reg,u32 sec_addr,u32 sec_cnt,const char * inbuf)422 static int sunxi_mmc_raw_write(char *reg, u32 sec_addr,
423 			u32 sec_cnt, const char *inbuf)
424 {
425 	u32 cmd_val, ri;
426 	u32 rval;
427 	int to = 0;
428 	int wcnt = (sec_cnt<<9)>>2;
429 	int i = 0;
430 	u32 *buf = (u32 *)inbuf;
431 
432 
433 	rval = mmc_mreadl(reg, REG_GCTRL);
434 	rval |= SDXC_ACCESS_BY_AHB | SDXC_FIFO_RESET;
435 	rval &= ~SDXC_DMA_ENABLE_BIT;
436 	mmc_mwritel(reg, REG_GCTRL, rval);
437 	for (to = 0; to < MWR_TO_NS; to++) {
438 		rval = mmc_mreadl(reg, REG_GCTRL);
439 		if (!(rval & SDXC_FIFO_RESET))
440 			break;
441 		ndelay(1);
442 	}
443 	if (to == MWR_TO_NS) {
444 		mmcerr("wait fifo rest timout\n");
445 		goto eout;
446 	}
447 
448 	/**cmd seting**/
449 	cmd_val = SDXC_START | SDXC_RESP_EXPECT \
450 				| SDXC_CHECK_RESPONSE_CRC | SDXC_DATA_EXPECT\
451 				| SDXC_WRITE | SDXC_SEND_AUTO_STOP
452 				| SDXC_WAIT_PRE_OVER | MMC_WRITE_MULTIPLE_BLOCK;
453 	mmc_mwritel(reg, REG_CARG, sec_addr);
454 	mmc_mwritel(reg, REG_A12A, 0);
455 
456 	/**data setting*/
457 	mmc_mwritel(reg, REG_BLKSZ, 512);
458 	mmc_mwritel(reg, REG_BCNTR, sec_cnt<<9);
459 
460 	mmc_mwritel(reg, REG_THLD, (512<<16)|(1<<2)|(1<<0));
461 	mmcdbg("thld %x\n", readl(reg + 0x100));
462 
463 	/**int seting*/
464 	rval = mmc_mreadl(reg, REG_GCTRL);
465 	rval &= ~SDXC_INTERRUPT_ENABLE_BIT;
466 	mmc_mwritel(reg, REG_GCTRL, rval);
467 	mmc_mwritel(reg, REG_MISTA, 0);
468 	mmc_mwritel(reg, REG_RINTR, 0xffffffff);
469 
470 	/**exe cmd**/
471 	mmc_mwritel(reg, REG_CMDR, cmd_val);
472 
473 	/*write data*/
474 	for (i = 0; i < wcnt; i++) {
475 		/*wait data not full*/
476 		for (to = 0; to < MWR_TO_NS; to++) {
477 			if (!(mmc_mreadl(reg, REG_STAS) & SDXC_FIFO_FULL))
478 				break;
479 			ri = mmc_mreadl(reg, REG_RINTR);
480 			if (ri & (SDXC_INTERRUPT_ERROR_BIT)) {
481 				mmcerr("trans err %x\n", ri);
482 				goto eout;
483 			}
484 			ndelay(1);
485 		}
486 		if (to == MWR_TO_NS) {
487 			mmcerr("wait fifo not full timeout\n");
488 			goto eout;
489 		}
490 
491 		mmc_mwritel(reg, REG_FIFO, buf[i]);
492 	}
493 
494 	/*wait busy over*/
495 	for (i = 0; i < MWR_TO_NS; i++) {
496 		if (!(mmc_mreadl(reg, REG_STAS) & SDXC_CARD_DATA_BUSY))
497 			break;
498 		ndelay(1);
499 	}
500 
501 	if ((mmc_mreadl(reg, REG_STAS) & SDXC_CARD_DATA_BUSY)) {
502 		mmcerr("dead Wait r1 rdy failed\n");
503 		goto eout;
504 	}
505 
506 	for (to = 0; to < MWR_TO_NS; to++) {
507 		ri = mmc_mreadl(reg, REG_RINTR);
508 		if (ri & (SDXC_AUTO_COMMAND_DONE))
509 			break;
510 		ndelay(1);
511 	}
512 	if (to == MWR_TO_NS) {
513 		mmcerr("wait auto cmd done timout\n");
514 		goto eout;
515 	}
516 
517 	mmc_mwritel(reg, REG_RINTR, 0xffff);
518 	mmcdbg("manul write ok\n");
519 	return MWR_ROK;
520 
521 eout:
522 	mmcerr("mau write failed\n");
523 	return MWR_RFAIL;
524 }
525 
526 
sunxi_mmc_raw_half_write(char * reg,u32 sec_addr,u32 sec_cnt,u32 stp_wd,const char * inbuf)527 static int sunxi_mmc_raw_half_write(char *reg, u32 sec_addr,
528 				u32 sec_cnt, u32 stp_wd, const char *inbuf)
529 {
530 	u32 cmd_val, ri;
531 	u32 rval;
532 	int to = 0;
533 	int wcnt = (sec_cnt<<9)>>2;
534 	int i = 0;
535 	u32 *buf = (u32 *)inbuf;
536 
537 	/**cmd seting**/
538 	cmd_val = SDXC_START | SDXC_RESP_EXPECT \
539 				| SDXC_CHECK_RESPONSE_CRC | SDXC_DATA_EXPECT\
540 				| SDXC_WRITE | SDXC_SEND_AUTO_STOP
541 				| SDXC_WAIT_PRE_OVER | MMC_WRITE_MULTIPLE_BLOCK;
542 	mmc_mwritel(reg, REG_CARG, sec_addr);
543 	mmc_mwritel(reg, REG_A12A, 0);
544 
545 	/**data setting*/
546 	mmc_mwritel(reg, REG_BLKSZ, 512);
547 	mmc_mwritel(reg, REG_BCNTR, sec_cnt<<9);
548 	rval = mmc_mreadl(reg, REG_GCTRL);
549 	rval |= SDXC_ACCESS_BY_AHB | SDXC_FIFO_RESET;
550 	rval &= ~SDXC_DMA_ENABLE_BIT;
551 	mmc_mwritel(reg, REG_GCTRL, rval);
552 	for (to = 0; to < MWR_TO_NS; to++) {
553 		rval = mmc_mreadl(reg, REG_GCTRL);
554 		if (!(rval & SDXC_FIFO_RESET))
555 			break;
556 		ndelay(1);
557 	}
558 	if (to == MWR_TO_NS) {
559 		mmcerr("wait fifo rest timout\n");
560 		goto eout;
561 	}
562 
563 	/**int seting*/
564 	rval &= ~SDXC_INTERRUPT_ENABLE_BIT;
565 	mmc_mwritel(reg, REG_GCTRL, rval);
566 	mmc_mwritel(reg, REG_MISTA, 0);
567 	mmc_mwritel(reg, REG_RINTR, 0xffff);
568 
569 	/**exe cmd**/
570 	mmc_mwritel(reg, REG_CMDR, cmd_val);
571 
572 	/*write data*/
573 	for (i = 0; (i < wcnt) && (i < stp_wd); i++) {
574 		/*wait data not full*/
575 		for (to = 0; to < MWR_TO_NS; to++) {
576 			if (!(mmc_mreadl(reg, REG_STAS) & SDXC_FIFO_FULL))
577 				break;
578 			ri = mmc_mreadl(reg, REG_RINTR);
579 			if (ri & (SDXC_INTERRUPT_ERROR_BIT)) {
580 				mmcerr("trans err %x\n", ri);
581 				goto eout;
582 			}
583 			ndelay(1);
584 		}
585 		if (to == MWR_TO_NS) {
586 			mmcerr("wait fifo not full timeout\n");
587 			goto eout;
588 		}
589 
590 		mmc_mwritel(reg, REG_FIFO, buf[i]);
591 	}
592 
593 	mmc_mwritel(reg, REG_RINTR, 0xffff);
594 	mmcdbg("manul half write ok\n");
595 	return MWR_ROK;
596 
597 eout:
598 	mmcerr("mau write failed\n");
599 	return MWR_RFAIL;
600 }
601 
sunxi_mmc_raw_wcmd_clr(char * reg,int * out_cmd_val)602 static int sunxi_mmc_raw_wcmd_clr(char *reg, int *out_cmd_val)
603 {
604 	int i = 0;
605 	u32 cmd_val = 0;
606 
607 	do {
608 		cmd_val = mmc_mreadl(reg, REG_CMDR);
609 		if (!(cmd_val & SDXC_START)) {
610 			*out_cmd_val = cmd_val;
611 			return MWR_ROK;
612 		}
613 		ndelay(1);
614 	} while ((i++) < MWR_TO_NS);
615 
616 	mmcerr("Wait cmd over timout\n");
617 	return MWR_RFAIL;
618 }
619 
sunxi_mmc_raw_stop(char * reg)620 static void sunxi_mmc_raw_stop(char *reg)
621 {
622 	u32 arg, cmd_val, ri;
623 	int i = 0;
624 	int rval = 0;
625 
626 	cmd_val = SDXC_START | SDXC_RESP_EXPECT
627 			|SDXC_STOP_ABORT_CMD | SDXC_CHECK_RESPONSE_CRC
628 			|MMC_STOP_TRANSMISSION;
629 	arg = 0;
630 
631 	/**int seting*/
632 	rval = mmc_mreadl(reg, REG_GCTRL);
633 	rval &= ~SDXC_INTERRUPT_ENABLE_BIT;
634 	mmc_mwritel(reg, REG_GCTRL, rval);
635 	mmc_mwritel(reg, REG_MISTA, 0);
636 	mmc_mwritel(reg, REG_RINTR, 0xffff);
637 
638 	mmc_mwritel(reg, REG_CARG, arg);
639 	mmc_mwritel(reg, REG_CMDR, cmd_val);
640 
641 	do {
642 		ri = mmc_mreadl(reg, REG_RINTR);
643 		if (ri & (SDXC_COMMAND_DONE |
644 					(SDXC_INTERRUPT_ERROR_BIT|SDXC_DAT_STARV_ERR)))
645 			break;
646 		ndelay(1);
647 	} while ((i++) < MWR_TO_NS);
648 
649 	if (!(ri & SDXC_COMMAND_DONE) ||
650 				(ri & (SDXC_INTERRUPT_ERROR_BIT|SDXC_DAT_STARV_ERR))) {
651 		ri = mmc_mreadl(reg, REG_RINTR);
652 		if (!(ri & SDXC_COMMAND_DONE) ||
653 					(ri & (SDXC_INTERRUPT_ERROR_BIT|SDXC_DAT_STARV_ERR))) {
654 			mmcdbg("send  manual stop command failed, %x\n", ri);
655 		} else {
656 			mmcdbg("send manual stop command ok\n");
657 			}
658 	} else
659 		mmcdbg("send manual stop command ok\n");
660 
661 
662 	mmc_mwritel(reg, REG_RINTR, 0xffff);
663 }
664 
sunxi_mmc_raw_read(char * reg,u32 sec_addr,u32 sec_cnt,char * outbuf)665 static int sunxi_mmc_raw_read(char *reg, u32 sec_addr,
666 			u32 sec_cnt, char *outbuf)
667 {
668 	u32 cmd_val, ri;
669 	u32 rval;
670 	int to = 0;
671 	int wcnt = (sec_cnt<<9)>>2;
672 	int i = 0;
673 	u32 *buf = (u32 *)outbuf;
674 	int fifo_level = 0;
675 
676 	/**int seting*/
677 	rval = mmc_mreadl(reg, REG_GCTRL);
678 	rval &= ~SDXC_INTERRUPT_ENABLE_BIT;
679 	mmc_mwritel(reg, REG_GCTRL, rval);
680 	mmc_mwritel(reg, REG_MISTA, 0);
681 	mmc_mwritel(reg, REG_RINTR, 0xffff);
682 
683 	/**cmd seting**/
684 	cmd_val = SDXC_START | SDXC_RESP_EXPECT \
685 				| SDXC_CHECK_RESPONSE_CRC | SDXC_DATA_EXPECT\
686 				| SDXC_SEND_AUTO_STOP
687 				| SDXC_WAIT_PRE_OVER | MMC_READ_MULTIPLE_BLOCK;
688 	mmc_mwritel(reg, REG_CARG, sec_addr);
689 	mmc_mwritel(reg, REG_A12A, 0);
690 
691 	/**data setting*/
692 	mmc_mwritel(reg, REG_BLKSZ, 512);
693 	mmc_mwritel(reg, REG_BCNTR, sec_cnt<<9);
694 	mmc_mwritel(reg, REG_THLD, (512<<16)|(1<<2)|(1<<0));
695 	mmcdbg("thld %x\n", readl(reg + 0x100));
696 
697 	rval = mmc_mreadl(reg, REG_GCTRL);
698 	rval |= SDXC_ACCESS_BY_AHB | SDXC_FIFO_RESET;
699 	rval &= ~SDXC_DMA_ENABLE_BIT;
700 	mmc_mwritel(reg, REG_GCTRL, rval);
701 	for (to = 0; to < MWR_TO_NS; to++) {
702 		rval = mmc_mreadl(reg, REG_GCTRL);
703 		if (!(rval & SDXC_FIFO_RESET))
704 			break;
705 		ndelay(1);
706 	}
707 	if (to == MWR_TO_NS) {
708 		mmcerr("wait fifo rest timout\n");
709 		goto eout;
710 	}
711 
712 
713 	/**exe cmd**/
714 	mmc_mwritel(reg, REG_CMDR, cmd_val);
715 
716 	/*read data*/
717 	do {
718 		/*wait data not full*/
719 		for (to = 0; to < MWR_TO_NS; to++) {
720 			if (!(mmc_mreadl(reg, REG_STAS)
721 				& SDXC_FIFO_EMPTY))
722 				break;
723 			ri = mmc_mreadl(reg, REG_RINTR);
724 			if (ri & (SDXC_INTERRUPT_ERROR_BIT)) {
725 				mmcerr("trans err %x\n", ri);
726 				goto eout;
727 			}
728 			ndelay(1);
729 		}
730 		if (to == MWR_TO_NS) {
731 			mmcerr("wait fifo no empty timeout %x\n", ri);
732 			goto eout;
733 		}
734 
735 		fifo_level = (mmc_mreadl(reg, REG_STAS) >> 17) & 0x1f;
736 		if (fifo_level && (fifo_level <= 16))
737 			while (fifo_level--)
738 				buf[i++] = mmc_mreadl(reg, REG_FIFO);
739 		else
740 			buf[i++] = mmc_mreadl(reg, REG_FIFO);
741 	} while (i < wcnt);
742 
743 
744 
745 	for (to = 0; to < MWR_TO_NS; to++) {
746 		ri = mmc_mreadl(reg, REG_RINTR);
747 		if (ri & (SDXC_AUTO_COMMAND_DONE))
748 			break;
749 		ndelay(1);
750 	}
751 	if (to == MWR_TO_NS) {
752 		mmcerr("wait auto cmd done timout\n");
753 		goto eout;
754 	}
755 
756 
757 	mmc_mwritel(reg, REG_RINTR, 0xffff);
758 	return MWR_ROK;
759 
760 eout:
761 	mmcerr("mau read failed\n");
762 	return MWR_RFAIL;
763 }
764 
765 
sunxi_mmc_raw_half_read(char * reg,u32 sec_addr,u32 sec_cnt,u32 stp_wd,char * outbuf)766 static int sunxi_mmc_raw_half_read(char *reg, u32 sec_addr, u32 sec_cnt, u32 stp_wd, char *outbuf)
767 {
768 	u32 cmd_val, ri;
769 	u32 rval;
770 	int to = 0;
771 	int wcnt = (sec_cnt<<9)>>2;
772 	int i = 0;
773 	u32 *buf = (u32 *)outbuf;
774 	int fifo_level = 0;
775 
776 
777 	/**int seting*/
778 	rval = mmc_mreadl(reg, REG_GCTRL);
779 	rval &= ~SDXC_INTERRUPT_ENABLE_BIT;
780 	mmc_mwritel(reg, REG_GCTRL, rval);
781 	mmc_mwritel(reg, REG_MISTA, 0);
782 	mmc_mwritel(reg, REG_RINTR, 0xffff);
783 
784 	/**cmd seting**/
785 	cmd_val = SDXC_START | SDXC_RESP_EXPECT \
786 				| SDXC_CHECK_RESPONSE_CRC | SDXC_DATA_EXPECT\
787 				| SDXC_SEND_AUTO_STOP
788 				| SDXC_WAIT_PRE_OVER | MMC_READ_MULTIPLE_BLOCK;
789 	mmc_mwritel(reg, REG_CARG, sec_addr);
790 	mmc_mwritel(reg, REG_A12A, 0);
791 
792 	/**data setting*/
793 	mmc_mwritel(reg, REG_BLKSZ, 512);
794 	mmc_mwritel(reg, REG_BCNTR, sec_cnt<<9);
795 	rval = mmc_mreadl(reg, REG_GCTRL);
796 	rval |= SDXC_ACCESS_BY_AHB | SDXC_FIFO_RESET;
797 	rval &= ~SDXC_DMA_ENABLE_BIT;
798 	mmc_mwritel(reg, REG_GCTRL, rval);
799 	for (to = 0; to < MWR_TO_NS; to++) {
800 		rval = mmc_mreadl(reg, REG_GCTRL);
801 		if (!(rval & SDXC_FIFO_RESET))
802 			break;
803 		ndelay(1);
804 	}
805 	if (to == MWR_TO_NS) {
806 		mmcerr("wait fifo rest timout\n");
807 		goto eout;
808 	}
809 
810 	/**exe cmd**/
811 	mmc_mwritel(reg, REG_CMDR, cmd_val);
812 
813 	/*read data*/
814 	do {
815 		/*wait data not full*/
816 		for (to = 0; to < MWR_TO_NS; to++) {
817 			if (!(mmc_mreadl(reg, REG_STAS) & SDXC_FIFO_EMPTY))
818 				break;
819 			ri = mmc_mreadl(reg, REG_RINTR);
820 			if (ri & (SDXC_INTERRUPT_ERROR_BIT)) {
821 				mmcerr("trans err %x\n", ri);
822 				goto eout;
823 			}
824 			ndelay(1);
825 		}
826 		if (to == MWR_TO_NS)
827 			goto eout;
828 
829 		fifo_level = (mmc_mreadl(reg, REG_STAS) >> 17) & 0x1f;
830 		if (fifo_level && (fifo_level <= 16))
831 			while (fifo_level--)
832 				buf[i++] = mmc_mreadl(reg, REG_FIFO);
833 		else
834 			buf[i++] = mmc_mreadl(reg, REG_FIFO);
835 	} while ((i < wcnt) && (i < stp_wd));
836 
837 	mmc_mwritel(reg, REG_RINTR, 0xffff);
838 	return MWR_ROK;
839 
840 eout:
841 	mmcerr("mau read failed\n");
842 	return MWR_RFAIL;
843 }
844 
845 
846 
847 /**use for panic situation,no irq,no lock,no dma**/
sunxi_mmc_panic_read(u32 sec_addr,u32 sec_cnt,char * outbuf)848 int sunxi_mmc_panic_read(u32 sec_addr, u32 sec_cnt, char *outbuf)
849 {
850 	char *reg = ghost_base_reg;
851 	int ret = 0;
852 	u32 cmd_val = 0;
853 
854 	BUG_ON(outbuf == NULL);
855 	if (!ghost_base_reg || !gccmu_base_reg) {
856 		mmcerr("host,ccmu reg has not init\n");
857 		return MWR_RFAIL;
858 	}
859 
860 	cmd_val = mmc_mreadl(reg, REG_CMDR);
861 
862 	ret = sunxi_mmc_raw_wcmd_clr(reg, &cmd_val);
863 	if (ret)
864 		return ret;
865 
866 	if (cmd_val & SDXC_DATA_EXPECT)
867 		sunxi_mmc_raw_stop(reg);
868 
869 	sunxi_mmc_rcover_host(reg);
870 
871 	if (cmd_val & SDXC_DATA_EXPECT)
872 		sunxi_mmc_raw_stop(reg);
873 
874 	if (cmd_val & SDXC_WRITE)
875 			ret = sunxi_mmc_mchk_r1_rdy(reg, MWR_TO_NS);
876 	if (ret)
877 		return ret;
878 
879 	return sunxi_mmc_raw_read(reg, sec_addr, sec_cnt, outbuf);
880 }
881 
882 /**use for panic situation,no irq,no lock,no dma**/
sunxi_mmc_panic_write(u32 sec_addr,u32 sec_cnt,const char * inbuf)883 int sunxi_mmc_panic_write(u32 sec_addr, u32 sec_cnt, const char *inbuf)
884 {
885 	int ret = 0;
886 	u32 cmd_val = 0;
887 	char *reg = ghost_base_reg;
888 
889 	cmd_val = mmc_mreadl(reg, REG_CMDR);
890 	BUG_ON(inbuf == NULL);
891 	if (!ghost_base_reg || !gccmu_base_reg) {
892 		mmcerr("host,ccmu reg has not init\n");
893 		return MWR_RFAIL;
894 	}
895 
896 	ret = sunxi_mmc_raw_wcmd_clr(reg, &cmd_val);
897 	if (ret)
898 		return ret;
899 
900 	if (cmd_val & SDXC_DATA_EXPECT)
901 		sunxi_mmc_raw_stop(reg);
902 
903 	sunxi_mmc_rcover_host(reg);
904 
905 	if (cmd_val & SDXC_DATA_EXPECT)
906 		sunxi_mmc_raw_stop(reg);
907 
908 	if (cmd_val & SDXC_WRITE)
909 			ret = sunxi_mmc_mchk_r1_rdy(reg, MWR_TO_NS);
910 	if (ret)
911 		return ret;
912 
913 	return sunxi_mmc_raw_write(reg, sec_addr, sec_cnt, inbuf);
914 }
915 
sunxi_mmc_panic_init(void)916 int sunxi_mmc_panic_init(void)
917 {
918 	gccmu_base_reg = ioremap(SUNXI_CCMU_BASE, 0x900);
919 	if (!gccmu_base_reg) {
920 		mmcerr("*iormap ccmu failed*\n");
921 		return MWR_RFAIL;
922 	}
923 
924 	ghost_base_reg = ioremap(SUNXI_SMHC_BASE, 0x300);
925 	if (!ghost_base_reg) {
926 		mmcerr("*iormap host failed*\n");
927 		return MWR_RFAIL;
928 	}
929 	return MWR_ROK;
930 }
931 
932 
933 
sunxi_mmc_panic_exit(void)934 void sunxi_mmc_panic_exit(void)
935 {
936 	iounmap(gccmu_base_reg);
937 	iounmap(ghost_base_reg);
938 }
939 
940 ssize_t
sunxi_mmc_panic_rtest(struct device * dev,struct device_attribute * attr,char * buf)941 sunxi_mmc_panic_rtest(struct device *dev,
942 			struct device_attribute *attr, char *buf)
943 {
944 	struct platform_device *pdev = to_platform_device(dev);
945 	struct mmc_host	*mmc = platform_get_drvdata(pdev);
946 	char *rxbuf = kzalloc(SUNXI_TEST_SIZE, GFP_KERNEL);
947 	int ret = 0;
948 
949 	printk("Start panic read test\n");
950 
951 	mmc_claim_host(mmc);
952 	sunxi_mmc_panic_init();
953 	ret = sunxi_mmc_panic_read(16, SUNXI_TEST_SIZE/512, rxbuf);
954 	if (ret)
955 		goto out;
956 	buf_dumphex32("rxbuf", rxbuf, SUNXI_TEST_SIZE);
957 	printk(KERN_INFO "panic read ok\n");
958 	mmc_release_host(mmc);
959 
960 out:
961 	kfree(rxbuf);
962 	return SUNXI_TEST_SIZE;
963 }
964 
965 ssize_t
sunxi_mmc_pancic_wrtest(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)966 sunxi_mmc_pancic_wrtest(struct device *dev, struct device_attribute *attr,
967 		const char *buf, size_t count)
968 {
969 	struct platform_device *pdev = to_platform_device(dev);
970 	struct mmc_host	*mmc = platform_get_drvdata(pdev);
971 	char *rxbuf = kzalloc(SUNXI_TEST_SIZE, GFP_KERNEL);
972 	char *mwr_tsdat = kzalloc(SUNXI_TEST_SIZE, GFP_KERNEL);
973 	int sc = 0;
974 	int i = 0;
975 	char *reg = NULL;
976 	if (kstrtoint(buf, 0, &sc))
977 		goto out;
978 
979 	mmcinfo(KERN_INFO "Start test sec %d\n", sc);
980 	for (i = 0; i < (SUNXI_TEST_SIZE/512); i++)
981 		memcpy(mwr_tsdat+i*512, mtsdat, 512);
982 
983 
984 	mmc_claim_host(mmc);
985 	sunxi_mmc_panic_init();
986 	reg = ghost_base_reg;
987 	mmcinfo("***Test normal w/r***\n");
988 	buf_dumphex32("test data", mwr_tsdat, SUNXI_TEST_SIZE);
989 	mmcdbg("Write test data\n");
990 	sunxi_mmc_panic_write(sc, SUNXI_TEST_SIZE/512, mwr_tsdat);
991 	mmcdbg("Read test data\n");
992 	sunxi_mmc_panic_read(sc, SUNXI_TEST_SIZE/512, rxbuf);
993 	buf_dumphex32("read data from mmc after write", rxbuf, SUNXI_TEST_SIZE);
994 	if (memcmp(mwr_tsdat, rxbuf, SUNXI_TEST_SIZE) != 0) {
995 		mmcinfo("write read failed\n");
996 		goto out;
997 	}
998 	mmcinfo(KERN_INFO "***write read compare ok,test ok***\n");
999 
1000 #if 1
1001 	mmcinfo("\n***test half read***\n");
1002 	memset(rxbuf, 0, SUNXI_TEST_SIZE);
1003 	buf_dumphex32("0 test data", rxbuf, SUNXI_TEST_SIZE);;
1004 	sunxi_mmc_raw_half_read(reg, sc, SUNXI_TEST_SIZE/512, 160, rxbuf);
1005 	buf_dumphex32("half read data", rxbuf, SUNXI_TEST_SIZE);
1006 	sunxi_mmc_panic_read(sc, SUNXI_TEST_SIZE/512, rxbuf);
1007 	buf_dumphex32("read test data", rxbuf, SUNXI_TEST_SIZE);
1008 	if (memcmp(mwr_tsdat, rxbuf, SUNXI_TEST_SIZE) != 0) {
1009 		mmcinfo("half read compare failed\n");
1010 		goto out;
1011 	}
1012 	mmcinfo("***test half read test ok***\n");
1013 
1014 
1015 	mmcinfo("\n***test half write***\n");
1016 	memset(rxbuf, 0, SUNXI_TEST_SIZE);
1017 	sunxi_mmc_raw_half_write(reg, sc, SUNXI_TEST_SIZE/512, 160, mwr_tsdat);
1018 	sunxi_mmc_panic_read(sc, SUNXI_TEST_SIZE/512, rxbuf);
1019 	buf_dumphex32("read half test data", rxbuf, SUNXI_TEST_SIZE);
1020 	if (memcmp(mwr_tsdat, rxbuf, SUNXI_TEST_SIZE) != 0) {
1021 		mmcinfo("half write compare failed\n");
1022 		return count;
1023 	}
1024 	mmcinfo("***test half write test ok***\n\n");
1025 #endif
1026 out:
1027 	sunxi_mmc_panic_exit();
1028 	mmc_release_host(mmc);
1029 
1030 
1031 	kfree(rxbuf);
1032 	kfree(mwr_tsdat);
1033 	return count;
1034 }
1035 
1036 #ifdef CONFIG_SUNXI_PANICPART
sunxi_mmc_panic_read_ps(struct panic_part * part,loff_t sec_off,size_t sec_cnt,char * buf)1037 static ssize_t sunxi_mmc_panic_read_ps(struct panic_part *part, loff_t sec_off,
1038 		size_t sec_cnt, char *buf)
1039 {
1040 	int ret;
1041 
1042 	ret = sunxi_mmc_panic_read(part->start_sect + sec_off, sec_cnt, buf);
1043 	if (ret)
1044 		return ret;
1045 	return sec_cnt;
1046 }
1047 
sunxi_mmc_panic_write_ps(struct panic_part * part,loff_t sec_off,size_t sec_cnt,const char * buf)1048 static ssize_t sunxi_mmc_panic_write_ps(struct panic_part *part, loff_t sec_off,
1049 		size_t sec_cnt, const char *buf)
1050 {
1051 	int ret;
1052 
1053 	ret =  sunxi_mmc_panic_write(part->start_sect + sec_off, sec_cnt, buf);
1054 	if (ret)
1055 		return ret;
1056 	return sec_cnt;
1057 }
1058 
1059 
1060 static struct panic_part sunxi_mmc_panic_ps = {
1061 	.type = SUNXI_FLASH_MMC,
1062 	.panic_read = sunxi_mmc_panic_read_ps,
1063 	.panic_write = sunxi_mmc_panic_write_ps,
1064 };
1065 #endif
1066 
sunxi_mmc_panic_init_ps(void * data)1067 int sunxi_mmc_panic_init_ps(void *data)
1068 {
1069 	int ret = 0;
1070 
1071 #ifdef CONFIG_SUNXI_PANICPART
1072 	if (init_cnt) {
1073 		mmcdbg("error Has init sunxi mmc panic\n");
1074 		return MWR_RFAIL;
1075 	}
1076 
1077 	ret = sunxi_mmc_panic_init();
1078 	if (ret <= MWR_RFAIL)
1079 		return ret;
1080 	if (!ret)
1081 		init_cnt = 1;
1082 
1083 	ret = sunxi_panicpart_init(&sunxi_mmc_panic_ps);
1084 #endif
1085 	return ret;
1086 }
1087 
1088