1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2009 4 * Heiko Schocher, DENX Software Engineering, hs@denx.de 5 */ 6 7#include <common.h> 8#include <nand.h> 9#include <asm/io.h> 10#include <linux/delay.h> 11 12#define CONFIG_NAND_MODE_REG (void *)(CONFIG_SYS_NAND_BASE + 0x20000) 13#define CONFIG_NAND_DATA_REG (void *)(CONFIG_SYS_NAND_BASE + 0x30000) 14 15#define read_mode() in_8(CONFIG_NAND_MODE_REG) 16#define write_mode(val) out_8(CONFIG_NAND_MODE_REG, val) 17#define read_data() in_8(CONFIG_NAND_DATA_REG) 18#define write_data(val) out_8(CONFIG_NAND_DATA_REG, val) 19 20#define KPN_RDY2 (1 << 7) 21#define KPN_RDY1 (1 << 6) 22#define KPN_WPN (1 << 4) 23#define KPN_CE2N (1 << 3) 24#define KPN_CE1N (1 << 2) 25#define KPN_ALE (1 << 1) 26#define KPN_CLE (1 << 0) 27 28#define KPN_DEFAULT_CHIP_DELAY 50 29 30static int kpn_chip_ready(void) 31{ 32 if (read_mode() & KPN_RDY1) 33 return 1; 34 35 return 0; 36} 37 38static void kpn_wait_rdy(void) 39{ 40 int cnt = 1000000; 41 42 while (--cnt && !kpn_chip_ready()) 43 udelay(1); 44 45 if (!cnt) 46 printf ("timeout while waiting for RDY\n"); 47} 48 49static void kpn_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) 50{ 51 u8 reg_val = read_mode(); 52 53 if (ctrl & NAND_CTRL_CHANGE) { 54 reg_val = reg_val & ~(KPN_ALE + KPN_CLE); 55 56 if (ctrl & NAND_CLE) 57 reg_val = reg_val | KPN_CLE; 58 if (ctrl & NAND_ALE) 59 reg_val = reg_val | KPN_ALE; 60 if (ctrl & NAND_NCE) 61 reg_val = reg_val & ~KPN_CE1N; 62 else 63 reg_val = reg_val | KPN_CE1N; 64 65 write_mode(reg_val); 66 } 67 if (cmd != NAND_CMD_NONE) 68 write_data(cmd); 69 70 /* wait until flash is ready */ 71 kpn_wait_rdy(); 72} 73 74static u_char kpn_nand_read_byte(struct mtd_info *mtd) 75{ 76 return read_data(); 77} 78 79static void kpn_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 80{ 81 int i; 82 83 for (i = 0; i < len; i++) { 84 write_data(buf[i]); 85 kpn_wait_rdy(); 86 } 87} 88 89static void kpn_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) 90{ 91 int i; 92 93 for (i = 0; i < len; i++) 94 buf[i] = read_data(); 95} 96 97static int kpn_nand_dev_ready(struct mtd_info *mtd) 98{ 99 kpn_wait_rdy(); 100 101 return 1; 102} 103 104int board_nand_init(struct nand_chip *nand) 105{ 106#if defined(CONFIG_NAND_ECC_BCH) 107 nand->ecc.mode = NAND_ECC_SOFT_BCH; 108#else 109 nand->ecc.mode = NAND_ECC_SOFT; 110#endif 111 112 /* Reference hardware control function */ 113 nand->cmd_ctrl = kpn_nand_hwcontrol; 114 nand->read_byte = kpn_nand_read_byte; 115 nand->write_buf = kpn_nand_write_buf; 116 nand->read_buf = kpn_nand_read_buf; 117 nand->dev_ready = kpn_nand_dev_ready; 118 nand->chip_delay = KPN_DEFAULT_CHIP_DELAY; 119 120 /* reset mode register */ 121 write_mode(KPN_CE1N + KPN_CE2N + KPN_WPN); 122 return 0; 123} 124