3 * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 #include <linux/mtd/nand_ecc.h>
28 #include <asm/arch/hardware.h>
29 #include <asm/arch/spr_nand.h>
31 static struct fsmc_regs
*const fsmc_regs_p
=
32 (struct fsmc_regs
*)CONFIG_SPEAR_FSMCBASE
;
34 static struct nand_ecclayout spear_nand_ecclayout
= {
36 .eccpos
= {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
37 66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
39 {.offset
= 8, .length
= 8},
40 {.offset
= 24, .length
= 8},
41 {.offset
= 40, .length
= 8},
42 {.offset
= 56, .length
= 8},
43 {.offset
= 72, .length
= 8},
44 {.offset
= 88, .length
= 8},
45 {.offset
= 104, .length
= 8},
46 {.offset
= 120, .length
= 8}
50 static void spear_nand_hwcontrol(struct mtd_info
*mtd
, int cmd
, uint ctrl
)
52 struct nand_chip
*this = mtd
->priv
;
55 if (ctrl
& NAND_CTRL_CHANGE
) {
56 IO_ADDR_W
= (ulong
)this->IO_ADDR_W
;
58 IO_ADDR_W
&= ~(CONFIG_SYS_NAND_CLE
| CONFIG_SYS_NAND_ALE
);
60 IO_ADDR_W
|= CONFIG_SYS_NAND_CLE
;
62 IO_ADDR_W
|= CONFIG_SYS_NAND_ALE
;
64 if (ctrl
& NAND_NCE
) {
65 writel(readl(&fsmc_regs_p
->genmemctrl_pc
) |
66 FSMC_ENABLE
, &fsmc_regs_p
->genmemctrl_pc
);
68 writel(readl(&fsmc_regs_p
->genmemctrl_pc
) &
69 ~FSMC_ENABLE
, &fsmc_regs_p
->genmemctrl_pc
);
71 this->IO_ADDR_W
= (void *)IO_ADDR_W
;
74 if (cmd
!= NAND_CMD_NONE
)
75 writeb(cmd
, this->IO_ADDR_W
);
78 static int spear_read_hwecc(struct mtd_info
*mtd
,
79 const u_char
*data
, u_char ecc
[3])
83 /* read the h/w ECC */
84 ecc_tmp
= readl(&fsmc_regs_p
->genmemctrl_ecc
);
86 ecc
[0] = (u_char
) (ecc_tmp
& 0xFF);
87 ecc
[1] = (u_char
) ((ecc_tmp
& 0xFF00) >> 8);
88 ecc
[2] = (u_char
) ((ecc_tmp
& 0xFF0000) >> 16);
93 void spear_enable_hwecc(struct mtd_info
*mtd
, int mode
)
95 writel(readl(&fsmc_regs_p
->genmemctrl_pc
) & ~0x80,
96 &fsmc_regs_p
->genmemctrl_pc
);
97 writel(readl(&fsmc_regs_p
->genmemctrl_pc
) & ~FSMC_ECCEN
,
98 &fsmc_regs_p
->genmemctrl_pc
);
99 writel(readl(&fsmc_regs_p
->genmemctrl_pc
) | FSMC_ECCEN
,
100 &fsmc_regs_p
->genmemctrl_pc
);
103 int spear_nand_init(struct nand_chip
*nand
)
105 writel(FSMC_DEVWID_8
| FSMC_DEVTYPE_NAND
| FSMC_ENABLE
| FSMC_WAITON
,
106 &fsmc_regs_p
->genmemctrl_pc
);
107 writel(readl(&fsmc_regs_p
->genmemctrl_pc
) | FSMC_TCLR_1
| FSMC_TAR_1
,
108 &fsmc_regs_p
->genmemctrl_pc
);
109 writel(FSMC_THIZ_1
| FSMC_THOLD_4
| FSMC_TWAIT_6
| FSMC_TSET_0
,
110 &fsmc_regs_p
->genmemctrl_comm
);
111 writel(FSMC_THIZ_1
| FSMC_THOLD_4
| FSMC_TWAIT_6
| FSMC_TSET_0
,
112 &fsmc_regs_p
->genmemctrl_attrib
);
115 nand
->ecc
.mode
= NAND_ECC_HW
;
116 nand
->ecc
.layout
= &spear_nand_ecclayout
;
117 nand
->ecc
.size
= 512;
119 nand
->ecc
.calculate
= spear_read_hwecc
;
120 nand
->ecc
.hwctl
= spear_enable_hwecc
;
121 nand
->ecc
.correct
= nand_correct_data
;
122 nand
->cmd_ctrl
= spear_nand_hwcontrol
;