kernel: update kernel 4.1 to version 4.1.11
[openwrt/svn-archive/archive.git] / target / linux / sunxi / patches-4.1 / 129-nand-sunxi-fix-write-to-USER_DATA-a13.patch
1 From b1488f1a55da6a297ac4e8e9140922f35b7583c5 Mon Sep 17 00:00:00 2001
2 From: Boris Brezillon <boris.brezillon@free-electrons.com>
3 Date: Mon, 15 Jun 2015 11:09:58 +0200
4 Subject: [PATCH] nand: sunxi: fix write to USER_DATA reg
5
6 The USER_DATA register cannot be updated with readb on A13 SoCs, thus
7 triggering a bug when using memcpy_toio on this register.
8 Use writel (plus a temporary variable to old the USER_DATA value) to
9 address that problem.
10
11 Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
12 ---
13 drivers/mtd/nand/sunxi_nand.c | 38 +++++++++++++++++++++-----------------
14 1 file changed, 21 insertions(+), 17 deletions(-)
15
16 --- a/drivers/mtd/nand/sunxi_nand.c
17 +++ b/drivers/mtd/nand/sunxi_nand.c
18 @@ -908,7 +908,7 @@ static int sunxi_nfc_hw_ecc_write_page(s
19
20 for (i = 0; i < ecc->steps; i++) {
21 bool rndactiv = false;
22 - u8 oob_buf[4];
23 + u32 user_data;
24
25 if (i)
26 chip->cmdfunc(mtd, NAND_CMD_RNDIN, i * ecc->size, -1);
27 @@ -919,15 +919,13 @@ static int sunxi_nfc_hw_ecc_write_page(s
28 offset = layout->eccpos[i * ecc->bytes] - 4 + mtd->writesize;
29
30 /* Fill OOB data in */
31 - if (!oob_required)
32 - memset(oob_buf, 0xff, 4);
33 - else
34 - memcpy(oob_buf,
35 - chip->oob_poi + layout->oobfree[i].offset,
36 - 4);
37 -
38 -
39 - memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, oob_buf, 4);
40 + if (!oob_required) {
41 + user_data = 0xffffffff;
42 + } else {
43 + memcpy(&user_data,
44 + chip->oob_poi + layout->oobfree[i].offset, 4);
45 + user_data = le32_to_cpu(user_data);
46 + }
47
48 if (i) {
49 cnt = ecc->bytes + 4;
50 @@ -946,12 +944,16 @@ static int sunxi_nfc_hw_ecc_write_page(s
51 if (rndactiv) {
52 /* pre randomize to generate FF patterns on the NAND */
53 if (!i) {
54 + u8 oob_tmp[2];
55 u16 state = rnd->subseeds[rnd->page % rnd->nseeds];
56 + oob_tmp[0] = user_data;
57 + oob_tmp[1] = user_data >> 8;
58 state = sunxi_nfc_hwrnd_single_step(state, 15);
59 - oob_buf[0] ^= state;
60 + oob_tmp[0] ^= state;
61 state = sunxi_nfc_hwrnd_step(rnd, state, 1);
62 - oob_buf[1] ^= state;
63 - memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, oob_buf, 4);
64 + oob_tmp[1] ^= state;
65 + user_data &= ~0xffff;
66 + user_data |= oob_tmp[0] | (oob_tmp[1] << 8);
67 }
68 tmp = readl(nfc->regs + NFC_REG_ECC_CTL);
69 tmp &= ~(NFC_RANDOM_DIRECTION | NFC_ECC_EXCEPTION);
70 @@ -959,6 +961,8 @@ static int sunxi_nfc_hw_ecc_write_page(s
71 writel(tmp, nfc->regs + NFC_REG_ECC_CTL);
72 }
73
74 + writel(user_data, nfc->regs + NFC_REG_USER_DATA_BASE);
75 +
76 chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset, -1);
77
78 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc);