Extend LPC32xx functionality and add LPC32xx-based work_92015 board
Subsystems (11)
v6 cover Extend LPC32xx functionality and add LPC32xx-based work_92015 board
This series extends functionality for the LPC32xx platform and introduces the WORK Microwave work_92105 board which makes use of the extended functionality.
NOTES:
A - I2C driver remains non-DM
During v2 review, it was suggested to move to DM for I2C. However, this caused issues with the 'date', 'dtt' and 'eeprom' commands which are configured in this board. Therefore the I2C move to DM was not done.
B - Some checkpatch diagnostics are not fixed
The following warnings checkpatch warnings and checks were not fixed:
1. "warning: arch/arm/Kconfig,135: please write a paragraph that describes the config symbol fully"
Other symbols in the same file have no description either. For consistency, I did not add the requested description.
1. "check: include/configs/work_92105.h,187: spaces required around that ':' (ctx:VxV)
(5 occurrences on the same line)
This is due to the value of CONFIG_ETHADDR not being in quotes. As it never is in any other definition of CONFIG_ETHADDR, I left it unchanged.
Changes in v6:
- added some missing readl() wraps
- moved descriptors and buffers to SRAM
- rewrite timeout loops
- fix bad block skipping in SPL chainload loop
- remove '+S:' prefixes from defconfig
- use custom LPC32XX linker script
- reset peripherals at startup
- support 128MB boards
Changes in v5:
- switch to CONFIG_SYS_NAND_SELF_INIT
- switched board NAND config to CONFIG_SYS_NAND_SELF_INIT
Changes in v4:
- remove two debugging statements
- add __iomem to regs struct
- remove useless 'else return;'
- take BB marker out of free OOB area
- replace magic numbers in OOB reads/writes
- add timeouts in NAND loops
- use DIV_ROUND_UP where applicable
- fix erroneous comment
- skip bad blocks in SPL chainload loop
Changes in v3:
- move DM dependency constraint into Kconfig
- move regs pointer and function cache into private struct
- discourage readers from using functions implementation as an example
- move regs and functions in private struct
- remove script/Makefile.spl change
- use writel() in DRAM initialization code
- remove useless conditionals in dram.c
- fix and complete the board README
- remove redundant CONFIG_CMD_DM from config header file
- add a note re the hard-coded MAC address
- add 'single flashable file' make target
Changes in v2:
- move from legacy to Driver Model support
- added MUX setting for SSP0
- cosmetic: added a blank line before copyright
- move boot image generation to mkimage framework
Albert ARIBAUD (3ADEV) (8):
lpc32xx: add Ethernet support
lpc32xx: mtd: nand: add MLC NAND controller
lpc32xx: i2c: add LPC32xx I2C interface support
lpc32xx: add GPIO support
lpc32xx: add LPC32xx SSP support (SPI mode)
dtt: add ds620 support
lpc32xx: add lpc32xx-spl.bin boot image target
lpc32xx: add support for board work_92105
Makefile | 20 + arch/arm/Kconfig | 6 + arch/arm/cpu/arm926ejs/lpc32xx/Makefile | 2 + arch/arm/cpu/arm926ejs/lpc32xx/clk.c | 34 + arch/arm/cpu/arm926ejs/lpc32xx/cpu.c | 13 + arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 43 ++ arch/arm/cpu/arm926ejs/lpc32xx/dram.c | 79 +++ arch/arm/cpu/arm926ejs/lpc32xx/lowlevel_init.S | 45 ++ arch/arm/cpu/arm926ejs/lpc32xx/u-boot.lds | 161 +++++ arch/arm/include/asm/arch-lpc32xx/clk.h | 16 + arch/arm/include/asm/arch-lpc32xx/config.h | 3 + arch/arm/include/asm/arch-lpc32xx/cpu.h | 3 + arch/arm/include/asm/arch-lpc32xx/gpio.h | 43 ++ arch/arm/include/asm/arch-lpc32xx/mux.h | 18 + arch/arm/include/asm/arch-lpc32xx/sys_proto.h | 8 +- board/work-microwave/work_92105/Kconfig | 15 + board/work-microwave/work_92105/MAINTAINERS | 6 + board/work-microwave/work_92105/Makefile | 10 + board/work-microwave/work_92105/README | 91 +++ board/work-microwave/work_92105/work_92105.c | 77 +++ .../work-microwave/work_92105/work_92105_display.c | 349 ++++++++++ .../work-microwave/work_92105/work_92105_display.h | 14 + board/work-microwave/work_92105/work_92105_spl.c | 33 + common/image.c | 1 + configs/work_92105_defconfig | 6 + drivers/gpio/Kconfig | 7 + drivers/gpio/Makefile | 1 + drivers/gpio/lpc32xx_gpio.c | 293 +++++++++ drivers/hwmon/Makefile | 1 + drivers/hwmon/ds620.c | 65 ++ drivers/i2c/Makefile | 1 + drivers/i2c/lpc32xx_i2c.c | 249 +++++++ drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/lpc32xx_nand_mlc.c | 718 +++++++++++++++++++++ drivers/net/Makefile | 1 + drivers/net/lpc32xx_eth.c | 639 ++++++++++++++++++ drivers/spi/Makefile | 1 + drivers/spi/lpc32xx_ssp.c | 144 +++++ include/configs/work_92105.h | 268 ++++++++ include/dtt.h | 15 +- include/image.h | 1 + include/netdev.h | 1 + tools/Makefile | 1 + tools/lpc32xximage.c | 178 +++++ 44 files changed, 3673 insertions(+), 8 deletions(-) create mode 100644 arch/arm/cpu/arm926ejs/lpc32xx/dram.c create mode 100644 arch/arm/cpu/arm926ejs/lpc32xx/lowlevel_init.S create mode 100644 arch/arm/cpu/arm926ejs/lpc32xx/u-boot.lds create mode 100644 arch/arm/include/asm/arch-lpc32xx/gpio.h create mode 100644 arch/arm/include/asm/arch-lpc32xx/mux.h create mode 100644 board/work-microwave/work_92105/Kconfig create mode 100644 board/work-microwave/work_92105/MAINTAINERS create mode 100644 board/work-microwave/work_92105/Makefile create mode 100644 board/work-microwave/work_92105/README create mode 100644 board/work-microwave/work_92105/work_92105.c create mode 100644 board/work-microwave/work_92105/work_92105_display.c create mode 100644 board/work-microwave/work_92105/work_92105_display.h create mode 100644 board/work-microwave/work_92105/work_92105_spl.c create mode 100644 configs/work_92105_defconfig create mode 100644 drivers/gpio/lpc32xx_gpio.c create mode 100644 drivers/hwmon/ds620.c create mode 100644 drivers/i2c/lpc32xx_i2c.c create mode 100644 drivers/mtd/nand/lpc32xx_nand_mlc.c create mode 100644 drivers/net/lpc32xx_eth.c create mode 100644 drivers/spi/lpc32xx_ssp.c create mode 100644 include/configs/work_92105.h create mode 100644 tools/lpc32xximage.c
Signature · 1 line
2.1.0
PATCH v6 1/8 lpc32xx: add Ethernet support
---
Changes in v6:
- added some missing readl() wraps
- moved descriptors and buffers to SRAM
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
arch/arm/cpu/arm926ejs/lpc32xx/cpu.c | 9 + arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 7 + arch/arm/cpu/arm926ejs/lpc32xx/u-boot.lds | 161 +++++++ arch/arm/include/asm/arch-lpc32xx/config.h | 3 + arch/arm/include/asm/arch-lpc32xx/sys_proto.h | 1 + drivers/net/Makefile | 1 + drivers/net/lpc32xx_eth.c | 639 ++++++++++++++++++++++++++ include/netdev.h | 1 + 8 files changed, 822 insertions(+) create mode 100644 arch/arm/cpu/arm926ejs/lpc32xx/u-boot.lds create mode 100644 drivers/net/lpc32xx_eth.c
arch/arm/cpu/arm926ejs/lpc32xx/cpu.c +9 -0
@@ -5,6 +5,7 @@*/ #include <common.h> +#include <netdev.h> #include <asm/arch/cpu.h> #include <asm/arch/clk.h> #include <asm/arch/wdt.h>
@@ -55,3 +56,11 @@ int print_cpuinfo(void) return 0; }#endif + +#ifdef CONFIG_LPC32XX_ETH +int cpu_eth_init (bd_t *bis) +{ +lpc32xx_eth_initialize (bis); +return 0 ; +} +#endif
arch/arm/cpu/arm926ejs/lpc32xx/devices.c +7 -0
@@ -37,3 +37,10 @@ void lpc32xx_uart_init(unsigned int uart_id)writel (CLK_UART_X_DIV (1 ) |CLK_UART_Y_DIV (1 ), &clk->u3clk + (uart_id -3 )); } + +void lpc32xx_mac_init (void ) +{ +/* Enable MAC interface */ +writel (CLK_MAC_REG |CLK_MAC_SLAVE |CLK_MAC_MASTER + |CLK_MAC_MII , &clk->macclk_ctrl); +}
arch/arm/cpu/arm926ejs/lpc32xx/u-boot.lds new file +161 -0
161 lines not on this page · raw message
arch/arm/include/asm/arch-lpc32xx/config.h +3 -0
@@ -52,6 +52,9 @@#define CONFIG_SYS_BAUDRATE_TABLE \ { 9600, 19200, 38400, 57600, 115200, 230400, 460800 } +/* Ethernet */ +#define LPC32XX_ETH_BASE ETHERNET_BASE +/* NOR Flash */ #if defined(CONFIG_SYS_FLASH_CFI )#define CONFIG_FLASH_CFI_DRIVER
arch/arm/include/asm/arch-lpc32xx/sys_proto.h +1 -0
@@ -8,5 +8,6 @@#define _LPC32XX_SYS_PROTO_Hvoid lpc32xx_uart_init (unsigned int uart_id); +void lpc32xx_mac_init (void );#endif /* _LPC32XX_SYS_PROTO_H */
drivers/net/Makefile +1 -0
@@ -35,6 +35,7 @@ obj-$(CONFIG_GRETH) += greth.o obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o obj-$(CONFIG_LAN91C96) += lan91c96.o +obj-$(CONFIG_LPC32XX_ETH) += lpc32xx_eth.o obj-$(CONFIG_MACB) += macb.o obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o obj-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o
drivers/net/lpc32xx_eth.c new file +639 -0
639 lines not on this page · raw message
include/netdev.h +1 -0
@@ -57,6 +57,7 @@ int greth_initialize(bd_t *bis);void gt6426x_eth_initialize (bd_t *bis);int ks8851_mll_initialize (u8 dev_num,int base_addr);int lan91c96_initialize (u8 dev_num,int base_addr); +int lpc32xx_eth_initialize (bd_t *bis);int macb_eth_initialize (int id,void *regs,unsigned int phy_addr);int mcdmafec_initialize (bd_t *bis);int mcffec_initialize (bd_t *bis);
Signature · 1 line
2.1.0
PATCH v6 2/8 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.
---
Changes in v6:
- rewrite timeout loops
- fix bad block skipping in SPL chainload loop
Changes in v5:
- switch to CONFIG_SYS_NAND_SELF_INIT
Changes in v4:
- remove two debugging statements
- add __iomem to regs struct
- remove useless 'else return;'
- take BB marker out of free OOB area
- replace magic numbers in OOB reads/writes
- add timeouts in NAND loops
- use DIV_ROUND_UP where applicable
- fix erroneous comment
- skip bad blocks in SPL chainload loop
Changes in v3: None
Changes in v2: None
arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 6 + arch/arm/include/asm/arch-lpc32xx/clk.h | 4 + arch/arm/include/asm/arch-lpc32xx/sys_proto.h | 1 + drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/lpc32xx_nand_mlc.c | 718 ++++++++++++++++++++++++++ 5 files changed, 730 insertions(+) create mode 100644 drivers/mtd/nand/lpc32xx_nand_mlc.c
arch/arm/cpu/arm926ejs/lpc32xx/devices.c +6 -0
@@ -44,3 +44,9 @@ void lpc32xx_mac_init(void)writel (CLK_MAC_REG |CLK_MAC_SLAVE |CLK_MAC_MASTER |CLK_MAC_MII , &clk->macclk_ctrl); } + +void lpc32xx_mlc_nand_init (void ) +{ +/* Enable NAND interface */ +writel (CLK_NAND_MLC |CLK_NAND_MLC_INT , &clk->flashclk_ctrl); +}
arch/arm/include/asm/arch-lpc32xx/clk.h +4 -0
@@ -147,6 +147,10 @@ struct clk_pm_regs {/* DMA Clock Control Register bits */ #define CLK_DMA_ENABLE (1 << 0) +/* NAND Clock Control Register bits */ +#define CLK_NAND_MLC (1 << 1) +#define CLK_NAND_MLC_INT (1 << 5) +unsigned int get_sys_clk_rate (void );unsigned int get_hclk_pll_rate (void );unsigned int get_hclk_clk_div (void );
arch/arm/include/asm/arch-lpc32xx/sys_proto.h +1 -0
@@ -9,5 +9,6 @@void lpc32xx_uart_init (unsigned int uart_id);void lpc32xx_mac_init (void ); +void lpc32xx_mlc_nand_init (void );#endif /* _LPC32XX_SYS_PROTO_H */
drivers/mtd/nand/Makefile +1 -0
@@ -52,6 +52,7 @@ obj-$(CONFIG_NAND_JZ4740) += jz4740_nand.o obj-$(CONFIG_NAND_KB9202) += kb9202_nand.o obj-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o obj-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o +obj-$(CONFIG_NAND_LPC32XX_MLC) += lpc32xx_nand_mlc.o obj-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o obj-$(CONFIG_NAND_MXC) += mxc_nand.o
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +718 -0
718 lines not on this page · raw message
Signature · 1 line
2.1.0
PATCH v6 3/8 lpc32xx: i2c: add LPC32xx I2C interface support
---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 11 ++ arch/arm/include/asm/arch-lpc32xx/clk.h | 4 + arch/arm/include/asm/arch-lpc32xx/cpu.h | 2 + arch/arm/include/asm/arch-lpc32xx/sys_proto.h | 1 + drivers/i2c/Makefile | 1 + drivers/i2c/lpc32xx_i2c.c | 249 ++++++++++++++++++++++++++ 6 files changed, 268 insertions(+) create mode 100644 drivers/i2c/lpc32xx_i2c.c
arch/arm/cpu/arm926ejs/lpc32xx/devices.c +11 -0
@@ -50,3 +50,14 @@ void lpc32xx_mlc_nand_init(void)/* Enable NAND interface */ writel (CLK_NAND_MLC |CLK_NAND_MLC_INT , &clk->flashclk_ctrl); } + +void lpc32xx_i2c_init (unsigned int devnum) +{ +/* Enable I2C interface */ +uint32_t ctrl =readl (&clk->i2cclk_ctrl); +if (devnum ==1 ) + ctrl |=CLK_I2C1_ENABLE ; +if (devnum ==2 ) + ctrl |=CLK_I2C2_ENABLE ; +writel (ctrl, &clk->i2cclk_ctrl); +}
arch/arm/include/asm/arch-lpc32xx/clk.h +4 -0
@@ -123,6 +123,10 @@ struct clk_pm_regs {#define CLK_MAC_SLAVE (1 << 1)#define CLK_MAC_REG (1 << 0) +/* I2C Clock Control Register bits */ +#define CLK_I2C2_ENABLE (1 << 1) +#define CLK_I2C1_ENABLE (1 << 0) +/* Timer Clock Control1 Register bits */ #define CLK_TIMCLK_MOTOR (1 << 6)#define CLK_TIMCLK_TIMER3 (1 << 5)
arch/arm/include/asm/arch-lpc32xx/cpu.h +2 -0
@@ -37,6 +37,8 @@#define UART4_BASE 0x40088000/* UART 4 registers base */ #define UART5_BASE 0x40090000/* UART 5 registers base */ #define UART6_BASE 0x40098000/* UART 6 registers base */ +#define I2C1_BASE 0x400A0000/* I2C 1 registers base */ +#define I2C2_BASE 0x400A8000/* I2C 2 registers base */ /* External SDRAM Memory Bank base addresses */ #define EMC_DYCS0_BASE 0x80000000/* SDRAM DYCS0 base address */
arch/arm/include/asm/arch-lpc32xx/sys_proto.h +1 -0
@@ -10,5 +10,6 @@void lpc32xx_uart_init (unsigned int uart_id);void lpc32xx_mac_init (void );void lpc32xx_mlc_nand_init (void ); +void lpc32xx_i2c_init (unsigned int devnum);#endif /* _LPC32XX_SYS_PROTO_H */
drivers/i2c/Makefile +1 -0
@@ -20,6 +20,7 @@ obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o obj-$(CONFIG_SYS_I2C_FTI2C010) += fti2c010.o obj-$(CONFIG_SYS_I2C_IHS) += ihs_i2c.o obj-$(CONFIG_SYS_I2C_KONA) += kona_i2c.o +obj-$(CONFIG_SYS_I2C_LPC32XX) += lpc32xx_i2c.o obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o obj-$(CONFIG_SYS_I2C_MXS) += mxs_i2c.o
drivers/i2c/lpc32xx_i2c.c new file +249 -0
249 lines not on this page · raw message
Signature · 1 line
2.1.0
PATCH v6 4/8 lpc32xx: add GPIO support
This driver only supports Driver Model, not legacy model.
---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- move DM dependency constraint into Kconfig
- move regs pointer and function cache into private struct
- discourage readers from using functions implementation as an example
Changes in v2:
- move from legacy to Driver Model support
arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 5 + arch/arm/include/asm/arch-lpc32xx/gpio.h | 43 +++++ drivers/gpio/Kconfig | 7 + drivers/gpio/Makefile | 1 + drivers/gpio/lpc32xx_gpio.c | 293 +++++++++++++++++++++++++++++++ 5 files changed, 349 insertions(+) create mode 100644 arch/arm/include/asm/arch-lpc32xx/gpio.h create mode 100644 drivers/gpio/lpc32xx_gpio.c
arch/arm/cpu/arm926ejs/lpc32xx/devices.c +5 -0
@@ -9,6 +9,7 @@#include <asm/arch/clk.h> #include <asm/arch/uart.h> #include <asm/io.h> +#include <dm.h> static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE ;static struct uart_ctrl_regs *ctrl = (struct uart_ctrl_regs *)UART_CTRL_BASE ;
@@ -61,3 +62,7 @@ void lpc32xx_i2c_init(unsigned int devnum) ctrl |=CLK_I2C2_ENABLE ;writel (ctrl, &clk->i2cclk_ctrl); } + +U_BOOT_DEVICE (lpc32xx_gpios) = { + .name ="gpio_lpc32xx" +};
arch/arm/include/asm/arch-lpc32xx/gpio.h new file +43 -0
43 lines not on this page · raw message
drivers/gpio/Kconfig +7 -0
@@ -7,3 +7,10 @@ config DM_GPIO the GPIO uclass. Drivers provide methods to query the particular GPIOs that they provide. The uclass interface is defined in include/asm-generic/gpio.h. + +config LPC32XX_GPIO + bool "LPC32XX GPIO driver" + depends on DM + default n + help + Support for the LPC32XX GPIO driver.
drivers/gpio/Makefile +1 -0
@@ -41,3 +41,4 @@ obj-$(CONFIG_ADI_GPIO2) += adi_gpio2.o obj-$(CONFIG_TCA642X) += tca642x.o oby-$(CONFIG_SX151X) += sx151x.o obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o +obj-$(CONFIG_LPC32XX_GPIO) += lpc32xx_gpio.o
drivers/gpio/lpc32xx_gpio.c new file +293 -0
293 lines not on this page · raw message
Signature · 1 line
2.1.0
PATCH v6 5/8 lpc32xx: add LPC32xx SSP support (SPI mode)
---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- move regs and functions in private struct
Changes in v2:
- added MUX setting for SSP0
arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 14 +++ arch/arm/include/asm/arch-lpc32xx/clk.h | 3 + arch/arm/include/asm/arch-lpc32xx/sys_proto.h | 1 + drivers/spi/Makefile | 1 + drivers/spi/lpc32xx_ssp.c | 144 ++++++++++++++++++++++++++ 5 files changed, 163 insertions(+) create mode 100644 drivers/spi/lpc32xx_ssp.c
arch/arm/cpu/arm926ejs/lpc32xx/devices.c +14 -0
@@ -8,11 +8,13 @@#include <asm/arch/cpu.h> #include <asm/arch/clk.h> #include <asm/arch/uart.h> +#include <asm/arch/mux.h> #include <asm/io.h> #include <dm.h> static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE ;static struct uart_ctrl_regs *ctrl = (struct uart_ctrl_regs *)UART_CTRL_BASE ; +static struct mux_regs *mux = (struct mux_regs *)MUX_BASE ;void lpc32xx_uart_init (unsigned int uart_id) {
@@ -66,3 +68,15 @@ void lpc32xx_i2c_init(unsigned int devnum)U_BOOT_DEVICE (lpc32xx_gpios) = { .name ="gpio_lpc32xx" }; + +/* Mux for SCK0, MISO0, MOSI0. We do not use SSEL0. */ + +#define P_MUX_SET_SSP0 0x1600 + +void lpc32xx_ssp_init (void ) +{ +/* Enable SSP0 interface */ +writel (CLK_SSP0_ENABLE_CLOCK , &clk->ssp_ctrl); +/* Mux SSP0 pins */ +writel (P_MUX_SET_SSP0 , &mux->p_mux_set); +}
arch/arm/include/asm/arch-lpc32xx/clk.h +3 -0
@@ -155,6 +155,9 @@ struct clk_pm_regs {#define CLK_NAND_MLC (1 << 1)#define CLK_NAND_MLC_INT (1 << 5) +/* SSP Clock Control Register bits */ +#define CLK_SSP0_ENABLE_CLOCK (1 << 0) +unsigned int get_sys_clk_rate (void );unsigned int get_hclk_pll_rate (void );unsigned int get_hclk_clk_div (void );
arch/arm/include/asm/arch-lpc32xx/sys_proto.h +1 -0
@@ -11,5 +11,6 @@ void lpc32xx_uart_init(unsigned int uart_id);void lpc32xx_mac_init (void );void lpc32xx_mlc_nand_init (void );void lpc32xx_i2c_init (unsigned int devnum); +void lpc32xx_ssp_init (void );#endif /* _LPC32XX_SYS_PROTO_H */
drivers/spi/Makefile +1 -0
@@ -32,6 +32,7 @@ obj-$(CONFIG_EXYNOS_SPI) += exynos_spi.o obj-$(CONFIG_FTSSP010_SPI) += ftssp010_spi.o obj-$(CONFIG_ICH_SPI) += ich.o obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o +obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o obj-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o obj-$(CONFIG_MXC_SPI) += mxc_spi.o
drivers/spi/lpc32xx_ssp.c new file +144 -0
144 lines not on this page · raw message
Signature · 1 line
2.1.0
PATCH v6 6/8 dtt: add ds620 support
---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- cosmetic: added a blank line before copyright
drivers/hwmon/Makefile | 1 + drivers/hwmon/ds620.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/dtt.h | 15 ++++++------ 3 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 drivers/hwmon/ds620.c
drivers/hwmon/Makefile +1 -0
@@ -15,6 +15,7 @@ obj-$(CONFIG_DTT_ADT7460) += adt7460.o obj-$(CONFIG_DTT_DS1621) += ds1621.o obj-$(CONFIG_DTT_DS1722) += ds1722.o obj-$(CONFIG_DTT_DS1775) += ds1775.o +obj-$(CONFIG_DTT_DS620) += ds620.o obj-$(CONFIG_DTT_LM63) += lm63.o obj-$(CONFIG_DTT_LM73) += lm73.o obj-$(CONFIG_DTT_LM75) += lm75.o
drivers/hwmon/ds620.c new file +65 -0
65 lines not on this page · raw message
include/dtt.h +8 -7
@@ -12,13 +12,14 @@#define _DTT_H_#if defined(CONFIG_DTT_ADM1021 ) || \ - defined(CONFIG_DTT_ADT7460 ) || \ - defined(CONFIG_DTT_DS1621 ) || \ - defined(CONFIG_DTT_DS1775 ) || \ - defined(CONFIG_DTT_LM63 ) || \ - defined(CONFIG_DTT_LM73 ) || \ - defined(CONFIG_DTT_LM75 ) || \ - defined(CONFIG_DTT_LM81 ) + defined(CONFIG_DTT_ADT7460 ) || \ + defined(CONFIG_DTT_DS1621 ) || \ + defined(CONFIG_DTT_DS1775 ) || \ + defined(CONFIG_DTT_DS620 ) || \ + defined(CONFIG_DTT_LM63 ) || \ + defined(CONFIG_DTT_LM73 ) || \ + defined(CONFIG_DTT_LM75 ) || \ + defined(CONFIG_DTT_LM81 )#define CONFIG_DTT /* We have a DTT */
Signature · 1 line
2.1.0
PATCH v6 7/8 lpc32xx: add lpc32xx-spl.bin boot image target
---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- remove script/Makefile.spl change
Changes in v2:
- move boot image generation to mkimage framework
common/image.c | 1 + include/image.h | 1 + tools/Makefile | 1 + tools/lpc32xximage.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 181 insertions(+) create mode 100644 tools/lpc32xximage.c
common/image.c +1 -0
@@ -149,6 +149,7 @@ static const table_entry_t uimage_type[] = { { IH_TYPE_MXSIMAGE, "mxsimage", "Freescale MXS Boot Image",}, { IH_TYPE_ATMELIMAGE, "atmelimage", "ATMEL ROM-Boot Image",}, { IH_TYPE_X86_SETUP, "x86_setup", "x86 setup.bin", }, + { IH_TYPE_LPC32XXIMAGE, "lpc32xximage", "LPC32XX Boot Image", }, { -1, "", "", }, };
include/image.h +1 -0
@@ -242,6 +242,7 @@ struct lmb;#define IH_TYPE_ATMELIMAGE 18/* ATMEL ROM bootable Image */ #define IH_TYPE_SOCFPGAIMAGE 19/* Altera SOCFPGA Preloader */ #define IH_TYPE_X86_SETUP 20/* x86 setup.bin Image */ +#define IH_TYPE_LPC32XXIMAGE 21/* x86 setup.bin Image */ /* * Compression Types
tools/Makefile +1 -0
@@ -83,6 +83,7 @@ dumpimage-mkimage-objs := aisimage.o \ imximage.o \ kwbimage.o \ lib/md5.o \ + lpc32xximage.o \ mxsimage.o \ omapimage.o \ os_support.o \
tools/lpc32xximage.c new file +178 -0
178 lines not on this page · raw message
Signature · 1 line
2.1.0
PATCH v6 8/8 lpc32xx: add support for board work_92105
Work_92105 from Work Microwave is an LPC3250-
based board with the following features:
- 64MB SDR DRAM
- 1 GB SLC NAND, managed through MLC controller.
- Ethernet
- Ethernet + PHY SMSC8710
- I2C:
- EEPROM (24M01-compatible)
- RTC (DS1374-compatible)
- Temperature sensor (DS620)
- DACs (2 x MAX518)
- SPI (through SSP interface)
- Port expander MAX6957
- LCD display (HD44780-compatible), controlled
through the port expander and DACs
This board has SPL support, and uses the LPC32XX boot image format.
---
Changes in v6:
- remove '+S:' prefixes from defconfig
- use custom LPC32XX linker script
- reset peripherals at startup
- support 128MB boards
Changes in v5:
- switched board NAND config to CONFIG_SYS_NAND_SELF_INIT
Changes in v4: None
Changes in v3:
- use writel() in DRAM initialization code
- remove useless conditionals in dram.c
- fix and complete the board README
- remove redundant CONFIG_CMD_DM from config header file
- add a note re the hard-coded MAC address
- add 'single flashable file' make target
Changes in v2: None
Makefile | 20 ++ arch/arm/Kconfig | 6 + arch/arm/cpu/arm926ejs/lpc32xx/Makefile | 2 + arch/arm/cpu/arm926ejs/lpc32xx/clk.c | 34 ++ arch/arm/cpu/arm926ejs/lpc32xx/cpu.c | 4 + arch/arm/cpu/arm926ejs/lpc32xx/dram.c | 79 +++++ arch/arm/cpu/arm926ejs/lpc32xx/lowlevel_init.S | 45 +++ arch/arm/include/asm/arch-lpc32xx/clk.h | 5 + arch/arm/include/asm/arch-lpc32xx/cpu.h | 1 + arch/arm/include/asm/arch-lpc32xx/mux.h | 18 ++ arch/arm/include/asm/arch-lpc32xx/sys_proto.h | 4 +- board/work-microwave/work_92105/Kconfig | 15 + board/work-microwave/work_92105/MAINTAINERS | 6 + board/work-microwave/work_92105/Makefile | 10 + board/work-microwave/work_92105/README | 91 ++++++ board/work-microwave/work_92105/work_92105.c | 77 +++++ .../work-microwave/work_92105/work_92105_display.c | 349 +++++++++++++++++++++ .../work-microwave/work_92105/work_92105_display.h | 14 + board/work-microwave/work_92105/work_92105_spl.c | 33 ++ configs/work_92105_defconfig | 6 + include/configs/work_92105.h | 268 ++++++++++++++++ 21 files changed, 1086 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/arm926ejs/lpc32xx/dram.c create mode 100644 arch/arm/cpu/arm926ejs/lpc32xx/lowlevel_init.S create mode 100644 arch/arm/include/asm/arch-lpc32xx/mux.h create mode 100644 board/work-microwave/work_92105/Kconfig create mode 100644 board/work-microwave/work_92105/MAINTAINERS create mode 100644 board/work-microwave/work_92105/Makefile create mode 100644 board/work-microwave/work_92105/README create mode 100644 board/work-microwave/work_92105/work_92105.c create mode 100644 board/work-microwave/work_92105/work_92105_display.c create mode 100644 board/work-microwave/work_92105/work_92105_display.h create mode 100644 board/work-microwave/work_92105/work_92105_spl.c create mode 100644 configs/work_92105_defconfig create mode 100644 include/configs/work_92105.h
Makefile +20 -0
@@ -896,6 +896,26 @@ OBJCOPYFLAGS_u-boot-with-spl.bin = -I binary -O binary \ u-boot-with-spl.bin: spl/u-boot-spl.bin $(SPL_PAYLOAD) FORCE $(call if_changed,pad_cat) +MKIMAGEFLAGS_lpc32xx-spl.img = -T lpc32xximage -a $(CONFIG_SPL_TEXT_BASE) + +lpc32xx-spl.img: spl/u-boot-spl.bin FORCE + $(call if_changed,mkimage) + +OBJCOPYFLAGS_lpc32xx-boot-0.bin = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) + +lpc32xx-boot-0.bin: lpc32xx-spl.img + $(call if_changed,objcopy) + +OBJCOPYFLAGS_lpc32xx-boot-1.bin = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) + +lpc32xx-boot-1.bin: lpc32xx-spl.img + $(call if_changed,objcopy) + +lpc32xx-full.bin: lpc32xx-boot-0.bin lpc32xx-boot-1.bin u-boot.img + $(call if_changed,cat) + +CLEAN_FILES += lpc32xx-* + OBJCOPYFLAGS_u-boot-with-tpl.bin = -I binary -O binary \ --pad-to=$(CONFIG_TPL_PAD_TO) tpl/u-boot-with-tpl.bin: tpl/u-boot-tpl.bin u-boot.bin FORCE
arch/arm/Kconfig +6 -0
@@ -132,6 +132,11 @@ config TARGET_DEVKIT3250 bool "Support devkit3250" select CPU_ARM926EJS +config TARGET_WORK_92105 + bool "Support work_92105" + select CPU_ARM926EJS + select SUPPORT_SPL + config TARGET_MX25PDK bool "Support mx25pdk" select CPU_ARM926EJS
@@ -871,6 +876,7 @@ source "board/vpac270/Kconfig" source "board/wandboard/Kconfig" source "board/warp/Kconfig" source "board/woodburn/Kconfig" +source "board/work-microwave/work_92105/Kconfig" source "board/xaeniax/Kconfig" source "board/xilinx/zynqmp/Kconfig" source "board/zipitz2/Kconfig"
arch/arm/cpu/arm926ejs/lpc32xx/Makefile +2 -0
@@ -6,3 +6,5 @@ # obj-y = cpu.o clk.o devices.o timer.o + +obj-$(CONFIG_SPL_BUILD) += dram.o lowlevel_init.o
arch/arm/cpu/arm926ejs/lpc32xx/clk.c +34 -0
@@ -98,6 +98,40 @@ unsigned int get_periph_clk_rate(void)return get_hclk_pll_rate () /get_periph_clk_div (); } +unsigned int get_sdram_clk_rate (void ) +{ +unsigned int src_clk; + +if (!(readl (&clk->pwr_ctrl) &CLK_PWR_NORMAL_RUN )) +return get_sys_clk_rate (); + + src_clk =get_hclk_pll_rate (); + +if (readl (&clk->sdramclk_ctrl) &CLK_SDRAM_DDR_SEL ) { +/* using DDR */ +switch (readl (&clk->hclkdiv_ctrl) &CLK_HCLK_DDRAM_MASK ) { +case CLK_HCLK_DDRAM_HALF : +return src_clk/2 ; +case CLK_HCLK_DDRAM_NOMINAL : +return src_clk; +default : +return 0 ; + } + }else { +/* using SDR */ +switch (readl (&clk->hclkdiv_ctrl) &CLK_HCLK_ARM_PLL_DIV_MASK ) { +case CLK_HCLK_ARM_PLL_DIV_4 : +return src_clk/4 ; +case CLK_HCLK_ARM_PLL_DIV_2 : +return src_clk/2 ; +case CLK_HCLK_ARM_PLL_DIV_1 : +return src_clk; +default : +return 0 ; + } + } +} +int get_serial_clock (void ) {return get_periph_clk_rate ();
arch/arm/cpu/arm926ejs/lpc32xx/cpu.c +4 -0
@@ -9,6 +9,7 @@#include <asm/arch/cpu.h> #include <asm/arch/clk.h> #include <asm/arch/wdt.h> +#include <asm/arch/sys_proto.h> #include <asm/io.h> static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE ;
@@ -33,6 +34,9 @@ void reset_cpu(ulong addr)#if defined(CONFIG_ARCH_CPU_INIT )int arch_cpu_init (void ) { +#if defined(CONFIG_SPL_BUILD ) +ddr_init (); +#endif /* * It might be necessary to flush data cache, if U-boot is loaded * from kickstart bootloader, e.g. from S1L loader
arch/arm/cpu/arm926ejs/lpc32xx/dram.c new file +79 -0
79 lines not on this page · raw message
arch/arm/cpu/arm926ejs/lpc32xx/lowlevel_init.S new file +45 -0
45 lines not on this page · raw message
arch/arm/include/asm/arch-lpc32xx/clk.h +5 -0
@@ -71,6 +71,7 @@ struct clk_pm_regs { };/* HCLK Divider Control Register bits */ +#define CLK_HCLK_DDRAM_MASK (0x3 << 7)#define CLK_HCLK_DDRAM_HALF (0x2 << 7)#define CLK_HCLK_DDRAM_NOMINAL (0x1 << 7)#define CLK_HCLK_DDRAM_STOPPED (0x0 << 7)
@@ -158,11 +159,15 @@ struct clk_pm_regs {/* SSP Clock Control Register bits */ #define CLK_SSP0_ENABLE_CLOCK (1 << 0) +/* SDRAMCLK register bits */ +#define CLK_SDRAM_DDR_SEL (1 << 1) +unsigned int get_sys_clk_rate (void );unsigned int get_hclk_pll_rate (void );unsigned int get_hclk_clk_div (void );unsigned int get_hclk_clk_rate (void );unsigned int get_periph_clk_div (void );unsigned int get_periph_clk_rate (void ); +unsigned int get_sdram_clk_rate (void );#endif /* _LPC32XX_CLK_H */
arch/arm/include/asm/arch-lpc32xx/cpu.h +1 -0
@@ -27,6 +27,7 @@#define HS_UART7_BASE 0x4001C000/* High speed UART 7 registers base */ #define RTC_BASE 0x40024000/* RTC registers base */ #define GPIO_BASE 0x40028000/* GPIO registers base */ +#define MUX_BASE 0x40028100/* MUX registers base */ #define WDT_BASE 0x4003C000/* Watchdog timer registers base */ #define TIMER0_BASE 0x40044000/* Timer0 registers base */ #define TIMER1_BASE 0x4004C000/* Timer1 registers base */
arch/arm/include/asm/arch-lpc32xx/mux.h new file +18 -0
@@ -0,0 +1,18 @@ +/* +* LPC32xx MUX interface +* +* (C) Copyright 2015 DENX Software Engineering GmbH +* Written-by: Albert ARIBAUD <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +/** +* MUX register map for LPC32xx +*/ + +struct mux_regs { +u32 p_mux_set; +u32 p_mux_clr; +u32 p_mux_state; +};
arch/arm/include/asm/arch-lpc32xx/sys_proto.h +3 -1
@@ -12,5 +12,7 @@ void lpc32xx_mac_init(void);void lpc32xx_mlc_nand_init (void );void lpc32xx_i2c_init (unsigned int devnum);void lpc32xx_ssp_init (void ); - +#if defined(CONFIG_SPL_BUILD ) +void ddr_init (void ); +#endif #endif /* _LPC32XX_SYS_PROTO_H */
board/work-microwave/work_92105/Kconfig new file +15 -0
@@ -0,0 +1,15 @@ +if TARGET_WORK_92105 + +config SYS_BOARD + default "work_92105" + +config SYS_VENDOR + default "work-microwave" + +config SYS_SOC + default "lpc32xx" + +config SYS_CONFIG_NAME + default "work_92105" + +endif
board/work-microwave/work_92105/MAINTAINERS new file +6 -0
@@ -0,0 +1,6 @@ +WORK_92105 BOARD +M: Albert ARIBAUD <[email protected]> +S: Maintained +F: board/work-microwave/work_92105/ +F: include/configs/work_92105.h +F: configs/work_92105_defconfig
board/work-microwave/work_92105/Makefile new file +10 -0
@@ -0,0 +1,10 @@ +# +# (C) Copyright 2014 DENX Software Engineering GmbH +# Written-by: Albert ARIBAUD <[email protected]> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := work_92105.o work_92105_display.o + +obj-$(CONFIG_SPL_BUILD) += work_92105_spl.o
board/work-microwave/work_92105/README new file +91 -0
91 lines not on this page · raw message
board/work-microwave/work_92105/work_92105.c new file +77 -0
77 lines not on this page · raw message
board/work-microwave/work_92105/work_92105_display.c new file +349 -0
349 lines not on this page · raw message
board/work-microwave/work_92105/work_92105_display.h new file +14 -0
@@ -0,0 +1,14 @@ +/* +* work_92105 display support interface +* +* (C) Copyright 2014 DENX Software Engineering GmbH +* Written-by: Albert ARIBAUD <[email protected]> +* +* The work_92105 display is a HD44780-compatible module +* controlled through a MAX6957AAX SPI port expander, two +* MAX518 I2C DACs and native LPC32xx GPO 15. +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +void work_92105_display_init (void );
board/work-microwave/work_92105/work_92105_spl.c new file +33 -0
@@ -0,0 +1,33 @@ +/* +* WORK Microwave work_92105 board support +* +* (C) Copyright 2014 DENX Software Engineering GmbH +* Written-by: Albert ARIBAUD <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/cpu.h> +#include <asm/arch/emc.h> +#include <asm/gpio.h> +#include <spl.h> +#include "work_92105_display.h" + +void spl_board_init (void ) +{ +/* initialize serial port for console */ +lpc32xx_uart_init (CONFIG_SYS_LPC32XX_UART ); +/* initialize console */ +preloader_console_init (); +/* init DDR and NAND to chainload U-Boot */ +ddr_init (); +lpc32xx_mlc_nand_init (); +} + +u32 spl_boot_device (void ) +{ +return BOOT_DEVICE_NAND ; +}
configs/work_92105_defconfig new file +6 -0
@@ -0,0 +1,6 @@ +CONFIG_ARM=y +CONFIG_TARGET_WORK_92105=y +CONFIG_DM=y +CONFIG_DM_GPIO=y +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="SYS_LDSCRIPT=arch/arm/cpu/arm926ejs/lpc32xx/u-boot.lds"
include/configs/work_92105.h new file +268 -0
268 lines not on this page · raw message
Signature · 1 line
2.1.0
PATCH v6 5/8 lpc32xx: add LPC32xx SSP support (SPI mode)
In reply to Albert ARIBAUD (3ADEV)Quoted 126 lines · On 18 March 2015 at 14:34, Albert ARIBAUD (3ADEV) <[email protected]>…
Signed-off-by Albert ARIBAUD (3ADEV) <[email protected]>---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- move regs and functions in private structChanges in v2:
- added MUX setting for SSP0arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 14 +++ arch/arm/include/asm/arch-lpc32xx/clk.h | 3 + arch/arm/include/asm/arch-lpc32xx/sys_proto.h | 1 + drivers/spi/Makefile | 1 + drivers/spi/lpc32xx_ssp.c | 144 ++++++++++++++++++++++++++ 5 files changed, 163 insertions(+) create mode 100644 drivers/spi/lpc32xx_ssp.carch/arm/cpu/arm926ejs/lpc32xx/devices.c +14
-0@@ -8,11 +8,13 @@#include <asm/arch/cpu.h> #include <asm/arch/clk.h> #include <asm/arch/uart.h> +#include <asm/arch/mux.h> #include <asm/io.h> #include <dm.h> static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE ;static struct uart_ctrl_regs *ctrl = (struct uart_ctrl_regs *)UART_CTRL_BASE ; +static struct mux_regs *mux = (struct mux_regs *)MUX_BASE ;void lpc32xx_uart_init (unsigned int uart_id) {@@ -66,3 +68,15 @@ void lpc32xx_i2c_init(unsigned int devnum)U_BOOT_DEVICE (lpc32xx_gpios) = { .name ="gpio_lpc32xx" }; + +/* Mux for SCK0, MISO0, MOSI0. We do not use SSEL0. */ + +#define P_MUX_SET_SSP0 0x1600 + +void lpc32xx_ssp_init (void ) +{ +/* Enable SSP0 interface */ +writel (CLK_SSP0_ENABLE_CLOCK , &clk->ssp_ctrl); +/* Mux SSP0 pins */ +writel (P_MUX_SET_SSP0 , &mux->p_mux_set); +}arch/arm/include/asm/arch-lpc32xx/clk.h +3
-0@@ -155,6 +155,9 @@ struct clk_pm_regs {#define CLK_NAND_MLC (1 << 1)#define CLK_NAND_MLC_INT (1 << 5) +/* SSP Clock Control Register bits */ +#define CLK_SSP0_ENABLE_CLOCK (1 << 0) +unsigned int get_sys_clk_rate (void );unsigned int get_hclk_pll_rate (void );unsigned int get_hclk_clk_div (void );arch/arm/include/asm/arch-lpc32xx/sys_proto.h +1
-0@@ -11,5 +11,6 @@ void lpc32xx_uart_init(unsigned int uart_id);void lpc32xx_mac_init (void );void lpc32xx_mlc_nand_init (void );void lpc32xx_i2c_init (unsigned int devnum); +void lpc32xx_ssp_init (void );#endif /* _LPC32XX_SYS_PROTO_H */ drivers/spi/Makefile +1
-0@@ -32,6 +32,7 @@ obj-$(CONFIG_EXYNOS_SPI) += exynos_spi.o obj-$(CONFIG_FTSSP010_SPI) += ftssp010_spi.o obj-$(CONFIG_ICH_SPI) += ich.o obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o +obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o obj-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o obj-$(CONFIG_MXC_SPI) += mxc_spi.odrivers/spi/lpc32xx_ssp.c new file +29
-0@@ -0,0 +1,144 @@ +/* +* LPC32xx SSP interface (SPI mode) +* +* (C) Copyright 2014 DENX Software Engineering GmbH +* Written-by: Albert ARIBAUD <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <linux/compat.h> +#include <asm/io.h> +#include <malloc.h> +#include <spi.h> +#include <asm/arch/clk.h> + +/* SSP chip registers */ +struct ssp_regs { +u32 cr0; +u32 cr1; +u32 data; +u32 sr; +u32 cpsr; +u32 imsc; +u32 ris; +u32 mis; +u32 icr; +u32 dmacr; +};
drivers/spi/lpc32xx_ssp.c line 39
Quoted 10 lines
drivers/spi/lpc32xx_ssp.c new file +10
-0+ +/* CR1 register defines */ +#define SSP_CR1_SSP_ENABLE 0x0002 + +/* SR register defines */ +#define SSP_SR_TNF 0x0002 +/* SSP status RX FIFO not empty bit */ +#define SSP_SR_RNE 0x0004 + +/* zynq spi slave */
Typo here.. zynq
Quoted 106 lines
drivers/spi/lpc32xx_ssp.c new file +105
-1+struct lpc32xx_spi_slave { +struct spi_slave slave; +struct ssp_regs *regs; +}; + +static inline struct lpc32xx_spi_slave *to_lpc32xx_spi_slave ( +struct spi_slave *slave) +{ + return container_of(slave, struct lpc32xx_spi_slave, slave); +} + +/* spi_init is called during boot when CONFIG_CMD_SPI is defined */ +void spi_init (void ) +{ +/* +* nothing to do: clocking was enabled in lpc32xx_ssp_enable() +* and configuration will be done in spi_setup_slave() +*/ +} + +/* the following is called in sequence by do_spi_xfer() */ + +struct spi_slave *spi_setup_slave (uint bus,uint cs,uint max_hz,uint mode) +{ +struct lpc32xx_spi_slave *lslave; + +/* we only set up SSP0 for now, so ignore bus */ + +if (mode &SPI_3WIRE ) { +error ("3-wire mode not supported" ); +return NULL ; + } + +if (mode &SPI_SLAVE ) { +error ("slave mode not supported\n" ); +return NULL ; + } + +if (mode &SPI_PREAMBLE ) { +error ("preamble byte skipping not supported\n" ); +return NULL ; + } + + lslave = spi_alloc_slave(struct lpc32xx_spi_slave, bus, cs); +if (!lslave) { +printf ("SPI_error: Fail to allocate lpc32xx_spi_slave\n" ); +return NULL ; + } + + lslave->regs = (struct ssp_regs *)SSP0_BASE ; + +/* +* 8 bit frame, SPI fmt, 500kbps -> clock divider is 26. +* Set SCR to 0 and CPSDVSR to 26. +*/ + +writel (0x7 , &lslave->regs->cr0);/* 8-bit chunks, SPI, 1 clk/bit */ +writel (26 , &lslave->regs->cpsr);/* SSP clock = HCLK/26 = 500kbps */ +writel (0 , &lslave->regs->imsc);/* do not raise any interrupts */ +writel (0 , &lslave->regs->icr);/* clear any pending interrupt */ +writel (0 , &lslave->regs->dmacr);/* do not do DMAs */ +writel (SSP_CR1_SSP_ENABLE , &lslave->regs->cr1);/* enable SSP0 */ +return &lslave->slave; +} + +void spi_free_slave (struct spi_slave *slave) +{ +struct lpc32xx_spi_slave *lslave =to_lpc32xx_spi_slave (slave); + +debug ("(lpc32xx) spi_free_slave: 0x%08x\n" , (u32 )lslave); +free (lslave); +} + +int spi_claim_bus (struct spi_slave *slave) +{ +/* only one bus and slave so far, always available */ +return 0 ; +} + +int spi_xfer (struct spi_slave *slave,unsigned int bitlen, +const void *dout,void *din,unsigned long flags) +{ +struct lpc32xx_spi_slave *lslave =to_lpc32xx_spi_slave (slave); +int bytelen = bitlen >>3 ; +int idx_out =0 ; +int idx_in =0 ; +int start_time; + + start_time =get_timer (0 ); +while ((idx_out < bytelen) || (idx_in < bytelen)) { +int status =readl (&lslave->regs->sr); +if ((idx_out < bytelen) && (status &SSP_SR_TNF )) +writel (((u8 *)dout)[idx_out++], &lslave->regs->data); +if ((idx_in < bytelen) && (status & status &SSP_SR_RNE )) + ((u8 *)din)[idx_in++] =readl (&lslave->regs->data); +if (get_timer (start_time) >=CONFIG_LPC32XX_SSP_TIMEOUT ) +return -1 ; + } +return 0 ; +} + +void spi_release_bus (struct spi_slave *slave) +{ +/* do nothing */ +} --
Quoted 1 line
2.1.0
thanks!
Signature · 1 line
Jagan.
PATCH v6 2/8 lpc32xx: mtd: nand: add MLC NAND controller
In reply to Albert ARIBAUD (3ADEV)drivers/mtd/nand/lpc32xx_nand_mlc.c line 673
Quoted 3 lines · On Wed, 2015-03-18 at 10:04 +0100, Albert ARIBAUD (3ADEV) wrote:
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +3
-0+int nand_spl_load_image (uint32_t offs,unsigned int size,void *dst) +{ +int block_good;
bool?
Quoted 4 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +4
-0+struct lpc32xx_oob oob; +unsigned int page, left; + +/* if starting mid-block consider block good */
drivers/mtd/nand/lpc32xx_nand_mlc.c line 687
Quoted 10 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +10
-0+ block_good =1 ; + +for (page = offs /BYTES_PER_PAGE , + left =DIV_ROUND_UP (size,BYTES_PER_PAGE ); + left && (page <PAGES_PER_CHIP_MAX ); page++) { +/* read inband and oob page data anyway */ +int res =read_single_page (dst, page, &oob); +/* return error if a good block's page was not readable */ +if ((res <0 ) && block_good) +return -1 ;
Why even try to read it if it's been marked bad?
drivers/mtd/nand/lpc32xx_nand_mlc.c line 688
Quoted 1 line
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +1
-0+/* if first page in a block, update 'block good' status */
The non-SPL driver appears to be checking the last two pages in the block, not the first page.
drivers/mtd/nand/lpc32xx_nand_mlc.c line 694
Quoted 6 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +6
-0+if ((page %PAGES_PER_BLOCK ) ==0 ) { +/* assume block is good */ + block_good =1 ; +/* if page could not be read, assume block is bad */ +if (res <0 ) + block_good =0 ;
No. A block is to be skipped if and only if it has a bad block marker. ECC errors should not be silently ignored just because they happen on the first page of a block. If the writer of this data didn't skip the block, then skipping it when reading will result in unusable data regardless of the underlying ECC problem.
-Scott
PATCH v6 2/8 lpc32xx: mtd: nand: add MLC NAND controller
Hi Scott,
Le Thu, 19 Mar 2015 16:39:42 -0500, Scott Wood
<[email protected]> a ?crit :
Quoted 7 lines · On Wed, 2015-03-18 at 10:04 +0100, Albert ARIBAUD (3ADEV) wrote:
drivers/mtd/nand/lpc32xx_nand_mlc.c line 673
Quoted 3 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +3
-0+int nand_spl_load_image (uint32_t offs,unsigned int size,void *dst) +{ +int block_good;bool?
Quoted 16 lines
Quoted 4 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +4
-0+struct lpc32xx_oob oob; +unsigned int page, left; + +/* if starting mid-block consider block good */ drivers/mtd/nand/lpc32xx_nand_mlc.c line 687
Quoted 10 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +10
-0+ block_good =1 ; + +for (page = offs /BYTES_PER_PAGE , + left =DIV_ROUND_UP (size,BYTES_PER_PAGE ); + left && (page <PAGES_PER_CHIP_MAX ); page++) { +/* read inband and oob page data anyway */ +int res =read_single_page (dst, page, &oob); +/* return error if a good block's page was not readable */ +if ((res <0 ) && block_good) +return -1 ;Why even try to read it if it's been marked bad?
Actually, at this point, we may not know yet if the block is good or bad, since we might be reading a page of it for the first time. Will fix, see below.
Quoted 4 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c line 688
Quoted 1 line
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +1
-0+/* if first page in a block, update 'block good' status */ The non-SPL driver appears to be checking the last two pages in the block, not the first page.
Thanks for pointing out this discrepancy.
I took the first page option here after checking the NAND's datasheet, which says that for factory bad block marking at least, while all pages in a bad block /should/ bear the bad block marker, only the first one is /guaranteed/ to have it. The driver might have inherited the 'last page' option from the previous NAND chip used, or from a mistake of my own.
BTW, is there a standard way to ask a NAND chip which page(s) in a bad block should be checked?
Quoted 4 lines
Quoted 4 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +4
-0+if ((page %PAGES_PER_BLOCK ) ==0 ) { +/* assume block is good */ + block_good =1 ; +/* if page could not be read, assume block is bad */
Quoted 8 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (res < 0) + block_good = 0;No. A block is to be skipped if and only if it has a bad block marker. ECC errors should not be silently ignored just because they happen on the first page of a block. If the writer of this data didn't skip the block, then skipping it when reading will result in unusable data regardless of the underlying ECC problem.
You're correct of course.
However, I do want the SPL chainloading to be as resilient as possible, and we have established that it will have to read some part of a bad block -- possibly resulting in a read failure -- before knowing that the block is bad, which means it may have to finally ignore the read failure.
I guess I could wait to declare the block good or bad until I could read at least one if its pages (actually, one of its pages' OOB data) properly, only bail out if the OOB says the block is supposed to be good.
Now, if none of the block's pages could be read, this still prevents us from knowing whether these read failures are catastrophic. If the block was actually bad and skipped, then the resulting image might be intact, will pass the checksum test, and will run; if the block was actually good, SPL will detect it and not boot the corrupt image -- except if the completely unreadable good block was the first one, which holds the signature and checksum, in which case SPL will fall back to considering a raw, unsigned, unverifiable image, and will jump into corrupt code.
This may happen; but I think the probability of having a completely unreadable sector is very low, and the probability of this sector being the first one of the image is very low too [1].
Which leads me to two possible courses of action:
- consider the risk even though the probabilities are very low, thus consider any totally unreadable sector as good, and bail out in this case, or
- add an option to SPL that prevents common/spl/spl.c from falling back to running the image as raw if no signature is found, and consider any totally unreadable sector as bad and therefore ignore the read errors. Either the sector was actually good, and SPL will catch the image as corrupt or missing a signature, or the sector was actually bad, and the image will run as expected.
I personally prefer the second one, as it bring a valuable (I think) feature to U-Boot, for any board on which one wants to prevent an unverifiable image from running.
Quoted 1 line
-Scott
Cordialement,
Albert ARIBAUD
3ADEV
Signature · 3 lines
[1] Both together would require Douglas Adam's infinite improbability generator while probably attracting its arch-nemesis, Murphy's Law. I wouldn't like to be trapped between the two. :)
PATCH v6 2/8 lpc32xx: mtd: nand: add MLC NAND controller
Quoted 38 lines · Albert ARIBAUD
Hi Scott,
Le Thu, 19 Mar 2015 16:39:42 -0500, Scott Wood
<[email protected]> a ?crit :Quoted 7 lines · On Wed, 2015-03-18 at 10:04 +0100, Albert ARIBAUD (3ADEV) wrote:
drivers/mtd/nand/lpc32xx_nand_mlc.c line 673
Quoted 3 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +3
-0+int nand_spl_load_image (uint32_t offs,unsigned int size,void *dst) +{ +int block_good;bool?
Quoted 16 lines
Quoted 4 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +4
-0+struct lpc32xx_oob oob; +unsigned int page, left; + +/* if starting mid-block consider block good */ drivers/mtd/nand/lpc32xx_nand_mlc.c line 687
Quoted 10 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +10
-0+ block_good =1 ; + +for (page = offs /BYTES_PER_PAGE , + left =DIV_ROUND_UP (size,BYTES_PER_PAGE ); + left && (page <PAGES_PER_CHIP_MAX ); page++) { +/* read inband and oob page data anyway */ +int res =read_single_page (dst, page, &oob); +/* return error if a good block's page was not readable */ +if ((res <0 ) && block_good) +return -1 ;Why even try to read it if it's been marked bad?
Actually, at this point, we may not know yet if the block is good or bad, since we might be reading a page of it for the first time. Will fix, see below.
Quoted 4 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c line 688
Quoted 1 line
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +1
-0+/* if first page in a block, update 'block good' status */ The non-SPL driver appears to be checking the last two pages in the block, not the first page.
Quoted 7 lines
Thanks for pointing out this discrepancy.
I took the first page option here after checking the NAND's datasheet, which says that for factory bad block marking at least, while all pages in a bad block /should/ bear the bad block marker, only the first one is /guaranteed/ to have it. The driver might have inherited the 'last page' option from the previous NAND chip used, or from a mistake of my own.
Are there any plans for this controller to be used with different chips?
Quoted 2 lines
BTW, is there a standard way to ask a NAND chip which page(s) in a bad block should be checked?
Yes and no:
http://lists.infradead.org/pipermail/linux-mtd/2011-November/038419.html
Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +4
-0+if ((page %PAGES_PER_BLOCK ) ==0 ) { +/* assume block is good */ + block_good =1 ; +/* if page could not be read, assume block is bad */ Quoted 8 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (res < 0) + block_good = 0;No. A block is to be skipped if and only if it has a bad block marker. ECC errors should not be silently ignored just because they happen on the first page of a block. If the writer of this data didn't skip the block, then skipping it when reading will result in unusable data regardless of the underlying ECC problem.
Quoted 7 lines
You're correct of course.
However, I do want the SPL chainloading to be as resilient as possible, and we have established that it will have to read some part of a bad block -- possibly resulting in a read failure -- before knowing that the block is bad, which means it may have to finally ignore the read failure.
FWIW, the eLBC/IFC SPL functions have the same problem regarding halting on an ECC error before checking the bad block status. Instead it should return an error code, and let the caller halt after it's sure it's not marked bad.
Quoted 20 lines
I guess I could wait to declare the block good or bad until I could read at least one if its pages (actually, one of its pages' OOB data) properly, only bail out if the OOB says the block is supposed to be good.
Now, if none of the block's pages could be read, this still prevents us from knowing whether these read failures are catastrophic.
If the block was actually bad and skipped, then the resulting image might be intact, will pass the checksum test, and will run; if the block was actually good, SPL will detect it and not boot the corrupt image -- except if the completely unreadable good block was the first one, which holds the signature and checksum, in which case SPL will fall back to considering a raw, unsigned, unverifiable image, and will jump into corrupt code.
This may happen; but I think the probability of having a completely unreadable sector is very low, and the probability of this sector being the first one of the image is very low too [1].
Quoted 5 lines
Which leads me to two possible courses of action:
- consider the risk even though the probabilities are very low, thus consider any totally unreadable sector as good, and bail out in this case, or
I was thinking instead to distinguish between a hard failure where you got no data from the NAND (e.g. a timeout), versus an ECC failure. In the later case you can still look in the OOB for a bad block marker.
Quoted 6 lines
- add an option to SPL that prevents
common/spl/spl.cfrom falling back to running the image as raw if no signature is found, and consider any totally unreadable sector as bad and therefore ignore the read errors. Either the sector was actually good, and SPL will catch the image as corrupt or missing a signature, or the sector was actually bad, and the image will run as expected.
...but this seems reasonable as well (it wouldn't work for eLBC/IFC since they need to support tiny SPLs that can only handle raw images). If you want to do this, just put a comment in explaining why you're skipping in that situation.
-Scott
PATCH v6 2/8 lpc32xx: mtd: nand: add MLC NAND controller
Bonjour Scott,
Le Fri, 20 Mar 2015 17:41:11 -0500, Scott Wood
<[email protected]> a ?crit :
Quoted 41 lines · Albert ARIBAUD
Quoted 40 lines
Hi Scott,
Le Thu, 19 Mar 2015 16:39:42 -0500, Scott Wood
<[email protected]> a ?crit :Quoted 7 lines · On Wed, 2015-03-18 at 10:04 +0100, Albert ARIBAUD (3ADEV) wrote:
drivers/mtd/nand/lpc32xx_nand_mlc.c line 673
Quoted 3 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +3
-0+int nand_spl_load_image (uint32_t offs,unsigned int size,void *dst) +{ +int block_good;bool?
Quoted 16 lines
Quoted 4 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +4
-0+struct lpc32xx_oob oob; +unsigned int page, left; + +/* if starting mid-block consider block good */ drivers/mtd/nand/lpc32xx_nand_mlc.c line 687
Quoted 10 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +10
-0+ block_good =1 ; + +for (page = offs /BYTES_PER_PAGE , + left =DIV_ROUND_UP (size,BYTES_PER_PAGE ); + left && (page <PAGES_PER_CHIP_MAX ); page++) { +/* read inband and oob page data anyway */ +int res =read_single_page (dst, page, &oob); +/* return error if a good block's page was not readable */ +if ((res <0 ) && block_good) +return -1 ;Why even try to read it if it's been marked bad?
Actually, at this point, we may not know yet if the block is good or bad, since we might be reading a page of it for the first time. Will fix, see below.
Quoted 4 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c line 688
Quoted 1 line
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +1
-0+/* if first page in a block, update 'block good' status */ The non-SPL driver appears to be checking the last two pages in the block, not the first page.
Thanks for pointing out this discrepancy.
Quoted 7 lines
Quoted 5 lines
I took the first page option here after checking the NAND's datasheet, which says that for factory bad block marking at least, while all pages in a bad block /should/ bear the bad block marker, only the first one is /guaranteed/ to have it. The driver might have inherited the 'last page' option from the previous NAND chip used, or from a mistake of my own.
Are there any plans for this controller to be used with different chips?
Not that I know; but in the same vein, the current LPC32XX maintainer did not consider there were any plans for a few devices in it, and then came my patch series :) so I cannot rule out that someday a new LPC32XX board pops up in U-Boot with another NAND device.
Quoted 5 lines
Quoted 2 lines
BTW, is there a standard way to ask a NAND chip which page(s) in a bad block should be checked?
Yes and no:
http://lists.infradead.org/pipermail/linux-mtd/2011-November/038419.html
... right.
How about this: the driver expects a driver-specific configuration option which tells it which page(s) in a block, and which byte in a page's OOB area, should be scanned for bad block markers, and "my" board provides a value for said option.
This way, when the driver is used with a new NAND chip in another board, it can be configured for this board's specific case.
Quoted 21 lines
Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
drivers/mtd/nand/lpc32xx_nand_mlc.c new file +4
-0+if ((page %PAGES_PER_BLOCK ) ==0 ) { +/* assume block is good */ + block_good =1 ; +/* if page could not be read, assume block is bad */ Quoted 8 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (res < 0) + block_good = 0;No. A block is to be skipped if and only if it has a bad block marker. ECC errors should not be silently ignored just because they happen on the first page of a block. If the writer of this data didn't skip the block, then skipping it when reading will result in unusable data regardless of the underlying ECC problem.
Quoted 7 lines
You're correct of course.
However, I do want the SPL chainloading to be as resilient as possible, and we have established that it will have to read some part of a bad block -- possibly resulting in a read failure -- before knowing that the block is bad, which means it may have to finally ignore the read failure.
Quoted 4 lines
FWIW, the eLBC/IFC SPL functions have the same problem regarding halting on an ECC error before checking the bad block status. Instead it should return an error code, and let the caller halt after it's sure it's not marked bad.
Maybe we could generalize an SPL chainloading common/spl/spl.c routine and have boards /SoCs only provide the hardware-specific page/OOB read function(s) ? Honestly, that would be way beyond my scope for this patch series.
Quoted 37 lines
Quoted 20 lines
I guess I could wait to declare the block good or bad until I could read at least one if its pages (actually, one of its pages' OOB data) properly, only bail out if the OOB says the block is supposed to be good.
Now, if none of the block's pages could be read, this still prevents us from knowing whether these read failures are catastrophic.
If the block was actually bad and skipped, then the resulting image might be intact, will pass the checksum test, and will run; if the block was actually good, SPL will detect it and not boot the corrupt image -- except if the completely unreadable good block was the first one, which holds the signature and checksum, in which case SPL will fall back to considering a raw, unsigned, unverifiable image, and will jump into corrupt code.
This may happen; but I think the probability of having a completely unreadable sector is very low, and the probability of this sector being the first one of the image is very low too [1].
Quoted 5 lines
Which leads me to two possible courses of action:
- consider the risk even though the probabilities are very low, thus consider any totally unreadable sector as good, and bail out in this case, or
I was thinking instead to distinguish between a hard failure where you got no data from the NAND (e.g. a timeout), versus an ECC failure. In the later case you can still look in the OOB for a bad block marker.
Quoted 6 lines
- add an option to SPL that prevents
common/spl/spl.cfrom falling back to running the image as raw if no signature is found, and consider any totally unreadable sector as bad and therefore ignore the read errors. Either the sector was actually good, and SPL will catch the image as corrupt or missing a signature, or the sector was actually bad, and the image will run as expected.
Quoted 2 lines
...but this seems reasonable as well (it wouldn't work for eLBC/IFC since they need to support tiny SPLs that can only handle raw images).
This leads me to a half-OT question: so those SPL, while too tiny to handle non-raw images, still do include the whole common/spl/spl.c and thus contain code which will never apply to them? Then maybe we should have /two/ options, one enabling raw images, and one enabling 'non-raw' images (and at least one enabled for any SPL), so that each SPL could choose what code it wants in. Again, I am not offering to do that in this patch series.
Quoted 2 lines
If you want to do this, just put a comment in explaining why you're skipping in that situation.
Ok -- I will go with the 'option' method then, and add a (lengthy, I'm afraid) comment in common/spl/spl.c explaining that skipping the raw image handling is required when chainloading from NAND and the NAND driver considers totally unreadable sectors bad, in order not to confuse a missing image header with a raw image.
Quoted 1 line
-Scott
Thanks for the feedback!
Cordialement,
Albert ARIBAUD
3ADEV
PATCH v6 2/8 lpc32xx: mtd: nand: add MLC NAND controller
Quoted 12 lines · Albert ARIBAUD
Bonjour Scott,
Le Fri, 20 Mar 2015 17:41:11 -0500, Scott Wood
<[email protected]> a ?crit :Quoted 6 lines · Albert ARIBAUD
Quoted 2 lines
BTW, is there a standard way to ask a NAND chip which page(s) in a bad block should be checked?
Yes and no:
http://lists.infradead.org/pipermail/linux-mtd/2011-November/038419.html
Quoted 6 lines
... right.
How about this: the driver expects a driver-specific configuration option which tells it which page(s) in a block, and which byte in a page's OOB area, should be scanned for bad block markers, and "my" board provides a value for said option.
It looks like the common NAND code will set NAND_BBT_SCANLASTPAGE/NAND_BBT_SCAN2NDPAGE automatically if it sees certain manufacturer IDs, so I don't think drivers should be setting them at all (and currently, none do).
That still leaves the question of what to do in SPL. For simplicity you could check every page as you do the normal read.
Quoted 2 lines
This leads me to a half-OT question: so those SPL, while too tiny to handle non-raw images, still do include the whole
common/spl/spl.c
No, there's no room for that.
Quoted 8 lines
Quoted 2 lines
If you want to do this, just put a comment in explaining why you're skipping in that situation.
Ok -- I will go with the 'option' method then, and add a (lengthy, I'm afraid) comment in
common/spl/spl.cexplaining that skipping the raw image handling is required when chainloading from NAND and the NAND driver considers totally unreadable sectors bad, in order not to confuse a missing image header with a raw image.
Skipping raw wouldn't be needed for all NAND drivers, only those that aren't guaranteed to halt on a legitimate unrecoverable ECC error.
-Scott
PATCH v6 2/8 lpc32xx: mtd: nand: add MLC NAND controller
Hi Scott,
Le Mon, 23 Mar 2015 20:20:50 -0500, Scott Wood
<[email protected]> a ?crit :
Quoted 20 lines · Albert ARIBAUD
Quoted 12 lines
Bonjour Scott,
Le Fri, 20 Mar 2015 17:41:11 -0500, Scott Wood
<[email protected]> a ?crit :Quoted 6 lines · Albert ARIBAUD
Quoted 2 lines
BTW, is there a standard way to ask a NAND chip which page(s) in a bad block should be checked?
Yes and no:
http://lists.infradead.org/pipermail/linux-mtd/2011-November/038419.htmlQuoted 6 lines
... right.
How about this: the driver expects a driver-specific configuration option which tells it which page(s) in a block, and which byte in a page's OOB area, should be scanned for bad block markers, and "my" board provides a value for said option.
Quoted 4 lines
It looks like the common NAND code will set NAND_BBT_SCANLASTPAGE/NAND_BBT_SCAN2NDPAGE automatically if it sees certain manufacturer IDs, so I don't think drivers should be setting them at all (and currently, none do).
Ok.
Quoted 2 lines
That still leaves the question of what to do in SPL. For simplicity you could check every page as you do the normal read.
Ok. Patch series v7 to follow... as soon as I have completed it.
Quoted 4 lines
Quoted 2 lines
This leads me to a half-OT question: so those SPL, while too tiny to handle non-raw images, still do include the whole
common/spl/spl.cNo, there's no room for that.
Ok.
Quoted 11 lines
Quoted 8 lines
Quoted 2 lines
If you want to do this, just put a comment in explaining why you're skipping in that situation.
Ok -- I will go with the 'option' method then, and add a (lengthy, I'm afraid) comment in
common/spl/spl.cexplaining that skipping the raw image handling is required when chainloading from NAND and the NAND driver considers totally unreadable sectors bad, in order not to confuse a missing image header with a raw image.Skipping raw wouldn't be needed for all NAND drivers, only those that aren't guaranteed to halt on a legitimate unrecoverable ECC error.
Understood.
Quoted 1 line
-Scott
Cordialement,
Albert ARIBAUD
3ADEV