17 #include <linux/module.h>
19 #include <linux/sched.h>
20 #include <linux/slab.h>
39 #define ONENAND_ERASE_STATUS 0x00
40 #define ONENAND_MULTI_ERASE_SET 0x01
41 #define ONENAND_ERASE_START 0x03
42 #define ONENAND_UNLOCK_START 0x08
43 #define ONENAND_UNLOCK_END 0x09
44 #define ONENAND_LOCK_START 0x0A
45 #define ONENAND_LOCK_END 0x0B
46 #define ONENAND_LOCK_TIGHT_START 0x0C
47 #define ONENAND_LOCK_TIGHT_END 0x0D
48 #define ONENAND_UNLOCK_ALL 0x0E
49 #define ONENAND_OTP_ACCESS 0x12
50 #define ONENAND_SPARE_ACCESS_ONLY 0x13
51 #define ONENAND_MAIN_ACCESS_ONLY 0x14
52 #define ONENAND_ERASE_VERIFY 0x15
53 #define ONENAND_MAIN_SPARE_ACCESS 0x16
54 #define ONENAND_PIPELINE_READ 0x4000
61 #define S3C64XX_CMD_MAP_SHIFT 24
62 #define S5PC100_CMD_MAP_SHIFT 26
64 #define S3C6400_FBA_SHIFT 10
65 #define S3C6400_FPA_SHIFT 4
66 #define S3C6400_FSA_SHIFT 2
68 #define S3C6410_FBA_SHIFT 12
69 #define S3C6410_FPA_SHIFT 6
70 #define S3C6410_FSA_SHIFT 4
72 #define S5PC100_FBA_SHIFT 13
73 #define S5PC100_FPA_SHIFT 7
74 #define S5PC100_FSA_SHIFT 5
77 #define S5PC110_DMA_SRC_ADDR 0x400
78 #define S5PC110_DMA_SRC_CFG 0x404
79 #define S5PC110_DMA_DST_ADDR 0x408
80 #define S5PC110_DMA_DST_CFG 0x40C
81 #define S5PC110_DMA_TRANS_SIZE 0x414
82 #define S5PC110_DMA_TRANS_CMD 0x418
83 #define S5PC110_DMA_TRANS_STATUS 0x41C
84 #define S5PC110_DMA_TRANS_DIR 0x420
85 #define S5PC110_INTC_DMA_CLR 0x1004
86 #define S5PC110_INTC_ONENAND_CLR 0x1008
87 #define S5PC110_INTC_DMA_MASK 0x1024
88 #define S5PC110_INTC_ONENAND_MASK 0x1028
89 #define S5PC110_INTC_DMA_PEND 0x1044
90 #define S5PC110_INTC_ONENAND_PEND 0x1048
91 #define S5PC110_INTC_DMA_STATUS 0x1064
92 #define S5PC110_INTC_ONENAND_STATUS 0x1068
94 #define S5PC110_INTC_DMA_TD (1 << 24)
95 #define S5PC110_INTC_DMA_TE (1 << 16)
97 #define S5PC110_DMA_CFG_SINGLE (0x0 << 16)
98 #define S5PC110_DMA_CFG_4BURST (0x2 << 16)
99 #define S5PC110_DMA_CFG_8BURST (0x3 << 16)
100 #define S5PC110_DMA_CFG_16BURST (0x4 << 16)
102 #define S5PC110_DMA_CFG_INC (0x0 << 8)
103 #define S5PC110_DMA_CFG_CNT (0x1 << 8)
105 #define S5PC110_DMA_CFG_8BIT (0x0 << 0)
106 #define S5PC110_DMA_CFG_16BIT (0x1 << 0)
107 #define S5PC110_DMA_CFG_32BIT (0x2 << 0)
109 #define S5PC110_DMA_SRC_CFG_READ (S5PC110_DMA_CFG_16BURST | \
110 S5PC110_DMA_CFG_INC | \
111 S5PC110_DMA_CFG_16BIT)
112 #define S5PC110_DMA_DST_CFG_READ (S5PC110_DMA_CFG_16BURST | \
113 S5PC110_DMA_CFG_INC | \
114 S5PC110_DMA_CFG_32BIT)
115 #define S5PC110_DMA_SRC_CFG_WRITE (S5PC110_DMA_CFG_16BURST | \
116 S5PC110_DMA_CFG_INC | \
117 S5PC110_DMA_CFG_32BIT)
118 #define S5PC110_DMA_DST_CFG_WRITE (S5PC110_DMA_CFG_16BURST | \
119 S5PC110_DMA_CFG_INC | \
120 S5PC110_DMA_CFG_16BIT)
122 #define S5PC110_DMA_TRANS_CMD_TDC (0x1 << 18)
123 #define S5PC110_DMA_TRANS_CMD_TEC (0x1 << 16)
124 #define S5PC110_DMA_TRANS_CMD_TR (0x1 << 0)
126 #define S5PC110_DMA_TRANS_STATUS_TD (0x1 << 18)
127 #define S5PC110_DMA_TRANS_STATUS_TB (0x1 << 17)
128 #define S5PC110_DMA_TRANS_STATUS_TE (0x1 << 16)
130 #define S5PC110_DMA_DIR_READ 0x0
131 #define S5PC110_DMA_DIR_WRITE 0x1
152 #define CMD_MAP_00(dev, addr) (dev->cmd_map(MAP_00, ((addr) << 1)))
153 #define CMD_MAP_01(dev, mem_addr) (dev->cmd_map(MAP_01, (mem_addr)))
154 #define CMD_MAP_10(dev, mem_addr) (dev->cmd_map(MAP_10, (mem_addr)))
155 #define CMD_MAP_11(dev, addr) (dev->cmd_map(MAP_11, ((addr) << 2)))
159 static inline int s3c_read_reg(
int offset)
164 static inline void s3c_write_reg(
int value,
int offset)
169 static inline int s3c_read_cmd(
unsigned int cmd)
174 static inline void s3c_write_cmd(
int value,
unsigned int cmd)
180 static void s3c_dump_reg(
void)
184 for (i = 0; i < 0x400; i += 0x40) {
186 (
unsigned int) onenand->
base + i,
187 s3c_read_reg(i), s3c_read_reg(i + 0x10),
188 s3c_read_reg(i + 0x20), s3c_read_reg(i + 0x30));
193 static unsigned int s3c64xx_cmd_map(
unsigned type,
unsigned val)
198 static unsigned int s5pc1xx_cmd_map(
unsigned type,
unsigned val)
203 static unsigned int s3c6400_mem_addr(
int fba,
int fpa,
int fsa)
209 static unsigned int s3c6410_mem_addr(
int fba,
int fpa,
int fsa)
215 static unsigned int s5pc100_mem_addr(
int fba,
int fpa,
int fsa)
221 static void s3c_onenand_reset(
void)
223 unsigned long timeout = 0x10000;
227 while (1 && timeout--) {
241 static unsigned short s3c_onenand_readw(
void __iomem *
addr)
246 int word_addr = reg >> 1;
276 if ((
unsigned int) addr < ONENAND_DATARAM && onenand->bootram_command) {
285 value = s3c_read_cmd(
CMD_MAP_11(onenand, word_addr)) & 0xffff;
286 dev_info(dev,
"%s: Illegal access at reg 0x%x, value 0x%x\n", __func__,
291 static void s3c_onenand_writew(
unsigned short value,
void __iomem *addr)
295 unsigned int reg = addr - this->base;
296 unsigned int word_addr = reg >> 1;
329 dev_info(dev,
"%s: Illegal access at reg 0x%x, value 0x%x\n", __func__,
332 s3c_write_cmd(value,
CMD_MAP_11(onenand, word_addr));
340 unsigned long timeout;
381 dev_info(dev,
"%s: ECC error = 0x%04x\n", __func__,
389 dev_info(dev,
"%s: controller error = 0x%04x\n", __func__,
392 dev_info(dev,
"%s: it's locked error = 0x%04x\n",
401 static int s3c_onenand_command(
struct mtd_info *mtd,
int cmd, loff_t addr,
406 int fba, fpa, fsa = 0;
407 unsigned int mem_addr, cmd_map_01, cmd_map_10;
415 mem_addr = onenand->
mem_addr(fba, fpa, fsa);
433 m = (
unsigned int *) onenand->
page_buf;
434 s = (
unsigned int *) onenand->
oob_buf;
447 for (i = 0; i < mcount; i++)
448 *m++ = s3c_read_cmd(cmd_map_01);
454 for (i = 0; i < mcount; i++)
455 *m++ = s3c_read_cmd(cmd_map_01);
458 for (i = 0; i <
scount; i++)
459 *s++ = s3c_read_cmd(cmd_map_01);
466 for (i = 0; i < mcount; i++)
467 s3c_write_cmd(*m++, cmd_map_01);
474 for (i = 0; i < mcount; i++)
475 s3c_write_cmd(0xffffffff, cmd_map_01);
478 for (i = 0; i <
scount; i++)
479 s3c_write_cmd(*s++, cmd_map_01);
499 static unsigned char *s3c_get_bufferram(
struct mtd_info *mtd,
int area)
506 p = (
unsigned char *) onenand->
page_buf;
510 p = (
unsigned char *) onenand->
oob_buf;
518 static int onenand_read_bufferram(
struct mtd_info *mtd,
int area,
524 p = s3c_get_bufferram(mtd, area);
525 memcpy(buffer, p + offset, count);
529 static int onenand_write_bufferram(
struct mtd_info *mtd,
int area,
535 p = s3c_get_bufferram(mtd, area);
536 memcpy(p + offset, buffer, count);
542 static int s5pc110_dma_poll(
void *dst,
void *src,
size_t count,
int direction)
546 unsigned long timeout;
608 static int s5pc110_dma_irq(
void *dst,
void *src,
size_t count,
int direction)
640 static int s5pc110_read_bufferram(
struct mtd_info *mtd,
int area,
645 void *
buf = (
void *) buffer;
647 int err, ofs, page_dma = 0;
650 p = this->base + area;
653 p += this->writesize;
658 if (offset & 3 || (
size_t) buf & 3 ||
663 if (buf >= high_memory) {
674 ofs = ((
size_t) buf & ~PAGE_MASK);
678 dma_src = onenand->
phys_base + (p - this->base);
682 dma_src = onenand->
phys_base + (p - this->base);
686 dev_err(dev,
"Couldn't map a %d byte buffer for DMA\n", count);
689 err = s5pc110_dma_ops((
void *) dma_dst, (
void *) dma_src,
704 p = this->page_buf +
offset;
712 static int s5pc110_chip_probe(
struct mtd_info *mtd)
718 static int s3c_onenand_bbt_wait(
struct mtd_info *mtd,
int state)
722 unsigned long timeout;
740 if (stat & LOAD_CMP) {
751 static void s3c_onenand_check_lock_status(
struct mtd_info *mtd)
758 end = this->chipsize >> this->erase_shift;
760 for (block = 0; block <
end; block++) {
761 unsigned int mem_addr = onenand->
mem_addr(block, 0, 0);
762 tmp = s3c_read_cmd(
CMD_MAP_01(onenand, mem_addr));
765 dev_err(dev,
"block %d is write-protected!\n", block);
771 static void s3c_onenand_do_lock_cmd(
struct mtd_info *mtd, loff_t ofs,
775 int start,
end, start_mem_addr, end_mem_addr;
778 start_mem_addr = onenand->
mem_addr(start, 0, 0);
780 end_mem_addr = onenand->
mem_addr(end, 0, 0);
797 static void s3c_unlock_all(
struct mtd_info *mtd)
812 s3c_onenand_check_lock_status(mtd);
823 s3c_onenand_check_lock_status(mtd);
826 static void s3c_onenand_setup(
struct mtd_info *mtd)
833 onenand->
mem_addr = s3c6400_mem_addr;
834 onenand->
cmd_map = s3c64xx_cmd_map;
836 onenand->
mem_addr = s3c6410_mem_addr;
837 onenand->
cmd_map = s3c64xx_cmd_map;
839 onenand->
mem_addr = s5pc100_mem_addr;
840 onenand->
cmd_map = s5pc1xx_cmd_map;
853 this->
wait = s3c_onenand_wait;
854 this->
bbt_wait = s3c_onenand_bbt_wait;
856 this->
command = s3c_onenand_command;
870 pdata = pdev->
dev.platform_data;
876 dev_err(&pdev->
dev,
"failed to allocate memory\n");
888 mtd->dev.parent = &pdev->
dev;
890 onenand->
pdev = pdev;
893 s3c_onenand_setup(mtd);
897 dev_err(&pdev->
dev,
"no memory resource defined\n");
899 goto ahb_resource_failed;
905 dev_err(&pdev->
dev,
"failed to request memory resource\n");
907 goto resource_failed;
911 if (!onenand->
base) {
912 dev_err(&pdev->
dev,
"failed to map memory resource\n");
917 this->base = onenand->
base;
925 dev_err(&pdev->
dev,
"no buffer memory resource defined\n");
927 goto ahb_resource_failed;
933 dev_err(&pdev->
dev,
"failed to request buffer memory resource\n");
935 goto ahb_resource_failed;
940 dev_err(&pdev->
dev,
"failed to map buffer memory resource\n");
942 goto ahb_ioremap_failed;
960 mtd->subpage_sft = 0;
966 dev_err(&pdev->
dev,
"no dma memory resource defined\n");
968 goto dma_resource_failed;
974 dev_err(&pdev->
dev,
"failed to request dma memory resource\n");
976 goto dma_resource_failed;
981 dev_err(&pdev->
dev,
"failed to map dma memory resource\n");
983 goto dma_ioremap_failed;
988 s5pc110_dma_ops = s5pc110_dma_poll;
992 init_completion(&onenand->
complete);
993 s5pc110_dma_ops = s5pc110_dma_irq;
1010 mtd->subpage_sft = 0;
1015 dev_info(&onenand->
pdev->dev,
"OneNAND Sync. Burst Read enabled\n");
1021 platform_set_drvdata(pdev, mtd);
1031 resource_size(onenand->
dma_res));
1041 resource_size(onenand->
ahb_res));
1042 dma_resource_failed:
1043 ahb_resource_failed:
1058 struct mtd_info *mtd = platform_get_drvdata(pdev);
1065 resource_size(onenand->
ahb_res));
1070 resource_size(onenand->
dma_res));
1076 platform_set_drvdata(pdev,
NULL);
1084 static int s3c_pm_ops_suspend(
struct device *dev)
1087 struct mtd_info *mtd = platform_get_drvdata(pdev);
1094 static int s3c_pm_ops_resume(
struct device *dev)
1097 struct mtd_info *mtd = platform_get_drvdata(pdev);
1104 static const struct dev_pm_ops s3c_pm_ops = {
1105 .suspend = s3c_pm_ops_suspend,
1106 .resume = s3c_pm_ops_resume,
1111 .name =
"s3c6400-onenand",
1114 .name =
"s3c6410-onenand",
1117 .name =
"s5pc100-onenand",
1120 .name =
"s5pc110-onenand",
1128 .name =
"samsung-onenand",
1131 .id_table = s3c_onenand_driver_ids,
1132 .probe = s3c_onenand_probe,