Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) /* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include "flash.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "flash_com.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "nandc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "rk_sftl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define     CPU_DELAY_NS(n)	ndelay(n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define	    NANDC_MASTER_EN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) void __iomem *nandc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) static u8 g_nandc_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) static u32 g_nandc_ecc_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #ifdef NANDC_MASTER_EN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) static struct MASTER_INFO_T master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) static u32 *g_master_temp_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) u8 nandc_get_version(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	return g_nandc_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) void nandc_init(void __iomem *nandc_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	union FM_CTL_T ctl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	nandc_base = nandc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	ctl_reg.d32 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	g_nandc_ver = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	if (nandc_readl(NANDC_V9_NANDC_VER) == RK3326_NANDC_VER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		g_nandc_ver = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	if (g_nandc_ver == 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		ctl_reg.V9.wp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		ctl_reg.V9.sif_read_delay = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		nandc_writel(ctl_reg.d32, NANDC_V9_FMCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		nandc_writel(0, NANDC_V9_RANDMZ_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		nandc_writel(0x1041, NANDC_V9_FMWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		ctl_reg.V6.wp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		nandc_writel(ctl_reg.d32, NANDC_FMCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		nandc_writel(0, NANDC_RANDMZ_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		nandc_writel(0x1061, NANDC_FMWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	nandc_time_cfg(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #ifdef NANDC_MASTER_EN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	if (!g_master_temp_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		g_master_temp_buf = (u32 *)ftl_malloc(MAX_FLASH_PAGE_SIZE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 					      MAX_FLASH_PAGE_SIZE / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	master.page_buf = &g_master_temp_buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	master.spare_buf = &g_master_temp_buf[MAX_FLASH_PAGE_SIZE / 4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	master.mapped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) void nandc_flash_cs(u8 chip_sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	union FM_CTL_T tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	tmp.d32 = nandc_readl(NANDC_FMCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	tmp.V6.cs = 0x01 << chip_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	nandc_writel(tmp.d32, NANDC_FMCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) void nandc_flash_de_cs(u8 chip_sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	union FM_CTL_T tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	tmp.d32 = nandc_readl(NANDC_FMCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	tmp.V6.cs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	tmp.V6.flash_abort_clear = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	nandc_writel(tmp.d32, NANDC_FMCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) u32 nandc_delayns(u32 count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	CPU_DELAY_NS(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) u32 nandc_wait_flash_ready(u8 chip_sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	union FM_CTL_T tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	for (i = 0; i < 100000; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		nandc_delayns(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		tmp.d32 = nandc_readl(NANDC_FMCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		if (tmp.V6.rdy != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	if (i >= 100000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		status = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) void nandc_randmz_sel(u8 chip_sel, u32 randmz_seed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	nandc_writel(randmz_seed, NANDC_RANDMZ_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) void nandc_time_cfg(u32 ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (g_nandc_ver == 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		if (ns < 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			nandc_writel(0x1041, NANDC_V9_FMWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		else if (ns >= 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 			nandc_writel(0x2082, NANDC_V9_FMWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			nandc_writel(0x1061, NANDC_V9_FMWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		if (ns < 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			nandc_writel(0x1061, NANDC_FMWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		else if (ns >= 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			nandc_writel(0x2082, NANDC_FMWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			nandc_writel(0x1081, NANDC_FMWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) void nandc_bch_sel(u8 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	union BCH_CTL_T tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	union FL_CTL_T fl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	u8 bch_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	fl_reg.d32 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	fl_reg.V6.rst = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	g_nandc_ecc_bits = bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	if (g_nandc_ver == 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		nandc_writel(fl_reg.d32, NANDC_V9_FLCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		if (bits == 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			bch_config = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		else if (bits == 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			bch_config = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		else if (bits == 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			bch_config = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			bch_config = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		tmp.d32 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		tmp.V9.bchmode = bch_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		tmp.V9.bchrst = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		nandc_writel(tmp.d32, NANDC_V9_BCHCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		nandc_writel(fl_reg.d32, NANDC_FLCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		tmp.d32 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		tmp.V6.addr = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		tmp.V6.bch_mode1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		if (bits == 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			tmp.V6.bch_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		} else if (bits == 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			tmp.V6.bch_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			tmp.V6.bch_mode1 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			tmp.V6.bch_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			if (bits == 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 				tmp.V6.bch_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		tmp.V6.rst = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		nandc_writel(tmp.d32, NANDC_BCHCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  *Nandc xfer data transmission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  *1. set bch register except nandc version equals 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  *2. set internal transfer control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  *3. set bus transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  *	a. target memory data address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  *	b. ahb setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  *4. configure register orderly and start transmission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static void nandc_xfer_start(u8 dir, u8 n_sec, u32 *data, u32 *spare)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	union BCH_CTL_T bch_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	union FL_CTL_T fl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	union MTRANS_CFG_T master_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	u16 *p_spare_tmp = (u16 *)spare;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	fl_reg.d32 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	if (g_nandc_ver == 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		fl_reg.V9.flash_rdn = dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		fl_reg.V9.bypass = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		fl_reg.V9.tr_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		fl_reg.V9.async_tog_mix = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		fl_reg.V9.cor_able = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		fl_reg.V9.st_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		fl_reg.V9.page_num = (n_sec + 1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		/* dma start transfer data do care flash rdy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		fl_reg.V9.flash_st_mod = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		if (dir != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			for (i = 0; i < n_sec / 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 				if (spare) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 					master.spare_buf[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 						(p_spare_tmp[0]) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 						((u32)p_spare_tmp[1] << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 					p_spare_tmp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 					master.spare_buf[i] = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			master.spare_buf[0] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		master.page_vir = (u32 *)((data == (u32 *)NULL) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 					  master.page_buf :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 					  (u32 *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		master.spare_vir = (u32 *)master.spare_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		master.page_phy =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		(u32)rknandc_dma_map_single((unsigned long)master.page_vir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 				    fl_reg.V6.page_num * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 				    dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		master.spare_phy =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		(u32)rknandc_dma_map_single((unsigned long)master.spare_vir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 				    fl_reg.V6.page_num * 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 				    dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		master.mapped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		nandc_writel(master.page_phy, NANDC_V9_MTRANS_SADDR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		nandc_writel(master.spare_phy, NANDC_V9_MTRANS_SADDR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		master_reg.d32 =  nandc_readl(NANDC_V9_MTRANS_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		master_reg.V9.incr_num = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		master_reg.V9.burst = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		master_reg.V9.hsize = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		master_reg.V9.bus_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		master_reg.V9.ahb_wr = !dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		master_reg.V9.ahb_wr_st = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		master_reg.V9.redundance_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		nandc_writel(master_reg.d32, NANDC_V9_MTRANS_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		nandc_writel(fl_reg.d32, NANDC_V9_FLCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		fl_reg.V9.flash_st = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		nandc_writel(fl_reg.d32, NANDC_V9_FLCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		bch_reg.d32 = nandc_readl(NANDC_BCHCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		bch_reg.V6.addr = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		bch_reg.V6.power_down = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		bch_reg.V6.region = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		fl_reg.V6.rdn = dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		fl_reg.V6.dma = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		fl_reg.V6.tr_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		fl_reg.V6.async_tog_mix = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		fl_reg.V6.cor_en = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		fl_reg.V6.st_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		master_reg.V6.bus_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		if (dir != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			u32 spare_sz = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			for (i = 0; i < n_sec / 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 				if (spare) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 					master.spare_buf[i * spare_sz / 4] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 					(p_spare_tmp[0]) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 					((u32)p_spare_tmp[1] << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 					p_spare_tmp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 					master.spare_buf[i * spare_sz / 4] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 					0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		fl_reg.V6.page_num = (n_sec + 1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		master.page_vir = (u32 *)((data == (u32 *)NULL) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 					  master.page_buf :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 					  (u32 *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		master.spare_vir = (u32 *)master.spare_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		master.page_phy =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			(u32)rknandc_dma_map_single((unsigned long)master.page_vir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 						    fl_reg.V6.page_num * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 						    dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		master.spare_phy =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			(u32)rknandc_dma_map_single((unsigned long)master.spare_vir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 						    fl_reg.V6.page_num * 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 						    dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		master.mapped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		nandc_writel(master.page_phy, NANDC_MTRANS_SADDR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		nandc_writel(master.spare_phy, NANDC_MTRANS_SADDR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		master_reg.d32 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		master_reg.V6.incr_num = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		master_reg.V6.burst = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		master_reg.V6.hsize = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		master_reg.V6.bus_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		master_reg.V6.ahb_wr = !dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		master_reg.V6.ahb_wr_st = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		nandc_writel(master_reg.d32, NANDC_MTRANS_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		nandc_writel(bch_reg.d32, NANDC_BCHCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		nandc_writel(fl_reg.d32, NANDC_FLCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		fl_reg.V6.start = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		nandc_writel(fl_reg.d32, NANDC_FLCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)  * Wait for the end of data transmission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static void nandc_xfer_done(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	union FL_CTL_T fl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	union MTRANS_CFG_T master_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	if (g_nandc_ver == 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		union MTRANS_STAT_T stat_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		master_reg.d32 = nandc_readl(NANDC_V9_MTRANS_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		if (master_reg.V9.ahb_wr != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 				fl_reg.d32 = nandc_readl(NANDC_V9_FLCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 				stat_reg.d32 = nandc_readl(NANDC_V9_MTRANS_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 				usleep_range(20, 30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			} while (stat_reg.V9.mtrans_cnt < fl_reg.V9.page_num ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 				 fl_reg.V9.tr_rdy == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 			udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 			if (master.mapped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 				rknandc_dma_unmap_single((u64)master.page_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 					fl_reg.V9.page_num * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 					0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 				rknandc_dma_unmap_single((u64)master.spare_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 					fl_reg.V9.page_num * 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 					0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 				fl_reg.d32 = nandc_readl(NANDC_V9_FLCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 				usleep_range(20, 30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			} while (fl_reg.V9.tr_rdy == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			if (master.mapped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 				rknandc_dma_unmap_single((u64)master.page_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 					fl_reg.V9.page_num * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 					1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 				rknandc_dma_unmap_single((u64)master.spare_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 					fl_reg.V9.page_num * 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 					1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		if (master_reg.V6.bus_mode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			union MTRANS_STAT_T stat_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		if (master_reg.V6.ahb_wr != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 				fl_reg.d32 = nandc_readl(NANDC_FLCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 				stat_reg.d32 = nandc_readl(NANDC_MTRANS_STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 				usleep_range(20, 30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 			} while (stat_reg.V6.mtrans_cnt < fl_reg.V6.page_num ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 				 fl_reg.V6.tr_rdy == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 			if (master.mapped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 				rknandc_dma_unmap_single(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 					(unsigned long)(master.page_phy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 					fl_reg.V6.page_num * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 					0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 				rknandc_dma_unmap_single(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 					(unsigned long)(master.spare_phy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 					fl_reg.V6.page_num * 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 					0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 				fl_reg.d32 = nandc_readl(NANDC_FLCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 				usleep_range(20, 30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 			} while (fl_reg.V6.tr_rdy == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			if (master.mapped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 				rknandc_dma_unmap_single(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 					(unsigned long)(master.page_phy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 					fl_reg.V6.page_num * 1024, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 				rknandc_dma_unmap_single(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 					(unsigned long)(master.spare_phy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 					fl_reg.V6.page_num * 64, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		master.mapped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 				fl_reg.d32 = nandc_readl(NANDC_FLCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 			} while ((fl_reg.V6.tr_rdy == 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) u32 nandc_xfer_data(u8 chip_sel, u8 dir, u8 n_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		    u32 *p_data, u32 *p_spare)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	u32 status = NAND_STS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	u32 spare[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	union BCH_ST_T bch_st_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	if (dir == NANDC_WRITE && !p_spare) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		p_spare = (u32 *)spare;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		memset(spare, 0xFF, sizeof(spare));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	nandc_xfer_start(dir, n_sec, p_data, p_spare);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	nandc_xfer_done();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	if (dir == NANDC_READ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		if (g_nandc_ver == 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			for (i = 0; i < n_sec / 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 				bch_st_reg.d32 = nandc_readl(NANDC_V9_BCHST(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 				if (n_sec > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 					if (bch_st_reg.V9.fail0 || bch_st_reg.V9.fail1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 						status = NAND_STS_ECC_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 					} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 						u32 tmp = max((u32)bch_st_reg.V9.err_bits0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 							      (u32)bch_st_reg.V9.err_bits1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 						status = max(tmp, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 					if (bch_st_reg.V9.fail0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 						status = NAND_STS_ECC_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 					else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 						status = bch_st_reg.V9.err_bits0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			if (p_spare) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 				for (i = 0; i < n_sec / 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 					p_spare[i] = master.spare_buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			for (i = 0; i < n_sec / 4 ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 				bch_st_reg.d32 = nandc_readl(NANDC_BCHST(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 				if (bch_st_reg.V6.fail0 || bch_st_reg.V6.fail1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 					status = NAND_STS_ECC_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 					u32 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 					tmp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 					max(bch_st_reg.V6.err_bits0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 					    ((u32)bch_st_reg.V6.err_bits0_5 << 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 					    bch_st_reg.V6.err_bits1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 					    ((u32)bch_st_reg.V6.err_bits1_5 << 5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 					status = max(tmp, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			if (p_spare) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 				u32 spare_sz = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 				u32 temp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 				u8 *p_spare_temp = (u8 *)p_spare;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 				for (i = 0; i < n_sec / 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 					temp_data = master.spare_buf[i * spare_sz / 4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 					*p_spare_temp++ = (u8)temp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 					*p_spare_temp++ = (u8)(temp_data >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 					*p_spare_temp++ = (u8)(temp_data >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 					*p_spare_temp++ = (u8)(temp_data >> 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 			nandc_writel(0, NANDC_MTRANS_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) void nandc_clean_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }