2 * Copyright (C) 2014 Panasonic Corporation
3 * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
5 * SPDX-License-Identifier: GPL-2.0+
10 #include <asm/unaligned.h>
11 #include <linux/mtd/rawnand.h>
14 #define DENALI_MAP01 (1 << 26) /* read/write pages in PIO */
15 #define DENALI_MAP10 (2 << 26) /* high-level control plane */
17 #define INDEX_CTRL_REG 0x0
18 #define INDEX_DATA_REG 0x10
20 #define SPARE_ACCESS 0x41
21 #define MAIN_ACCESS 0x42
22 #define PIPELINE_ACCESS 0x2000
24 #define BANK(x) ((x) << 24)
26 static void __iomem
*denali_flash_mem
=
27 (void __iomem
*)CONFIG_SYS_NAND_DATA_BASE
;
28 static void __iomem
*denali_flash_reg
=
29 (void __iomem
*)CONFIG_SYS_NAND_REGS_BASE
;
31 static const int flash_bank
;
32 static int page_size
, oob_size
, pages_per_block
;
34 static void index_addr(uint32_t address
, uint32_t data
)
36 writel(address
, denali_flash_mem
+ INDEX_CTRL_REG
);
37 writel(data
, denali_flash_mem
+ INDEX_DATA_REG
);
40 static int wait_for_irq(uint32_t irq_mask
)
42 unsigned long timeout
= 1000000;
46 intr_status
= readl(denali_flash_reg
+ INTR_STATUS(flash_bank
));
48 if (intr_status
& INTR__ECC_UNCOR_ERR
) {
49 debug("Uncorrected ECC detected\n");
53 if (intr_status
& irq_mask
)
61 debug("Timeout with interrupt status %08x\n", intr_status
);
68 static void read_data_from_flash_mem(uint8_t *buf
, int len
)
73 /* transfer the data from the flash */
74 buf32
= (uint32_t *)buf
;
77 * Let's take care of unaligned access although it rarely happens.
78 * Avoid put_unaligned() for the normal use cases since it leads to
79 * a bit performance regression.
81 if ((unsigned long)buf32
% 4) {
82 for (i
= 0; i
< len
/ 4; i
++)
83 put_unaligned(readl(denali_flash_mem
+ INDEX_DATA_REG
),
86 for (i
= 0; i
< len
/ 4; i
++)
87 *buf32
++ = readl(denali_flash_mem
+ INDEX_DATA_REG
);
93 tmp
= cpu_to_le32(readl(denali_flash_mem
+ INDEX_DATA_REG
));
94 buf
= (uint8_t *)buf32
;
95 for (i
= 0; i
< len
% 4; i
++) {
102 int denali_send_pipeline_cmd(int page
, int ecc_en
, int access_type
)
105 static uint32_t page_count
= 1;
107 writel(ecc_en
, denali_flash_reg
+ ECC_ENABLE
);
109 /* clear all bits of intr_status. */
110 writel(0xffff, denali_flash_reg
+ INTR_STATUS(flash_bank
));
112 addr
= BANK(flash_bank
) | page
;
114 /* setup the acccess type */
115 cmd
= DENALI_MAP10
| addr
;
116 index_addr(cmd
, access_type
);
118 /* setup the pipeline command */
119 index_addr(cmd
, PIPELINE_ACCESS
| page_count
);
121 cmd
= DENALI_MAP01
| addr
;
122 writel(cmd
, denali_flash_mem
+ INDEX_CTRL_REG
);
124 return wait_for_irq(INTR__LOAD_COMP
);
127 static int nand_read_oob(void *buf
, int page
)
131 ret
= denali_send_pipeline_cmd(page
, 0, SPARE_ACCESS
);
135 read_data_from_flash_mem(buf
, oob_size
);
140 static int nand_read_page(void *buf
, int page
)
144 ret
= denali_send_pipeline_cmd(page
, 1, MAIN_ACCESS
);
148 read_data_from_flash_mem(buf
, page_size
);
153 static int nand_block_isbad(void *buf
, int block
)
157 ret
= nand_read_oob(buf
, block
* pages_per_block
);
161 return *((uint8_t *)buf
+ CONFIG_SYS_NAND_BAD_BLOCK_POS
) != 0xff;
164 /* nand_init() - initialize data to make nand usable by SPL */
167 /* access to main area */
168 writel(0, denali_flash_reg
+ TRANSFER_SPARE_REG
);
171 * These registers are expected to be already set by the hardware
172 * or earlier boot code. So we read these values out.
174 page_size
= readl(denali_flash_reg
+ DEVICE_MAIN_AREA_SIZE
);
175 oob_size
= readl(denali_flash_reg
+ DEVICE_SPARE_AREA_SIZE
);
176 pages_per_block
= readl(denali_flash_reg
+ PAGES_PER_BLOCK
);
179 int nand_spl_load_image(uint32_t offs
, unsigned int size
, void *dst
)
181 int block
, page
, column
, readlen
;
183 int force_bad_block_check
= 1;
185 page
= offs
/ page_size
;
186 column
= offs
% page_size
;
188 block
= page
/ pages_per_block
;
189 page
= page
% pages_per_block
;
192 if (force_bad_block_check
|| page
== 0) {
193 ret
= nand_block_isbad(dst
, block
);
203 force_bad_block_check
= 0;
205 ret
= nand_read_page(dst
, block
* pages_per_block
+ page
);
209 readlen
= min(page_size
- column
, (int)size
);
211 if (unlikely(column
)) {
212 /* Partial page read */
213 memmove(dst
, dst
+ column
, readlen
);
220 if (page
== pages_per_block
) {
229 void nand_deselect(void) {}