Commit c8381bf435ddb104594df00411a8ebd049dd753c
Committed by
Albert ARIBAUD
1 parent
ac2916a224
Exists in
v2017.01-smarct4x
and in
37 other branches
lpc32xx: mtd: nand: add MLC NAND controller
The controller's Reed-Solomon ECC hardware is used except of course for raw reads and writes. It covers in- and out-of-band data together. The SPL framework is supported. Signed-off-by: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Showing 5 changed files with 776 additions and 0 deletions Inline Diff
arch/arm/cpu/arm926ejs/lpc32xx/devices.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> | 2 | * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <common.h> | 7 | #include <common.h> |
8 | #include <asm/arch/cpu.h> | 8 | #include <asm/arch/cpu.h> |
9 | #include <asm/arch/clk.h> | 9 | #include <asm/arch/clk.h> |
10 | #include <asm/arch/uart.h> | 10 | #include <asm/arch/uart.h> |
11 | #include <asm/io.h> | 11 | #include <asm/io.h> |
12 | 12 | ||
13 | static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE; | 13 | static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE; |
14 | static struct uart_ctrl_regs *ctrl = (struct uart_ctrl_regs *)UART_CTRL_BASE; | 14 | static struct uart_ctrl_regs *ctrl = (struct uart_ctrl_regs *)UART_CTRL_BASE; |
15 | 15 | ||
16 | void lpc32xx_uart_init(unsigned int uart_id) | 16 | void lpc32xx_uart_init(unsigned int uart_id) |
17 | { | 17 | { |
18 | if (uart_id < 1 || uart_id > 7) | 18 | if (uart_id < 1 || uart_id > 7) |
19 | return; | 19 | return; |
20 | 20 | ||
21 | /* Disable loopback mode, if it is set by S1L bootloader */ | 21 | /* Disable loopback mode, if it is set by S1L bootloader */ |
22 | clrbits_le32(&ctrl->loop, | 22 | clrbits_le32(&ctrl->loop, |
23 | UART_LOOPBACK(CONFIG_SYS_LPC32XX_UART)); | 23 | UART_LOOPBACK(CONFIG_SYS_LPC32XX_UART)); |
24 | 24 | ||
25 | if (uart_id < 3 || uart_id > 6) | 25 | if (uart_id < 3 || uart_id > 6) |
26 | return; | 26 | return; |
27 | 27 | ||
28 | /* Enable UART system clock */ | 28 | /* Enable UART system clock */ |
29 | setbits_le32(&clk->uartclk_ctrl, CLK_UART(uart_id)); | 29 | setbits_le32(&clk->uartclk_ctrl, CLK_UART(uart_id)); |
30 | 30 | ||
31 | /* Set UART into autoclock mode */ | 31 | /* Set UART into autoclock mode */ |
32 | clrsetbits_le32(&ctrl->clkmode, | 32 | clrsetbits_le32(&ctrl->clkmode, |
33 | UART_CLKMODE_MASK(uart_id), | 33 | UART_CLKMODE_MASK(uart_id), |
34 | UART_CLKMODE_AUTO(uart_id)); | 34 | UART_CLKMODE_AUTO(uart_id)); |
35 | 35 | ||
36 | /* Bypass pre-divider of UART clock */ | 36 | /* Bypass pre-divider of UART clock */ |
37 | writel(CLK_UART_X_DIV(1) | CLK_UART_Y_DIV(1), | 37 | writel(CLK_UART_X_DIV(1) | CLK_UART_Y_DIV(1), |
38 | &clk->u3clk + (uart_id - 3)); | 38 | &clk->u3clk + (uart_id - 3)); |
39 | } | 39 | } |
40 | 40 | ||
41 | void lpc32xx_mac_init(void) | 41 | void lpc32xx_mac_init(void) |
42 | { | 42 | { |
43 | /* Enable MAC interface */ | 43 | /* Enable MAC interface */ |
44 | writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER | 44 | writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER |
45 | | CLK_MAC_MII, &clk->macclk_ctrl); | 45 | | CLK_MAC_MII, &clk->macclk_ctrl); |
46 | } | 46 | } |
47 | |||
48 | void lpc32xx_mlc_nand_init(void) | ||
49 | { | ||
50 | /* Enable NAND interface */ | ||
51 | writel(CLK_NAND_MLC | CLK_NAND_MLC_INT, &clk->flashclk_ctrl); | ||
52 | } | ||
47 | 53 |
arch/arm/include/asm/arch-lpc32xx/clk.h
1 | /* | 1 | /* |
2 | * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> | 2 | * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef _LPC32XX_CLK_H | 7 | #ifndef _LPC32XX_CLK_H |
8 | #define _LPC32XX_CLK_H | 8 | #define _LPC32XX_CLK_H |
9 | 9 | ||
10 | #include <asm/types.h> | 10 | #include <asm/types.h> |
11 | 11 | ||
12 | #define OSC_CLK_FREQUENCY 13000000 | 12 | #define OSC_CLK_FREQUENCY 13000000 |
13 | #define RTC_CLK_FREQUENCY 32768 | 13 | #define RTC_CLK_FREQUENCY 32768 |
14 | 14 | ||
15 | /* Clocking and Power Control Registers */ | 15 | /* Clocking and Power Control Registers */ |
16 | struct clk_pm_regs { | 16 | struct clk_pm_regs { |
17 | u32 reserved0[5]; | 17 | u32 reserved0[5]; |
18 | u32 boot_map; /* Boot Map Control Register */ | 18 | u32 boot_map; /* Boot Map Control Register */ |
19 | u32 p0_intr_er; /* Port 0/1 Start and Interrupt Enable */ | 19 | u32 p0_intr_er; /* Port 0/1 Start and Interrupt Enable */ |
20 | u32 usbdiv_ctrl; /* USB Clock Pre-Divide Register */ | 20 | u32 usbdiv_ctrl; /* USB Clock Pre-Divide Register */ |
21 | /* Internal Start Signal Sources Registers */ | 21 | /* Internal Start Signal Sources Registers */ |
22 | u32 start_er_int; /* Start Enable Register */ | 22 | u32 start_er_int; /* Start Enable Register */ |
23 | u32 start_rsr_int; /* Start Raw Status Register */ | 23 | u32 start_rsr_int; /* Start Raw Status Register */ |
24 | u32 start_sr_int; /* Start Status Register */ | 24 | u32 start_sr_int; /* Start Status Register */ |
25 | u32 start_apr_int; /* Start Activation Polarity Register */ | 25 | u32 start_apr_int; /* Start Activation Polarity Register */ |
26 | /* Device Pin Start Signal Sources Registers */ | 26 | /* Device Pin Start Signal Sources Registers */ |
27 | u32 start_er_pin; /* Start Enable Register */ | 27 | u32 start_er_pin; /* Start Enable Register */ |
28 | u32 start_rsr_pin; /* Start Raw Status Register */ | 28 | u32 start_rsr_pin; /* Start Raw Status Register */ |
29 | u32 start_sr_pin; /* Start Status Register */ | 29 | u32 start_sr_pin; /* Start Status Register */ |
30 | u32 start_apr_pin; /* Start Activation Polarity Register */ | 30 | u32 start_apr_pin; /* Start Activation Polarity Register */ |
31 | /* Clock Control Registers */ | 31 | /* Clock Control Registers */ |
32 | u32 hclkdiv_ctrl; /* HCLK Divider Control Register */ | 32 | u32 hclkdiv_ctrl; /* HCLK Divider Control Register */ |
33 | u32 pwr_ctrl; /* Power Control Register */ | 33 | u32 pwr_ctrl; /* Power Control Register */ |
34 | u32 pll397_ctrl; /* PLL397 Control Register */ | 34 | u32 pll397_ctrl; /* PLL397 Control Register */ |
35 | u32 osc_ctrl; /* Main Oscillator Control Register */ | 35 | u32 osc_ctrl; /* Main Oscillator Control Register */ |
36 | u32 sysclk_ctrl; /* SYSCLK Control Register */ | 36 | u32 sysclk_ctrl; /* SYSCLK Control Register */ |
37 | u32 lcdclk_ctrl; /* LCD Clock Control Register */ | 37 | u32 lcdclk_ctrl; /* LCD Clock Control Register */ |
38 | u32 hclkpll_ctrl; /* HCLK PLL Control Register */ | 38 | u32 hclkpll_ctrl; /* HCLK PLL Control Register */ |
39 | u32 reserved1; | 39 | u32 reserved1; |
40 | u32 adclk_ctrl1; /* ADC Clock Control1 Register */ | 40 | u32 adclk_ctrl1; /* ADC Clock Control1 Register */ |
41 | u32 usb_ctrl; /* USB Control Register */ | 41 | u32 usb_ctrl; /* USB Control Register */ |
42 | u32 sdramclk_ctrl; /* SDRAM Clock Control Register */ | 42 | u32 sdramclk_ctrl; /* SDRAM Clock Control Register */ |
43 | u32 ddr_lap_nom; /* DDR Calibration Nominal Value */ | 43 | u32 ddr_lap_nom; /* DDR Calibration Nominal Value */ |
44 | u32 ddr_lap_count; /* DDR Calibration Measured Value */ | 44 | u32 ddr_lap_count; /* DDR Calibration Measured Value */ |
45 | u32 ddr_cal_delay; /* DDR Calibration Delay Value */ | 45 | u32 ddr_cal_delay; /* DDR Calibration Delay Value */ |
46 | u32 ssp_ctrl; /* SSP Control Register */ | 46 | u32 ssp_ctrl; /* SSP Control Register */ |
47 | u32 i2s_ctrl; /* I2S Clock Control Register */ | 47 | u32 i2s_ctrl; /* I2S Clock Control Register */ |
48 | u32 ms_ctrl; /* Memory Card Control Register */ | 48 | u32 ms_ctrl; /* Memory Card Control Register */ |
49 | u32 reserved2[3]; | 49 | u32 reserved2[3]; |
50 | u32 macclk_ctrl; /* Ethernet MAC Clock Control Register */ | 50 | u32 macclk_ctrl; /* Ethernet MAC Clock Control Register */ |
51 | u32 reserved3[4]; | 51 | u32 reserved3[4]; |
52 | u32 test_clk; /* Test Clock Selection Register */ | 52 | u32 test_clk; /* Test Clock Selection Register */ |
53 | u32 sw_int; /* Software Interrupt Register */ | 53 | u32 sw_int; /* Software Interrupt Register */ |
54 | u32 i2cclk_ctrl; /* I2C Clock Control Register */ | 54 | u32 i2cclk_ctrl; /* I2C Clock Control Register */ |
55 | u32 keyclk_ctrl; /* Keyboard Scan Clock Control Register */ | 55 | u32 keyclk_ctrl; /* Keyboard Scan Clock Control Register */ |
56 | u32 adclk_ctrl; /* ADC Clock Control Register */ | 56 | u32 adclk_ctrl; /* ADC Clock Control Register */ |
57 | u32 pwmclk_ctrl; /* PWM Clock Control Register */ | 57 | u32 pwmclk_ctrl; /* PWM Clock Control Register */ |
58 | u32 timclk_ctrl; /* Watchdog and Highspeed Timer Control */ | 58 | u32 timclk_ctrl; /* Watchdog and Highspeed Timer Control */ |
59 | u32 timclk_ctrl1; /* Motor and Timer Clock Control */ | 59 | u32 timclk_ctrl1; /* Motor and Timer Clock Control */ |
60 | u32 spi_ctrl; /* SPI Control Register */ | 60 | u32 spi_ctrl; /* SPI Control Register */ |
61 | u32 flashclk_ctrl; /* NAND Flash Clock Control Register */ | 61 | u32 flashclk_ctrl; /* NAND Flash Clock Control Register */ |
62 | u32 reserved4; | 62 | u32 reserved4; |
63 | u32 u3clk; /* UART 3 Clock Control Register */ | 63 | u32 u3clk; /* UART 3 Clock Control Register */ |
64 | u32 u4clk; /* UART 4 Clock Control Register */ | 64 | u32 u4clk; /* UART 4 Clock Control Register */ |
65 | u32 u5clk; /* UART 5 Clock Control Register */ | 65 | u32 u5clk; /* UART 5 Clock Control Register */ |
66 | u32 u6clk; /* UART 6 Clock Control Register */ | 66 | u32 u6clk; /* UART 6 Clock Control Register */ |
67 | u32 irdaclk; /* IrDA Clock Control Register */ | 67 | u32 irdaclk; /* IrDA Clock Control Register */ |
68 | u32 uartclk_ctrl; /* UART Clock Control Register */ | 68 | u32 uartclk_ctrl; /* UART Clock Control Register */ |
69 | u32 dmaclk_ctrl; /* DMA Clock Control Register */ | 69 | u32 dmaclk_ctrl; /* DMA Clock Control Register */ |
70 | u32 autoclk_ctrl; /* Autoclock Control Register */ | 70 | u32 autoclk_ctrl; /* Autoclock Control Register */ |
71 | }; | 71 | }; |
72 | 72 | ||
73 | /* HCLK Divider Control Register bits */ | 73 | /* HCLK Divider Control Register bits */ |
74 | #define CLK_HCLK_DDRAM_HALF (0x2 << 7) | 74 | #define CLK_HCLK_DDRAM_HALF (0x2 << 7) |
75 | #define CLK_HCLK_DDRAM_NOMINAL (0x1 << 7) | 75 | #define CLK_HCLK_DDRAM_NOMINAL (0x1 << 7) |
76 | #define CLK_HCLK_DDRAM_STOPPED (0x0 << 7) | 76 | #define CLK_HCLK_DDRAM_STOPPED (0x0 << 7) |
77 | #define CLK_HCLK_PERIPH_DIV_MASK (0x1F << 2) | 77 | #define CLK_HCLK_PERIPH_DIV_MASK (0x1F << 2) |
78 | #define CLK_HCLK_PERIPH_DIV(n) ((((n) - 1) & 0x1F) << 2) | 78 | #define CLK_HCLK_PERIPH_DIV(n) ((((n) - 1) & 0x1F) << 2) |
79 | #define CLK_HCLK_ARM_PLL_DIV_MASK (0x3 << 0) | 79 | #define CLK_HCLK_ARM_PLL_DIV_MASK (0x3 << 0) |
80 | #define CLK_HCLK_ARM_PLL_DIV_4 (0x2 << 0) | 80 | #define CLK_HCLK_ARM_PLL_DIV_4 (0x2 << 0) |
81 | #define CLK_HCLK_ARM_PLL_DIV_2 (0x1 << 0) | 81 | #define CLK_HCLK_ARM_PLL_DIV_2 (0x1 << 0) |
82 | #define CLK_HCLK_ARM_PLL_DIV_1 (0x0 << 0) | 82 | #define CLK_HCLK_ARM_PLL_DIV_1 (0x0 << 0) |
83 | 83 | ||
84 | /* Power Control Register bits */ | 84 | /* Power Control Register bits */ |
85 | #define CLK_PWR_HCLK_RUN_PERIPH (1 << 10) | 85 | #define CLK_PWR_HCLK_RUN_PERIPH (1 << 10) |
86 | #define CLK_PWR_EMC_SREFREQ (1 << 9) | 86 | #define CLK_PWR_EMC_SREFREQ (1 << 9) |
87 | #define CLK_PWR_EMC_SREFREQ_UPDATE (1 << 8) | 87 | #define CLK_PWR_EMC_SREFREQ_UPDATE (1 << 8) |
88 | #define CLK_PWR_SDRAM_SREFREQ (1 << 7) | 88 | #define CLK_PWR_SDRAM_SREFREQ (1 << 7) |
89 | #define CLK_PWR_HIGHCORE_LEVEL (1 << 5) | 89 | #define CLK_PWR_HIGHCORE_LEVEL (1 << 5) |
90 | #define CLK_PWR_SYSCLKEN_LEVEL (1 << 4) | 90 | #define CLK_PWR_SYSCLKEN_LEVEL (1 << 4) |
91 | #define CLK_PWR_SYSCLKEN_CTRL (1 << 3) | 91 | #define CLK_PWR_SYSCLKEN_CTRL (1 << 3) |
92 | #define CLK_PWR_NORMAL_RUN (1 << 2) | 92 | #define CLK_PWR_NORMAL_RUN (1 << 2) |
93 | #define CLK_PWR_HIGHCORE_CTRL (1 << 1) | 93 | #define CLK_PWR_HIGHCORE_CTRL (1 << 1) |
94 | #define CLK_PWR_STOP_MODE (1 << 0) | 94 | #define CLK_PWR_STOP_MODE (1 << 0) |
95 | 95 | ||
96 | /* SYSCLK Control Register bits */ | 96 | /* SYSCLK Control Register bits */ |
97 | #define CLK_SYSCLK_PLL397 (1 << 1) | 97 | #define CLK_SYSCLK_PLL397 (1 << 1) |
98 | #define CLK_SYSCLK_MUX (1 << 0) | 98 | #define CLK_SYSCLK_MUX (1 << 0) |
99 | 99 | ||
100 | /* HCLK PLL Control Register bits */ | 100 | /* HCLK PLL Control Register bits */ |
101 | #define CLK_HCLK_PLL_OPERATING (1 << 16) | 101 | #define CLK_HCLK_PLL_OPERATING (1 << 16) |
102 | #define CLK_HCLK_PLL_BYPASS (1 << 15) | 102 | #define CLK_HCLK_PLL_BYPASS (1 << 15) |
103 | #define CLK_HCLK_PLL_DIRECT (1 << 14) | 103 | #define CLK_HCLK_PLL_DIRECT (1 << 14) |
104 | #define CLK_HCLK_PLL_FEEDBACK (1 << 13) | 104 | #define CLK_HCLK_PLL_FEEDBACK (1 << 13) |
105 | #define CLK_HCLK_PLL_POSTDIV_MASK (0x3 << 11) | 105 | #define CLK_HCLK_PLL_POSTDIV_MASK (0x3 << 11) |
106 | #define CLK_HCLK_PLL_POSTDIV_16 (0x3 << 11) | 106 | #define CLK_HCLK_PLL_POSTDIV_16 (0x3 << 11) |
107 | #define CLK_HCLK_PLL_POSTDIV_8 (0x2 << 11) | 107 | #define CLK_HCLK_PLL_POSTDIV_8 (0x2 << 11) |
108 | #define CLK_HCLK_PLL_POSTDIV_4 (0x1 << 11) | 108 | #define CLK_HCLK_PLL_POSTDIV_4 (0x1 << 11) |
109 | #define CLK_HCLK_PLL_POSTDIV_2 (0x0 << 11) | 109 | #define CLK_HCLK_PLL_POSTDIV_2 (0x0 << 11) |
110 | #define CLK_HCLK_PLL_PREDIV_MASK (0x3 << 9) | 110 | #define CLK_HCLK_PLL_PREDIV_MASK (0x3 << 9) |
111 | #define CLK_HCLK_PLL_PREDIV_4 (0x3 << 9) | 111 | #define CLK_HCLK_PLL_PREDIV_4 (0x3 << 9) |
112 | #define CLK_HCLK_PLL_PREDIV_3 (0x2 << 9) | 112 | #define CLK_HCLK_PLL_PREDIV_3 (0x2 << 9) |
113 | #define CLK_HCLK_PLL_PREDIV_2 (0x1 << 9) | 113 | #define CLK_HCLK_PLL_PREDIV_2 (0x1 << 9) |
114 | #define CLK_HCLK_PLL_PREDIV_1 (0x0 << 9) | 114 | #define CLK_HCLK_PLL_PREDIV_1 (0x0 << 9) |
115 | #define CLK_HCLK_PLL_FEEDBACK_DIV_MASK (0xFF << 1) | 115 | #define CLK_HCLK_PLL_FEEDBACK_DIV_MASK (0xFF << 1) |
116 | #define CLK_HCLK_PLL_FEEDBACK_DIV(n) ((((n) - 1) & 0xFF) << 1) | 116 | #define CLK_HCLK_PLL_FEEDBACK_DIV(n) ((((n) - 1) & 0xFF) << 1) |
117 | #define CLK_HCLK_PLL_LOCKED (1 << 0) | 117 | #define CLK_HCLK_PLL_LOCKED (1 << 0) |
118 | 118 | ||
119 | /* Ethernet MAC Clock Control Register bits */ | 119 | /* Ethernet MAC Clock Control Register bits */ |
120 | #define CLK_MAC_RMII (0x3 << 3) | 120 | #define CLK_MAC_RMII (0x3 << 3) |
121 | #define CLK_MAC_MII (0x1 << 3) | 121 | #define CLK_MAC_MII (0x1 << 3) |
122 | #define CLK_MAC_MASTER (1 << 2) | 122 | #define CLK_MAC_MASTER (1 << 2) |
123 | #define CLK_MAC_SLAVE (1 << 1) | 123 | #define CLK_MAC_SLAVE (1 << 1) |
124 | #define CLK_MAC_REG (1 << 0) | 124 | #define CLK_MAC_REG (1 << 0) |
125 | 125 | ||
126 | /* Timer Clock Control1 Register bits */ | 126 | /* Timer Clock Control1 Register bits */ |
127 | #define CLK_TIMCLK_MOTOR (1 << 6) | 127 | #define CLK_TIMCLK_MOTOR (1 << 6) |
128 | #define CLK_TIMCLK_TIMER3 (1 << 5) | 128 | #define CLK_TIMCLK_TIMER3 (1 << 5) |
129 | #define CLK_TIMCLK_TIMER2 (1 << 4) | 129 | #define CLK_TIMCLK_TIMER2 (1 << 4) |
130 | #define CLK_TIMCLK_TIMER1 (1 << 3) | 130 | #define CLK_TIMCLK_TIMER1 (1 << 3) |
131 | #define CLK_TIMCLK_TIMER0 (1 << 2) | 131 | #define CLK_TIMCLK_TIMER0 (1 << 2) |
132 | #define CLK_TIMCLK_TIMER5 (1 << 1) | 132 | #define CLK_TIMCLK_TIMER5 (1 << 1) |
133 | #define CLK_TIMCLK_TIMER4 (1 << 0) | 133 | #define CLK_TIMCLK_TIMER4 (1 << 0) |
134 | 134 | ||
135 | /* Timer Clock Control Register bits */ | 135 | /* Timer Clock Control Register bits */ |
136 | #define CLK_TIMCLK_HSTIMER (1 << 1) | 136 | #define CLK_TIMCLK_HSTIMER (1 << 1) |
137 | #define CLK_TIMCLK_WATCHDOG (1 << 0) | 137 | #define CLK_TIMCLK_WATCHDOG (1 << 0) |
138 | 138 | ||
139 | /* UART Clock Control Register bits */ | 139 | /* UART Clock Control Register bits */ |
140 | #define CLK_UART(n) (1 << ((n) - 3)) | 140 | #define CLK_UART(n) (1 << ((n) - 3)) |
141 | 141 | ||
142 | /* UARTn Clock Select Registers bits */ | 142 | /* UARTn Clock Select Registers bits */ |
143 | #define CLK_UART_HCLK (1 << 16) | 143 | #define CLK_UART_HCLK (1 << 16) |
144 | #define CLK_UART_X_DIV(n) (((n) & 0xFF) << 8) | 144 | #define CLK_UART_X_DIV(n) (((n) & 0xFF) << 8) |
145 | #define CLK_UART_Y_DIV(n) (((n) & 0xFF) << 0) | 145 | #define CLK_UART_Y_DIV(n) (((n) & 0xFF) << 0) |
146 | 146 | ||
147 | /* DMA Clock Control Register bits */ | 147 | /* DMA Clock Control Register bits */ |
148 | #define CLK_DMA_ENABLE (1 << 0) | 148 | #define CLK_DMA_ENABLE (1 << 0) |
149 | 149 | ||
150 | /* NAND Clock Control Register bits */ | ||
151 | #define CLK_NAND_MLC (1 << 1) | ||
152 | #define CLK_NAND_MLC_INT (1 << 5) | ||
153 | |||
150 | unsigned int get_sys_clk_rate(void); | 154 | unsigned int get_sys_clk_rate(void); |
151 | unsigned int get_hclk_pll_rate(void); | 155 | unsigned int get_hclk_pll_rate(void); |
152 | unsigned int get_hclk_clk_div(void); | 156 | unsigned int get_hclk_clk_div(void); |
153 | unsigned int get_hclk_clk_rate(void); | 157 | unsigned int get_hclk_clk_rate(void); |
154 | unsigned int get_periph_clk_div(void); | 158 | unsigned int get_periph_clk_div(void); |
155 | unsigned int get_periph_clk_rate(void); | 159 | unsigned int get_periph_clk_rate(void); |
156 | 160 | ||
157 | #endif /* _LPC32XX_CLK_H */ | 161 | #endif /* _LPC32XX_CLK_H */ |
158 | 162 |
arch/arm/include/asm/arch-lpc32xx/sys_proto.h
1 | /* | 1 | /* |
2 | * Copyright (C) 2011 Vladimir Zapolskiy <vz@mleia.com> | 2 | * Copyright (C) 2011 Vladimir Zapolskiy <vz@mleia.com> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef _LPC32XX_SYS_PROTO_H | 7 | #ifndef _LPC32XX_SYS_PROTO_H |
8 | #define _LPC32XX_SYS_PROTO_H | 8 | #define _LPC32XX_SYS_PROTO_H |
9 | 9 | ||
10 | void lpc32xx_uart_init(unsigned int uart_id); | 10 | void lpc32xx_uart_init(unsigned int uart_id); |
11 | void lpc32xx_mac_init(void); | 11 | void lpc32xx_mac_init(void); |
12 | void lpc32xx_mlc_nand_init(void); | ||
12 | 13 | ||
13 | #endif /* _LPC32XX_SYS_PROTO_H */ | 14 | #endif /* _LPC32XX_SYS_PROTO_H */ |
14 | 15 |
drivers/mtd/nand/Makefile
1 | # | 1 | # |
2 | # (C) Copyright 2006 | 2 | # (C) Copyright 2006 |
3 | # Wolfgang Denk, DENX Software Engineering, wd@denx.de. | 3 | # Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
4 | # | 4 | # |
5 | # SPDX-License-Identifier: GPL-2.0+ | 5 | # SPDX-License-Identifier: GPL-2.0+ |
6 | # | 6 | # |
7 | 7 | ||
8 | ifdef CONFIG_SPL_BUILD | 8 | ifdef CONFIG_SPL_BUILD |
9 | 9 | ||
10 | ifdef CONFIG_SPL_NAND_DRIVERS | 10 | ifdef CONFIG_SPL_NAND_DRIVERS |
11 | NORMAL_DRIVERS=y | 11 | NORMAL_DRIVERS=y |
12 | endif | 12 | endif |
13 | 13 | ||
14 | obj-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o | 14 | obj-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o |
15 | obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o | 15 | obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o |
16 | obj-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o | 16 | obj-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o |
17 | obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o | 17 | obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o |
18 | obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o | 18 | obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o |
19 | obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o | 19 | obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o |
20 | obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o | 20 | obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o |
21 | obj-$(CONFIG_SPL_NAND_INIT) += nand.o | 21 | obj-$(CONFIG_SPL_NAND_INIT) += nand.o |
22 | ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) | 22 | ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) |
23 | obj-$(CONFIG_ENV_IS_IN_NAND) += nand_util.o | 23 | obj-$(CONFIG_ENV_IS_IN_NAND) += nand_util.o |
24 | endif | 24 | endif |
25 | 25 | ||
26 | else # not spl | 26 | else # not spl |
27 | 27 | ||
28 | NORMAL_DRIVERS=y | 28 | NORMAL_DRIVERS=y |
29 | 29 | ||
30 | obj-y += nand.o | 30 | obj-y += nand.o |
31 | obj-y += nand_bbt.o | 31 | obj-y += nand_bbt.o |
32 | obj-y += nand_ids.o | 32 | obj-y += nand_ids.o |
33 | obj-y += nand_util.o | 33 | obj-y += nand_util.o |
34 | obj-y += nand_ecc.o | 34 | obj-y += nand_ecc.o |
35 | obj-y += nand_base.o | 35 | obj-y += nand_base.o |
36 | 36 | ||
37 | endif # not spl | 37 | endif # not spl |
38 | 38 | ||
39 | ifdef NORMAL_DRIVERS | 39 | ifdef NORMAL_DRIVERS |
40 | 40 | ||
41 | obj-$(CONFIG_NAND_ECC_BCH) += nand_bch.o | 41 | obj-$(CONFIG_NAND_ECC_BCH) += nand_bch.o |
42 | 42 | ||
43 | obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o | 43 | obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o |
44 | obj-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o | 44 | obj-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o |
45 | obj-$(CONFIG_NAND_DAVINCI) += davinci_nand.o | 45 | obj-$(CONFIG_NAND_DAVINCI) += davinci_nand.o |
46 | obj-$(CONFIG_NAND_DENALI) += denali.o | 46 | obj-$(CONFIG_NAND_DENALI) += denali.o |
47 | obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o | 47 | obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o |
48 | obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o | 48 | obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o |
49 | obj-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o | 49 | obj-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o |
50 | obj-$(CONFIG_NAND_FSMC) += fsmc_nand.o | 50 | obj-$(CONFIG_NAND_FSMC) += fsmc_nand.o |
51 | obj-$(CONFIG_NAND_JZ4740) += jz4740_nand.o | 51 | obj-$(CONFIG_NAND_JZ4740) += jz4740_nand.o |
52 | obj-$(CONFIG_NAND_KB9202) += kb9202_nand.o | 52 | obj-$(CONFIG_NAND_KB9202) += kb9202_nand.o |
53 | obj-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o | 53 | obj-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o |
54 | obj-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o | 54 | obj-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o |
55 | obj-$(CONFIG_NAND_LPC32XX_MLC) += lpc32xx_nand_mlc.o | ||
55 | obj-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o | 56 | obj-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o |
56 | obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o | 57 | obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o |
57 | obj-$(CONFIG_NAND_MXC) += mxc_nand.o | 58 | obj-$(CONFIG_NAND_MXC) += mxc_nand.o |
58 | obj-$(CONFIG_NAND_MXS) += mxs_nand.o | 59 | obj-$(CONFIG_NAND_MXS) += mxs_nand.o |
59 | obj-$(CONFIG_NAND_NDFC) += ndfc.o | 60 | obj-$(CONFIG_NAND_NDFC) += ndfc.o |
60 | obj-$(CONFIG_NAND_NOMADIK) += nomadik.o | 61 | obj-$(CONFIG_NAND_NOMADIK) += nomadik.o |
61 | obj-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o | 62 | obj-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o |
62 | obj-$(CONFIG_NAND_SPEAR) += spr_nand.o | 63 | obj-$(CONFIG_NAND_SPEAR) += spr_nand.o |
63 | obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o | 64 | obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o |
64 | obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o | 65 | obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o |
65 | obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o | 66 | obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o |
66 | obj-$(CONFIG_NAND_PLAT) += nand_plat.o | 67 | obj-$(CONFIG_NAND_PLAT) += nand_plat.o |
67 | obj-$(CONFIG_NAND_DOCG4) += docg4.o | 68 | obj-$(CONFIG_NAND_DOCG4) += docg4.o |
68 | 69 | ||
69 | else # minimal SPL drivers | 70 | else # minimal SPL drivers |
70 | 71 | ||
71 | obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o | 72 | obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o |
72 | obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o | 73 | obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o |
73 | obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o | 74 | obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o |
74 | obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o | 75 | obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o |
75 | 76 | ||
76 | endif # drivers | 77 | endif # drivers |
77 | 78 |
drivers/mtd/nand/lpc32xx_nand_mlc.c
File was created | 1 | /* | |
2 | * LPC32xx MLC NAND flash controller driver | ||
3 | * | ||
4 | * (C) Copyright 2014 3ADEV <http://3adev.com> | ||
5 | * Written by Albert ARIBAUD <albert.aribaud@3adev.fr> | ||
6 | * | ||
7 | * SPDX-License-Identifier: GPL-2.0+ | ||
8 | * | ||
9 | * NOTE: | ||
10 | * | ||
11 | * The MLC NAND flash controller provides hardware Reed-Solomon ECC | ||
12 | * covering in- and out-of-band data together. Therefore, in- and out- | ||
13 | * of-band data must be written together in order to have a valid ECC. | ||
14 | * | ||
15 | * Consequently, pages with meaningful in-band data are written with | ||
16 | * blank (all-ones) out-of-band data and a valid ECC, and any later | ||
17 | * out-of-band data write will void the ECC. | ||
18 | * | ||
19 | * Therefore, code which reads such late-written out-of-band data | ||
20 | * should not rely on the ECC validity. | ||
21 | */ | ||
22 | |||
23 | #include <common.h> | ||
24 | #include <nand.h> | ||
25 | #include <asm/errno.h> | ||
26 | #include <asm/io.h> | ||
27 | #include <nand.h> | ||
28 | #include <asm/arch/clk.h> | ||
29 | #include <asm/arch/sys_proto.h> | ||
30 | |||
31 | /* | ||
32 | * MLC NAND controller registers. | ||
33 | */ | ||
34 | struct lpc32xx_nand_mlc_registers { | ||
35 | u8 buff[32768]; /* controller's serial data buffer */ | ||
36 | u8 data[32768]; /* NAND's raw data buffer */ | ||
37 | u32 cmd; | ||
38 | u32 addr; | ||
39 | u32 ecc_enc_reg; | ||
40 | u32 ecc_dec_reg; | ||
41 | u32 ecc_auto_enc_reg; | ||
42 | u32 ecc_auto_dec_reg; | ||
43 | u32 rpr; | ||
44 | u32 wpr; | ||
45 | u32 rubp; | ||
46 | u32 robp; | ||
47 | u32 sw_wp_add_low; | ||
48 | u32 sw_wp_add_hig; | ||
49 | u32 icr; | ||
50 | u32 time_reg; | ||
51 | u32 irq_mr; | ||
52 | u32 irq_sr; | ||
53 | u32 lock_pr; | ||
54 | u32 isr; | ||
55 | u32 ceh; | ||
56 | }; | ||
57 | |||
58 | /* LOCK_PR register defines */ | ||
59 | #define LOCK_PR_UNLOCK_KEY 0x0000A25E /* Magic unlock value */ | ||
60 | |||
61 | /* ICR defines */ | ||
62 | #define ICR_LARGE_BLOCKS 0x00000004 /* configure for 2KB blocks */ | ||
63 | #define ICR_ADDR4 0x00000002 /* configure for 4-word addrs */ | ||
64 | |||
65 | /* CEH defines */ | ||
66 | #define CEH_NORMAL_CE 0x00000001 /* do not force CE ON */ | ||
67 | |||
68 | /* ISR register defines */ | ||
69 | #define ISR_NAND_READY 0x00000001 | ||
70 | #define ISR_CONTROLLER_READY 0x00000002 | ||
71 | #define ISR_ECC_READY 0x00000004 | ||
72 | #define ISR_DECODER_ERRORS(s) ((((s) >> 4) & 3)+1) | ||
73 | #define ISR_DECODER_FAILURE 0x00000040 | ||
74 | #define ISR_DECODER_ERROR 0x00000008 | ||
75 | |||
76 | /* time-out for NAND chip / controller loops, in us */ | ||
77 | #define LPC32X_NAND_TIMEOUT 5000 | ||
78 | |||
79 | /* | ||
80 | * There is a single instance of the NAND MLC controller | ||
81 | */ | ||
82 | |||
83 | static struct lpc32xx_nand_mlc_registers __iomem *lpc32xx_nand_mlc_registers | ||
84 | = (struct lpc32xx_nand_mlc_registers __iomem *)MLC_NAND_BASE; | ||
85 | |||
86 | #define clkdiv(v, w, o) (((1+(clk/v)) & w) << o) | ||
87 | |||
88 | /** | ||
89 | * OOB data in each small page are 6 'free' then 10 ECC bytes. | ||
90 | * To make things easier, when reading large pages, the four pages' | ||
91 | * 'free' OOB bytes are grouped in the first 24 bytes of the OOB buffer, | ||
92 | * while the the four ECC bytes are groupe in its last 40 bytes. | ||
93 | * | ||
94 | * The struct below represents how free vs ecc oob bytes are stored | ||
95 | * in the buffer. | ||
96 | * | ||
97 | * Note: the OOB bytes contain the bad block marker at offsets 0 and 1. | ||
98 | */ | ||
99 | |||
100 | struct lpc32xx_oob { | ||
101 | struct { | ||
102 | uint8_t free_oob_bytes[6]; | ||
103 | } free[4]; | ||
104 | struct { | ||
105 | uint8_t ecc_oob_bytes[10]; | ||
106 | } ecc[4]; | ||
107 | }; | ||
108 | |||
109 | /* | ||
110 | * Initialize the controller | ||
111 | */ | ||
112 | |||
113 | static void lpc32xx_nand_init(void) | ||
114 | { | ||
115 | unsigned int clk; | ||
116 | |||
117 | /* Configure controller for no software write protection, x8 bus | ||
118 | width, large block device, and 4 address words */ | ||
119 | |||
120 | /* unlock controller registers with magic key */ | ||
121 | writel(LOCK_PR_UNLOCK_KEY, | ||
122 | &lpc32xx_nand_mlc_registers->lock_pr); | ||
123 | |||
124 | /* enable large blocks and large NANDs */ | ||
125 | writel(ICR_LARGE_BLOCKS | ICR_ADDR4, | ||
126 | &lpc32xx_nand_mlc_registers->icr); | ||
127 | |||
128 | /* Make sure MLC interrupts are disabled */ | ||
129 | writel(0, &lpc32xx_nand_mlc_registers->irq_mr); | ||
130 | |||
131 | /* Normal chip enable operation */ | ||
132 | writel(CEH_NORMAL_CE, | ||
133 | &lpc32xx_nand_mlc_registers->ceh); | ||
134 | |||
135 | /* Setup NAND timing */ | ||
136 | clk = get_hclk_clk_rate(); | ||
137 | |||
138 | writel( | ||
139 | clkdiv(CONFIG_LPC32XX_NAND_MLC_TCEA_DELAY, 0x03, 24) | | ||
140 | clkdiv(CONFIG_LPC32XX_NAND_MLC_BUSY_DELAY, 0x1F, 19) | | ||
141 | clkdiv(CONFIG_LPC32XX_NAND_MLC_NAND_TA, 0x07, 16) | | ||
142 | clkdiv(CONFIG_LPC32XX_NAND_MLC_RD_HIGH, 0x0F, 12) | | ||
143 | clkdiv(CONFIG_LPC32XX_NAND_MLC_RD_LOW, 0x0F, 8) | | ||
144 | clkdiv(CONFIG_LPC32XX_NAND_MLC_WR_HIGH, 0x0F, 4) | | ||
145 | clkdiv(CONFIG_LPC32XX_NAND_MLC_WR_LOW, 0x0F, 0), | ||
146 | &lpc32xx_nand_mlc_registers->time_reg); | ||
147 | } | ||
148 | |||
149 | #if !defined(CONFIG_SPL_BUILD) | ||
150 | |||
151 | /** | ||
152 | * lpc32xx_cmd_ctrl - write command to either cmd or data register | ||
153 | */ | ||
154 | |||
155 | static void lpc32xx_cmd_ctrl(struct mtd_info *mtd, int cmd, | ||
156 | unsigned int ctrl) | ||
157 | { | ||
158 | if (cmd == NAND_CMD_NONE) | ||
159 | return; | ||
160 | |||
161 | if (ctrl & NAND_CLE) | ||
162 | writeb(cmd & 0Xff, &lpc32xx_nand_mlc_registers->cmd); | ||
163 | else if (ctrl & NAND_ALE) | ||
164 | writeb(cmd & 0Xff, &lpc32xx_nand_mlc_registers->addr); | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * lpc32xx_read_byte - read a byte from the NAND | ||
169 | * @mtd: MTD device structure | ||
170 | */ | ||
171 | |||
172 | static uint8_t lpc32xx_read_byte(struct mtd_info *mtd) | ||
173 | { | ||
174 | return readb(&lpc32xx_nand_mlc_registers->data); | ||
175 | } | ||
176 | |||
177 | /** | ||
178 | * lpc32xx_dev_ready - test if NAND device (actually controller) is ready | ||
179 | * @mtd: MTD device structure | ||
180 | * @mode: mode to set the ECC HW to. | ||
181 | */ | ||
182 | |||
183 | static int lpc32xx_dev_ready(struct mtd_info *mtd) | ||
184 | { | ||
185 | /* means *controller* ready for us */ | ||
186 | int status = readl(&lpc32xx_nand_mlc_registers->isr); | ||
187 | return status & ISR_CONTROLLER_READY; | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * ECC layout -- this is needed whatever ECC mode we are using. | ||
192 | * In a 2KB (4*512B) page, R/S codes occupy 40 (4*10) bytes. | ||
193 | * To make U-Boot's life easier, we pack 'useable' OOB at the | ||
194 | * front and R/S ECC at the back. | ||
195 | */ | ||
196 | |||
197 | static struct nand_ecclayout lpc32xx_largepage_ecclayout = { | ||
198 | .eccbytes = 40, | ||
199 | .eccpos = {24, 25, 26, 27, 28, 29, 30, 31, 32, 33, | ||
200 | 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, | ||
201 | 44, 45, 46, 47, 48, 48, 50, 51, 52, 53, | ||
202 | 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, | ||
203 | }, | ||
204 | .oobfree = { | ||
205 | /* bytes 0 and 1 are used for the bad block marker */ | ||
206 | { | ||
207 | .offset = 2, | ||
208 | .length = 22 | ||
209 | }, | ||
210 | } | ||
211 | }; | ||
212 | |||
213 | /** | ||
214 | * lpc32xx_read_page_hwecc - read in- and out-of-band data with ECC | ||
215 | * @mtd: mtd info structure | ||
216 | * @chip: nand chip info structure | ||
217 | * @buf: buffer to store read data | ||
218 | * @oob_required: caller requires OOB data read to chip->oob_poi | ||
219 | * @page: page number to read | ||
220 | * | ||
221 | * Use large block Auto Decode Read Mode(1) as described in User Manual | ||
222 | * section 8.6.2.1. | ||
223 | * | ||
224 | * The initial Read Mode and Read Start commands are sent by the caller. | ||
225 | * | ||
226 | * ECC will be false if out-of-band data has been updated since in-band | ||
227 | * data was initially written. | ||
228 | */ | ||
229 | |||
230 | static int lpc32xx_read_page_hwecc(struct mtd_info *mtd, | ||
231 | struct nand_chip *chip, uint8_t *buf, int oob_required, | ||
232 | int page) | ||
233 | { | ||
234 | unsigned int i, status, timeout, err, max_bitflips = 0; | ||
235 | struct lpc32xx_oob *oob = (struct lpc32xx_oob *)chip->oob_poi; | ||
236 | |||
237 | /* go through all four small pages */ | ||
238 | for (i = 0; i < 4; i++) { | ||
239 | /* start auto decode (reads 528 NAND bytes) */ | ||
240 | writel(0, &lpc32xx_nand_mlc_registers->ecc_auto_dec_reg); | ||
241 | /* wait for controller to return to ready state */ | ||
242 | for (timeout = LPC32X_NAND_TIMEOUT; timeout; timeout--) { | ||
243 | status = readl(&lpc32xx_nand_mlc_registers->isr); | ||
244 | if (status & ISR_CONTROLLER_READY) | ||
245 | break; | ||
246 | udelay(1); | ||
247 | } | ||
248 | /* if decoder failed, return failure */ | ||
249 | if (status & ISR_DECODER_FAILURE) | ||
250 | return -1; | ||
251 | /* keep count of maximum bitflips performed */ | ||
252 | if (status & ISR_DECODER_ERROR) { | ||
253 | err = ISR_DECODER_ERRORS(status); | ||
254 | if (err > max_bitflips) | ||
255 | max_bitflips = err; | ||
256 | } | ||
257 | /* copy first 512 bytes into buffer */ | ||
258 | memcpy(buf+512*i, lpc32xx_nand_mlc_registers->buff, 512); | ||
259 | /* copy next 6 bytes at front of OOB buffer */ | ||
260 | memcpy(&oob->free[i], lpc32xx_nand_mlc_registers->buff, 6); | ||
261 | /* copy last 10 bytes (R/S ECC) at back of OOB buffer */ | ||
262 | memcpy(&oob->ecc[i], lpc32xx_nand_mlc_registers->buff, 10); | ||
263 | } | ||
264 | return max_bitflips; | ||
265 | } | ||
266 | |||
267 | /** | ||
268 | * lpc32xx_read_page_raw - read raw (in-band, out-of-band and ECC) data | ||
269 | * @mtd: mtd info structure | ||
270 | * @chip: nand chip info structure | ||
271 | * @buf: buffer to store read data | ||
272 | * @oob_required: caller requires OOB data read to chip->oob_poi | ||
273 | * @page: page number to read | ||
274 | * | ||
275 | * Read NAND directly; can read pages with invalid ECC. | ||
276 | */ | ||
277 | |||
278 | static int lpc32xx_read_page_raw(struct mtd_info *mtd, | ||
279 | struct nand_chip *chip, uint8_t *buf, int oob_required, | ||
280 | int page) | ||
281 | { | ||
282 | unsigned int i, status, timeout; | ||
283 | struct lpc32xx_oob *oob = (struct lpc32xx_oob *)chip->oob_poi; | ||
284 | |||
285 | /* when we get here we've already had the Read Mode(1) */ | ||
286 | |||
287 | /* go through all four small pages */ | ||
288 | for (i = 0; i < 4; i++) { | ||
289 | /* wait for NAND to return to ready state */ | ||
290 | for (timeout = LPC32X_NAND_TIMEOUT; timeout; timeout--) { | ||
291 | status = readl(&lpc32xx_nand_mlc_registers->isr); | ||
292 | if (status & ISR_NAND_READY) | ||
293 | break; | ||
294 | udelay(1); | ||
295 | } | ||
296 | /* if NAND stalled, return failure */ | ||
297 | if (!(status & ISR_NAND_READY)) | ||
298 | return -1; | ||
299 | /* copy first 512 bytes into buffer */ | ||
300 | memcpy(buf+512*i, lpc32xx_nand_mlc_registers->data, 512); | ||
301 | /* copy next 6 bytes at front of OOB buffer */ | ||
302 | memcpy(&oob->free[i], lpc32xx_nand_mlc_registers->data, 6); | ||
303 | /* copy last 10 bytes (R/S ECC) at back of OOB buffer */ | ||
304 | memcpy(&oob->ecc[i], lpc32xx_nand_mlc_registers->data, 10); | ||
305 | } | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | /** | ||
310 | * lpc32xx_read_oob - read out-of-band data | ||
311 | * @mtd: mtd info structure | ||
312 | * @chip: nand chip info structure | ||
313 | * @page: page number to read | ||
314 | * | ||
315 | * Read out-of-band data. User Manual section 8.6.4 suggests using Read | ||
316 | * Mode(3) which the controller will turn into a Read Mode(1) internally | ||
317 | * but nand_base.c will turn Mode(3) into Mode(0), so let's use Mode(0) | ||
318 | * directly. | ||
319 | * | ||
320 | * ECC covers in- and out-of-band data and was written when out-of-band | ||
321 | * data was blank. Therefore, if the out-of-band being read here is not | ||
322 | * blank, then the ECC will be false and the read will return bitflips, | ||
323 | * even in case of ECC failure where we will return 5 bitflips. The | ||
324 | * caller should be prepared to handle this. | ||
325 | */ | ||
326 | |||
327 | static int lpc32xx_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | ||
328 | int page) | ||
329 | { | ||
330 | unsigned int i, status, timeout, err, max_bitflips = 0; | ||
331 | struct lpc32xx_oob *oob = (struct lpc32xx_oob *)chip->oob_poi; | ||
332 | |||
333 | /* No command was sent before calling read_oob() so send one */ | ||
334 | |||
335 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); | ||
336 | |||
337 | /* go through all four small pages */ | ||
338 | for (i = 0; i < 4; i++) { | ||
339 | /* start auto decode (reads 528 NAND bytes) */ | ||
340 | writel(0, &lpc32xx_nand_mlc_registers->ecc_auto_dec_reg); | ||
341 | /* wait for controller to return to ready state */ | ||
342 | for (timeout = LPC32X_NAND_TIMEOUT; timeout; timeout--) { | ||
343 | status = readl(&lpc32xx_nand_mlc_registers->isr); | ||
344 | if (status & ISR_CONTROLLER_READY) | ||
345 | break; | ||
346 | udelay(1); | ||
347 | } | ||
348 | /* if decoder failure, count 'one too many' bitflips */ | ||
349 | if (status & ISR_DECODER_FAILURE) | ||
350 | max_bitflips = 5; | ||
351 | /* keep count of maximum bitflips performed */ | ||
352 | if (status & ISR_DECODER_ERROR) { | ||
353 | err = ISR_DECODER_ERRORS(status); | ||
354 | if (err > max_bitflips) | ||
355 | max_bitflips = err; | ||
356 | } | ||
357 | /* set read pointer to OOB area */ | ||
358 | writel(0, &lpc32xx_nand_mlc_registers->robp); | ||
359 | /* copy next 6 bytes at front of OOB buffer */ | ||
360 | memcpy(&oob->free[i], lpc32xx_nand_mlc_registers->buff, 6); | ||
361 | /* copy next 10 bytes (R/S ECC) at back of OOB buffer */ | ||
362 | memcpy(&oob->ecc[i], lpc32xx_nand_mlc_registers->buff, 10); | ||
363 | } | ||
364 | return max_bitflips; | ||
365 | } | ||
366 | |||
367 | /** | ||
368 | * lpc32xx_write_page_hwecc - write in- and out-of-band data with ECC | ||
369 | * @mtd: mtd info structure | ||
370 | * @chip: nand chip info structure | ||
371 | * @buf: data buffer | ||
372 | * @oob_required: must write chip->oob_poi to OOB | ||
373 | * | ||
374 | * Use large block Auto Encode as per User Manual section 8.6.4. | ||
375 | * | ||
376 | * The initial Write Serial Input and final Auto Program commands are | ||
377 | * sent by the caller. | ||
378 | */ | ||
379 | |||
380 | static int lpc32xx_write_page_hwecc(struct mtd_info *mtd, | ||
381 | struct nand_chip *chip, const uint8_t *buf, int oob_required) | ||
382 | { | ||
383 | unsigned int i, status, timeout; | ||
384 | struct lpc32xx_oob *oob = (struct lpc32xx_oob *)chip->oob_poi; | ||
385 | |||
386 | /* when we get here we've already had the SEQIN */ | ||
387 | for (i = 0; i < 4; i++) { | ||
388 | /* start encode (expects 518 writes to buff) */ | ||
389 | writel(0, &lpc32xx_nand_mlc_registers->ecc_enc_reg); | ||
390 | /* copy first 512 bytes from buffer */ | ||
391 | memcpy(&lpc32xx_nand_mlc_registers->buff, buf+512*i, 512); | ||
392 | /* copy next 6 bytes from OOB buffer -- excluding ECC */ | ||
393 | memcpy(&lpc32xx_nand_mlc_registers->buff, &oob->free[i], 6); | ||
394 | /* wait for ECC to return to ready state */ | ||
395 | for (timeout = LPC32X_NAND_TIMEOUT; timeout; timeout--) { | ||
396 | status = readl(&lpc32xx_nand_mlc_registers->isr); | ||
397 | if (status & ISR_ECC_READY) | ||
398 | break; | ||
399 | udelay(1); | ||
400 | } | ||
401 | /* if ECC stalled, return failure */ | ||
402 | if (!(status & ISR_ECC_READY)) | ||
403 | return -1; | ||
404 | /* Trigger auto encode (writes 528 bytes to NAND) */ | ||
405 | writel(0, &lpc32xx_nand_mlc_registers->ecc_auto_enc_reg); | ||
406 | /* wait for controller to return to ready state */ | ||
407 | for (timeout = LPC32X_NAND_TIMEOUT; timeout; timeout--) { | ||
408 | status = readl(&lpc32xx_nand_mlc_registers->isr); | ||
409 | if (status & ISR_CONTROLLER_READY) | ||
410 | break; | ||
411 | udelay(1); | ||
412 | } | ||
413 | /* if controller stalled, return error */ | ||
414 | if (!(status & ISR_CONTROLLER_READY)) | ||
415 | return -1; | ||
416 | } | ||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * lpc32xx_write_page_raw - write raw (in-band, out-of-band and ECC) data | ||
422 | * @mtd: mtd info structure | ||
423 | * @chip: nand chip info structure | ||
424 | * @buf: buffer to store read data | ||
425 | * @oob_required: caller requires OOB data read to chip->oob_poi | ||
426 | * @page: page number to read | ||
427 | * | ||
428 | * Use large block write but without encode. | ||
429 | * | ||
430 | * The initial Write Serial Input and final Auto Program commands are | ||
431 | * sent by the caller. | ||
432 | * | ||
433 | * This function will write the full out-of-band data, including the | ||
434 | * ECC area. Therefore, it can write pages with valid *or* invalid ECC. | ||
435 | */ | ||
436 | |||
437 | static int lpc32xx_write_page_raw(struct mtd_info *mtd, | ||
438 | struct nand_chip *chip, const uint8_t *buf, int oob_required) | ||
439 | { | ||
440 | unsigned int i; | ||
441 | struct lpc32xx_oob *oob = (struct lpc32xx_oob *)chip->oob_poi; | ||
442 | |||
443 | /* when we get here we've already had the Read Mode(1) */ | ||
444 | for (i = 0; i < 4; i++) { | ||
445 | /* copy first 512 bytes from buffer */ | ||
446 | memcpy(lpc32xx_nand_mlc_registers->buff, buf+512*i, 512); | ||
447 | /* copy next 6 bytes into OOB buffer -- excluding ECC */ | ||
448 | memcpy(lpc32xx_nand_mlc_registers->buff, &oob->free[i], 6); | ||
449 | /* copy next 10 bytes into OOB buffer -- that is 'ECC' */ | ||
450 | memcpy(lpc32xx_nand_mlc_registers->buff, &oob->ecc[i], 10); | ||
451 | } | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | /** | ||
456 | * lpc32xx_write_oob - write out-of-band data | ||
457 | * @mtd: mtd info structure | ||
458 | * @chip: nand chip info structure | ||
459 | * @page: page number to read | ||
460 | * | ||
461 | * Since ECC covers in- and out-of-band data, writing out-of-band data | ||
462 | * with ECC will render the page ECC wrong -- or, if the page was blank, | ||
463 | * then it will produce a good ECC but a later in-band data write will | ||
464 | * render it wrong. | ||
465 | * | ||
466 | * Therefore, do not compute or write any ECC, and always return success. | ||
467 | * | ||
468 | * This implies that we do four writes, since non-ECC out-of-band data | ||
469 | * are not contiguous in a large page. | ||
470 | */ | ||
471 | |||
472 | static int lpc32xx_write_oob(struct mtd_info *mtd, struct nand_chip *chip, | ||
473 | int page) | ||
474 | { | ||
475 | /* update oob on all 4 subpages in sequence */ | ||
476 | unsigned int i, status, timeout; | ||
477 | struct lpc32xx_oob *oob = (struct lpc32xx_oob *)chip->oob_poi; | ||
478 | |||
479 | for (i = 0; i < 4; i++) { | ||
480 | /* start data input */ | ||
481 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x200+0x210*i, page); | ||
482 | /* copy 6 non-ECC out-of-band bytes directly into NAND */ | ||
483 | memcpy(lpc32xx_nand_mlc_registers->data, &oob->free[i], 6); | ||
484 | /* program page */ | ||
485 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | ||
486 | /* wait for NAND to return to ready state */ | ||
487 | for (timeout = LPC32X_NAND_TIMEOUT; timeout; timeout--) { | ||
488 | status = readl(&lpc32xx_nand_mlc_registers->isr); | ||
489 | if (status & ISR_NAND_READY) | ||
490 | break; | ||
491 | udelay(1); | ||
492 | } | ||
493 | /* if NAND stalled, return error */ | ||
494 | if (!(status & ISR_NAND_READY)) | ||
495 | return -1; | ||
496 | } | ||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | /** | ||
501 | * lpc32xx_waitfunc - wait until a command is done | ||
502 | * @mtd: MTD device structure | ||
503 | * @chip: NAND chip structure | ||
504 | * | ||
505 | * Wait for controller and FLASH to both be ready. | ||
506 | */ | ||
507 | |||
508 | static int lpc32xx_waitfunc(struct mtd_info *mtd, struct nand_chip *chip) | ||
509 | { | ||
510 | int status; | ||
511 | unsigned int timeout; | ||
512 | /* wait until both controller and NAND are ready */ | ||
513 | for (timeout = LPC32X_NAND_TIMEOUT; timeout; timeout--) { | ||
514 | status = readl(&lpc32xx_nand_mlc_registers->isr); | ||
515 | if ((status & (ISR_CONTROLLER_READY || ISR_NAND_READY)) | ||
516 | == (ISR_CONTROLLER_READY || ISR_NAND_READY)) | ||
517 | break; | ||
518 | udelay(1); | ||
519 | } | ||
520 | /* if controller or NAND stalled, return error */ | ||
521 | if ((status & (ISR_CONTROLLER_READY || ISR_NAND_READY)) | ||
522 | != (ISR_CONTROLLER_READY || ISR_NAND_READY)) | ||
523 | return -1; | ||
524 | /* write NAND status command */ | ||
525 | writel(NAND_CMD_STATUS, &lpc32xx_nand_mlc_registers->cmd); | ||
526 | /* read back status and return it */ | ||
527 | return readb(&lpc32xx_nand_mlc_registers->data); | ||
528 | } | ||
529 | |||
530 | /* | ||
531 | * We are self-initializing, so we need our own chip struct | ||
532 | */ | ||
533 | |||
534 | static struct nand_chip lpc32xx_chip; | ||
535 | |||
536 | /* | ||
537 | * Initialize the controller | ||
538 | */ | ||
539 | |||
540 | void board_nand_init(void) | ||
541 | { | ||
542 | /* we have only one device anyway */ | ||
543 | struct mtd_info *mtd = &nand_info[0]; | ||
544 | /* chip is struct nand_chip, and is now provided by the driver. */ | ||
545 | mtd->priv = &lpc32xx_chip; | ||
546 | /* to store return status in case we need to print it */ | ||
547 | int ret; | ||
548 | |||
549 | /* Set all BOARDSPECIFIC (actually core-specific) fields */ | ||
550 | |||
551 | lpc32xx_chip.IO_ADDR_R = &lpc32xx_nand_mlc_registers->buff; | ||
552 | lpc32xx_chip.IO_ADDR_W = &lpc32xx_nand_mlc_registers->buff; | ||
553 | lpc32xx_chip.cmd_ctrl = lpc32xx_cmd_ctrl; | ||
554 | /* do not set init_size: nand_base.c will read sizes from chip */ | ||
555 | lpc32xx_chip.dev_ready = lpc32xx_dev_ready; | ||
556 | /* do not set setup_read_retry: this is NAND-chip-specific */ | ||
557 | /* do not set chip_delay: we have dev_ready defined. */ | ||
558 | lpc32xx_chip.options |= NAND_NO_SUBPAGE_WRITE; | ||
559 | |||
560 | /* Set needed ECC fields */ | ||
561 | |||
562 | lpc32xx_chip.ecc.mode = NAND_ECC_HW; | ||
563 | lpc32xx_chip.ecc.layout = &lpc32xx_largepage_ecclayout; | ||
564 | lpc32xx_chip.ecc.size = 512; | ||
565 | lpc32xx_chip.ecc.bytes = 10; | ||
566 | lpc32xx_chip.ecc.strength = 4; | ||
567 | lpc32xx_chip.ecc.read_page = lpc32xx_read_page_hwecc; | ||
568 | lpc32xx_chip.ecc.read_page_raw = lpc32xx_read_page_raw; | ||
569 | lpc32xx_chip.ecc.write_page = lpc32xx_write_page_hwecc; | ||
570 | lpc32xx_chip.ecc.write_page_raw = lpc32xx_write_page_raw; | ||
571 | lpc32xx_chip.ecc.read_oob = lpc32xx_read_oob; | ||
572 | lpc32xx_chip.ecc.write_oob = lpc32xx_write_oob; | ||
573 | lpc32xx_chip.waitfunc = lpc32xx_waitfunc; | ||
574 | |||
575 | lpc32xx_chip.read_byte = lpc32xx_read_byte; /* FIXME: NEEDED? */ | ||
576 | |||
577 | /* BBT options: read from last two pages */ | ||
578 | lpc32xx_chip.bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_LASTBLOCK | ||
579 | | NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | ||
580 | | NAND_BBT_WRITE; | ||
581 | |||
582 | /* Initialize NAND interface */ | ||
583 | lpc32xx_nand_init(); | ||
584 | |||
585 | /* identify chip */ | ||
586 | ret = nand_scan_ident(mtd, CONFIG_SYS_MAX_NAND_CHIPS, NULL); | ||
587 | if (ret) { | ||
588 | error("nand_scan_ident returned %i", ret); | ||
589 | return; | ||
590 | } | ||
591 | |||
592 | /* finish scanning the chip */ | ||
593 | ret = nand_scan_tail(mtd); | ||
594 | if (ret) { | ||
595 | error("nand_scan_tail returned %i", ret); | ||
596 | return; | ||
597 | } | ||
598 | |||
599 | /* chip is good, register it */ | ||
600 | ret = nand_register(0); | ||
601 | if (ret) | ||
602 | error("nand_register returned %i", ret); | ||
603 | } | ||
604 | |||
605 | #else /* defined(CONFIG_SPL_BUILD) */ | ||
606 | |||
607 | void nand_init(void) | ||
608 | { | ||
609 | /* enable NAND controller */ | ||
610 | lpc32xx_mlc_nand_init(); | ||
611 | /* initialize NAND controller */ | ||
612 | lpc32xx_nand_init(); | ||
613 | } | ||
614 | |||
615 | void nand_deselect(void) | ||
616 | { | ||
617 | /* nothing to do, but SPL requires this function */ | ||
618 | } | ||
619 | |||
620 | static int read_single_page(uint8_t *dest, int page, | ||
621 | struct lpc32xx_oob *oob) | ||
622 | { | ||
623 | int status, i, timeout, err, max_bitflips = 0; | ||
624 | |||
625 | /* enter read mode */ | ||
626 | writel(NAND_CMD_READ0, &lpc32xx_nand_mlc_registers->cmd); | ||
627 | /* send column (lsb then MSB) and page (lsb to MSB) */ | ||
628 | writel(0, &lpc32xx_nand_mlc_registers->addr); | ||
629 | writel(0, &lpc32xx_nand_mlc_registers->addr); | ||
630 | writel(page & 0xff, &lpc32xx_nand_mlc_registers->addr); | ||
631 | writel((page>>8) & 0xff, &lpc32xx_nand_mlc_registers->addr); | ||
632 | writel((page>>16) & 0xff, &lpc32xx_nand_mlc_registers->addr); | ||
633 | /* start reading */ | ||
634 | writel(NAND_CMD_READSTART, &lpc32xx_nand_mlc_registers->cmd); | ||
635 | |||
636 | /* large page auto decode read */ | ||
637 | for (i = 0; i < 4; i++) { | ||
638 | /* start auto decode (reads 528 NAND bytes) */ | ||
639 | writel(0, &lpc32xx_nand_mlc_registers->ecc_auto_dec_reg); | ||
640 | /* wait for controller to return to ready state */ | ||
641 | for (timeout = LPC32X_NAND_TIMEOUT; timeout; timeout--) { | ||
642 | status = readl(&lpc32xx_nand_mlc_registers->isr); | ||
643 | if (status & ISR_CONTROLLER_READY) | ||
644 | break; | ||
645 | udelay(1); | ||
646 | } | ||
647 | /* if controller stalled, return error */ | ||
648 | if (!(status & ISR_CONTROLLER_READY)) | ||
649 | return -1; | ||
650 | /* if decoder failure, return error */ | ||
651 | if (status & ISR_DECODER_FAILURE) | ||
652 | return -1; | ||
653 | /* keep count of maximum bitflips performed */ | ||
654 | if (status & ISR_DECODER_ERROR) { | ||
655 | err = ISR_DECODER_ERRORS(status); | ||
656 | if (err > max_bitflips) | ||
657 | max_bitflips = err; | ||
658 | } | ||
659 | /* copy first 512 bytes into buffer */ | ||
660 | memcpy(dest+i*512, lpc32xx_nand_mlc_registers->buff, 512); | ||
661 | /* copy next 6 bytes bytes into OOB buffer */ | ||
662 | memcpy(&oob->free[i], lpc32xx_nand_mlc_registers->buff, 6); | ||
663 | } | ||
664 | return max_bitflips; | ||
665 | } | ||
666 | |||
667 | /* | ||
668 | * Load U-Boot signed image. | ||
669 | * This loads an image from NAND, skipping bad blocks. | ||
670 | * A block is declared bad if at least one of its readable pages has | ||
671 | * a bad block marker in its OOB at position 0. | ||
672 | * If all pages ion a block are unreadable, the block is considered | ||
673 | * bad (i.e., assumed not to be part of the image) and skipped. | ||
674 | * | ||
675 | * IMPORTANT NOTE: | ||
676 | * | ||
677 | * If the first block of the image is fully unreadable, it will be | ||
678 | * ignored and skipped as if it had been marked bad. If it was not | ||
679 | * actually marked bad at the time of writing the image, the resulting | ||
680 | * image loaded will lack a header and magic number. It could thus be | ||
681 | * considered as a raw, headerless, image and SPL might erroneously | ||
682 | * jump into it. | ||
683 | * | ||
684 | * In order to avoid this risk, LPC32XX-based boards which use this | ||
685 | * driver MUST define CONFIG_SPL_PANIC_ON_RAW_IMAGE. | ||
686 | */ | ||
687 | |||
688 | #define BYTES_PER_PAGE 2048 | ||
689 | #define PAGES_PER_BLOCK 64 | ||
690 | #define BYTES_PER_BLOCK (BYTES_PER_PAGE * PAGES_PER_BLOCK) | ||
691 | #define PAGES_PER_CHIP_MAX 524288 | ||
692 | |||
693 | int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) | ||
694 | { | ||
695 | int bytes_left = size; | ||
696 | int pages_left = DIV_ROUND_UP(size, BYTES_PER_PAGE); | ||
697 | int blocks_left = DIV_ROUND_UP(size, BYTES_PER_BLOCK); | ||
698 | int block = 0; | ||
699 | int page = offs / BYTES_PER_PAGE; | ||
700 | /* perform reads block by block */ | ||
701 | while (blocks_left) { | ||
702 | /* compute first page number to read */ | ||
703 | void *block_page_dst = dst; | ||
704 | /* read at most one block, possibly less */ | ||
705 | int block_bytes_left = bytes_left; | ||
706 | if (block_bytes_left > BYTES_PER_BLOCK) | ||
707 | block_bytes_left = BYTES_PER_BLOCK; | ||
708 | /* keep track of good, failed, and "bad" pages */ | ||
709 | int block_pages_good = 0; | ||
710 | int block_pages_bad = 0; | ||
711 | int block_pages_err = 0; | ||
712 | /* we shall read a full block of pages, maybe less */ | ||
713 | int block_pages_left = pages_left; | ||
714 | if (block_pages_left > PAGES_PER_BLOCK) | ||
715 | block_pages_left = PAGES_PER_BLOCK; | ||
716 | int block_pages = block_pages_left; | ||
717 | int block_page = page; | ||
718 | /* while pages are left and the block is not known as bad */ | ||
719 | while ((block_pages > 0) && (block_pages_bad == 0)) { | ||
720 | /* we will read OOB, too, for bad block markers */ | ||
721 | struct lpc32xx_oob oob; | ||
722 | /* read page */ | ||
723 | int res = read_single_page(block_page_dst, block_page, | ||
724 | &oob); | ||
725 | /* count readable pages */ | ||
726 | if (res >= 0) { | ||
727 | /* this page is good */ | ||
728 | block_pages_good++; | ||
729 | /* this page is bad */ | ||
730 | if ((oob.free[0].free_oob_bytes[0] != 0xff) | ||
731 | | (oob.free[0].free_oob_bytes[1] != 0xff)) | ||
732 | block_pages_bad++; | ||
733 | } else | ||
734 | /* count errors */ | ||
735 | block_pages_err++; | ||
736 | /* we're done with this page */ | ||
737 | block_page++; | ||
738 | block_page_dst += BYTES_PER_PAGE; | ||
739 | if (block_pages) | ||
740 | block_pages--; | ||
741 | } | ||
742 | /* a fully unreadable block is considered bad */ | ||
743 | if (block_pages_good == 0) | ||
744 | block_pages_bad = block_pages_err; | ||
745 | /* errors are fatal only in good blocks */ | ||
746 | if ((block_pages_err > 0) && (block_pages_bad == 0)) | ||
747 | return -1; | ||
748 | /* we keep reads only of good blocks */ | ||
749 | if (block_pages_bad == 0) { | ||
750 | dst += block_bytes_left; | ||
751 | bytes_left -= block_bytes_left; | ||
752 | pages_left -= block_pages_left; | ||
753 | blocks_left--; | ||
754 | } | ||
755 | /* good or bad, we're done with this block */ | ||
756 | block++; | ||
757 | page += PAGES_PER_BLOCK; | ||
758 | } | ||
759 | |||
760 | /* report success */ | ||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | #endif /* CONFIG_SPL_BUILD */ | ||
765 |