...
 
Commits (30)
......@@ -763,7 +763,7 @@ int arch_cpu_init(void)
self.cfile+='\tuart_wait_tx_fifo_empty(); /* Second time - for some reason 1 wait sometimes fails after LAST_PRINT_DEBUG */\n'
self.cfile+='''/* set up the CPU clk clock frequency in the global data struct */
zynq_clk_early_init();
//zynq_clk_early_init();
'''
#LOCK_SLCR
......@@ -785,4 +785,4 @@ int arch_cpu_init(void)
c_out_file=open(cname,'w')
c_out_file.write(self.cfile)
c_out_file.close()
\ No newline at end of file
if ARCH_ZYNQ
config ZYNQ_CUSTOM_INIT
bool "Use custom ps7_init provided by Xilinx tool"
help
U-Boot includes ps7_init_gpl.[ch] for some Zynq board variants.
If you want to override them with customized ones
or ps7_init code for your board is missing, please say Y here
and add ones into board/xilinx/zynq/custom_hw_platform/ directory.
config TARGET_ELPHEL393
bool "Elphel 10393 Zynq Board"
default y
choice
prompt "Xilinx Zynq board select"
default TARGET_ZYNQ_ZC702
config SPL_LDSCRIPT
default "arch/arm/mach-zynq/u-boot-spl.lds"
config TARGET_ZYNQ_ZED
bool "Zynq ZedBoard"
config SPL_FAT_SUPPORT
default y
config TARGET_ZYNQ_MICROZED
bool "Zynq MicroZed"
config SPL_LIBCOMMON_SUPPORT
default y
config TARGET_ZYNQ_PICOZED
bool "Zynq PicoZed"
config SPL_LIBDISK_SUPPORT
default y
config TARGET_ZYNQ_ZC702
bool "Zynq ZC702 Board"
config SPL_LIBGENERIC_SUPPORT
default y
config TARGET_ZYNQ_ZC706
bool "Zynq ZC706 Board"
config SPL_MMC_SUPPORT
default y if MMC_SDHCI_ZYNQ
config TARGET_ZYNQ_ZC770
bool "Zynq ZC770 Board"
select ZYNQ_CUSTOM_INIT
config SPL_SERIAL_SUPPORT
default y
config TARGET_ZYNQ_ZYBO
bool "Zynq Zybo Board"
config SPL_SPI_FLASH_SUPPORT
default y if ZYNQ_QSPI
config TARGET_ELPHEL393
bool "Zynq Elphel 10393 Board"
endchoice
config SPL_SPI_SUPPORT
default y if ZYNQ_QSPI
config ZYNQ_DDRC_INIT
bool "Zynq DDRC initialization"
default y
help
This option used to perform DDR specific initialization
if required. There might be cases like ddr less where we
want to skip ddr init and this option is useful for it.
config SYS_BOARD
string "Board name"
default "elphel393" if TARGET_ELPHEL393
default "zynq"
config SYS_VENDOR
string "Vendor name"
default "elphel" if TARGET_ELPHEL393
default "xilinx"
......@@ -51,13 +53,28 @@ config SYS_SOC
default "zynq"
config SYS_CONFIG_NAME
default "zynq_zed" if TARGET_ZYNQ_ZED
default "zynq_microzed" if TARGET_ZYNQ_MICROZED
default "zynq_picozed" if TARGET_ZYNQ_PICOZED
default "zynq_zc70x" if TARGET_ZYNQ_ZC702
default "zynq_zc706" if TARGET_ZYNQ_ZC706
default "zynq_zc770" if TARGET_ZYNQ_ZC770
default "zynq_zybo" if TARGET_ZYNQ_ZYBO
string "Board configuration name"
default "elphel393" if TARGET_ELPHEL393
default "zynq-common"
help
This option contains information about board configuration name.
Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
will be used for board configuration.
config SYS_MALLOC_F_LEN
default 0x600
config SYS_MALLOC_LEN
default 0x1400000
config BOOT_INIT_FILE
string "boot.bin init register filename"
default ""
help
Add register writes to boot.bin format (max 256 pairs).
Expect a table of register-value pairs, e.g. "0x12345678 0x4321"
config ZYNQ_SDHCI_MAX_FREQ
default 52000000
endif
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2000-2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# (C) Copyright 2008
# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := timer.o
obj-y += cpu.o
......@@ -24,4 +22,4 @@ endif
obj-y += clk.o
obj-y += lowlevel_init.o
AFLAGS_lowlevel_init.o := -mfpu=neon
obj-$(CONFIG_SPL_BUILD) += spl.o
obj-$(CONFIG_SPL_BUILD) += spl.o ps7_spl_init.o
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
* Copyright (C) 2012 Xilinx, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <zynqpl.h>
#include <asm/io.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/hardware.h>
#include <asm/arch/clk.h>
#include <asm/arch/hardware.h>
#include <asm/arch/ps7_init_gpl.h>
#include <asm/arch/sys_proto.h>
#define ZYNQ_SILICON_VER_MASK 0xF0000000
#define ZYNQ_SILICON_VER_SHIFT 28
/* Added __weak because the function is overridden in ezynq.c */
#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
(defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
xilinx_desc fpga = {
.family = xilinx_zynq,
.iface = devcfg,
.operations = &zynq_op,
};
#endif
static const struct {
u8 idcode;
#if defined(CONFIG_FPGA)
u32 fpga_size;
#endif
char *devicename;
} zynq_fpga_descs[] = {
ZYNQ_DESC(7Z007S),
ZYNQ_DESC(7Z010),
ZYNQ_DESC(7Z012S),
ZYNQ_DESC(7Z014S),
ZYNQ_DESC(7Z015),
ZYNQ_DESC(7Z020),
ZYNQ_DESC(7Z030),
ZYNQ_DESC(7Z035),
ZYNQ_DESC(7Z045),
ZYNQ_DESC(7Z100),
{ /* Sentinel */ },
};
/* ELPHEL: Added __weak because the function is overridden in ezynq.c */
__weak int arch_cpu_init(void)
{
zynq_slcr_unlock();
......@@ -36,7 +66,6 @@ __weak int arch_cpu_init(void)
writel(0xC, &slcr_base->ddr_urgent);
#endif
#endif
zynq_clk_early_init();
zynq_slcr_lock();
return 0;
......@@ -44,12 +73,8 @@ __weak int arch_cpu_init(void)
unsigned int zynq_get_silicon_version(void)
{
unsigned int ver;
ver = (readl(&devcfg_base->mctrl) &
ZYNQ_SILICON_VER_MASK) >> ZYNQ_SILICON_VER_SHIFT;
return ver;
return (readl(&devcfg_base->mctrl) & ZYNQ_SILICON_VER_MASK)
>> ZYNQ_SILICON_VER_SHIFT;
}
void reset_cpu(ulong addr)
......@@ -62,7 +87,59 @@ void reset_cpu(ulong addr)
#ifndef CONFIG_SYS_DCACHE_OFF
void enable_caches(void)
{
/* Enable D-cache. I-cache is already enabled in start.S */
dcache_enable();
/* Enable D-cache. I-cache is already enabled in start.S */
dcache_enable();
}
#endif
static int __maybe_unused cpu_desc_id(void)
{
u32 idcode;
u8 i;
idcode = zynq_slcr_get_idcode();
for (i = 0; zynq_fpga_descs[i].idcode; i++) {
if (zynq_fpga_descs[i].idcode == idcode)
return i;
}
return -ENODEV;
}
#if defined(CONFIG_ARCH_EARLY_INIT_R)
int arch_early_init_r(void)
{
#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
(defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
int cpu_id = cpu_desc_id();
if (cpu_id < 0)
return 0;
fpga.size = zynq_fpga_descs[cpu_id].fpga_size;
fpga.name = zynq_fpga_descs[cpu_id].devicename;
fpga_init();
fpga_add(fpga_xilinx, &fpga);
#endif
return 0;
}
#endif
#ifdef CONFIG_DISPLAY_CPUINFO
int print_cpuinfo(void)
{
u32 version;
int cpu_id = cpu_desc_id();
if (cpu_id < 0)
return 0;
version = zynq_get_silicon_version() << 1;
if (version > (PCW_SILICON_VERSION_3 << 1))
version += 1;
printf("CPU: Zynq %s\n", zynq_fpga_descs[cpu_id].devicename);
printf("Silicon: v%d.%d\n", version >> 1, version & 1);
return 0;
}
#endif
/*
* Copyright (c) 2013 Xilinx Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/io.h>
#include <malloc.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/clk.h>
#define SLCR_LOCK_MAGIC 0x767B
#define SLCR_UNLOCK_MAGIC 0xDF0D
#define SLCR_QSPI_ENABLE 0x02
#define SLCR_QSPI_ENABLE_MASK 0x03
#define SLCR_NAND_L2_SEL 0x10
#define SLCR_NAND_L2_SEL_MASK 0x1F
#define SLCR_USB_L1_SEL 0x04
#define SLCR_IDCODE_MASK 0x1F000
#define SLCR_IDCODE_SHIFT 12
/*
* zynq_slcr_mio_get_status - Get the status of MIO peripheral.
*
* @peri_name: Name of the peripheral for checking MIO status
* @get_pins: Pointer to array of get pin for this peripheral
* @num_pins: Number of pins for this peripheral
* @mask: Mask value
* @check_val: Required check value to get the status of periph
*/
struct zynq_slcr_mio_get_status {
const char *peri_name;
const int *get_pins;
int num_pins;
u32 mask;
u32 check_val;
};
static const int qspi0_pins[] = {
1, 2, 3, 4, 5, 6
};
static const int qspi1_cs_pin[] = {
0
};
static const int qspi1_pins[] = {
9, 10, 11, 12, 13
};
static const int qspi0_dio_pins[] = {
1, 2, 3, 6
};
static const int qspi1_cs_dio_pin[] = {
0
};
static const int qspi1_dio_pins[] = {
9, 10, 11
};
static const int nand8_pins[] = {
0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
};
static const int nand16_pins[] = {
16, 17, 18, 19, 20, 21, 22, 23
};
static const int usb0_pins[] = {
28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39
};
static const int usb1_pins[] = {
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
};
static const struct zynq_slcr_mio_get_status mio_periphs[] = {
{
"qspi0",
qspi0_pins,
ARRAY_SIZE(qspi0_pins),
SLCR_QSPI_ENABLE_MASK,
SLCR_QSPI_ENABLE,
},
{
"qspi1_cs",
qspi1_cs_pin,
ARRAY_SIZE(qspi1_cs_pin),
SLCR_QSPI_ENABLE_MASK,
SLCR_QSPI_ENABLE,
},
{
"qspi1",
qspi1_pins,
ARRAY_SIZE(qspi1_pins),
SLCR_QSPI_ENABLE_MASK,
SLCR_QSPI_ENABLE,
},
{
"qspi0_dio",
qspi0_dio_pins,
ARRAY_SIZE(qspi0_dio_pins),
SLCR_QSPI_ENABLE_MASK,
SLCR_QSPI_ENABLE,
},
{
"qspi1_cs_dio",
qspi1_cs_dio_pin,
ARRAY_SIZE(qspi1_cs_dio_pin),
SLCR_QSPI_ENABLE_MASK,
SLCR_QSPI_ENABLE,
},
{
"qspi1_dio",
qspi1_dio_pins,
ARRAY_SIZE(qspi1_dio_pins),
SLCR_QSPI_ENABLE_MASK,
SLCR_QSPI_ENABLE,
},
{
"nand8",
nand8_pins,
ARRAY_SIZE(nand8_pins),
SLCR_NAND_L2_SEL_MASK,
SLCR_NAND_L2_SEL,
},
{
"nand16",
nand16_pins,
ARRAY_SIZE(nand16_pins),
SLCR_NAND_L2_SEL_MASK,
SLCR_NAND_L2_SEL,
},
{
"usb0",
usb0_pins,
ARRAY_SIZE(usb0_pins),
SLCR_USB_L1_SEL,
SLCR_USB_L1_SEL,
},
{
"usb1",
usb1_pins,
ARRAY_SIZE(usb1_pins),
SLCR_USB_L1_SEL,
SLCR_USB_L1_SEL,
},
};
static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */
void zynq_slcr_lock(void)
{
if (!slcr_lock) {
writel(SLCR_LOCK_MAGIC, &slcr_base->slcr_lock);
slcr_lock = 1;
}
}
void zynq_slcr_unlock(void)
{
if (slcr_lock) {
writel(SLCR_UNLOCK_MAGIC, &slcr_base->slcr_unlock);
slcr_lock = 0;
}
}
/* Reset the entire system */
void zynq_slcr_cpu_reset(void)
{
/*
* Unlock the SLCR then reset the system.
* Note that this seems to require raw i/o
* functions or there's a lockup?
*/
zynq_slcr_unlock();
/*
* Clear 0x0F000000 bits of reboot status register to workaround
* the FSBL not loading the bitstream after soft-reboot
* This is a temporary solution until we know more.
*/
clrbits_le32(&slcr_base->reboot_status, 0xF000000);
writel(1, &slcr_base->pss_rst_ctrl);
}
/* Setup clk for network */
void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate)
{
int ret;
zynq_slcr_unlock();
if (gem_id > 1) {
printf("Non existing GEM id %d\n", gem_id);
goto out;
}
ret = zynq_clk_set_rate(gem0_clk + gem_id, clk_rate);
if (ret)
goto out;
if (gem_id) {
/* Configure GEM_RCLK_CTRL */
writel(1, &slcr_base->gem1_rclk_ctrl);
} else {
/* Configure GEM_RCLK_CTRL */
writel(1, &slcr_base->gem0_rclk_ctrl);
}
udelay(100000);
out:
zynq_slcr_lock();
}
void zynq_slcr_devcfg_disable(void)
{
u32 reg_val;
zynq_slcr_unlock();
/* Disable AXI interface by asserting FPGA resets */
writel(0xF, &slcr_base->fpga_rst_ctrl);
/* Disable Level shifters before setting PS-PL */
reg_val = readl(&slcr_base->lvl_shftr_en);
reg_val &= ~0xF;
writel(reg_val, &slcr_base->lvl_shftr_en);
/* Set Level Shifters DT618760 */
writel(0xA, &slcr_base->lvl_shftr_en);
zynq_slcr_lock();
}
void zynq_slcr_devcfg_enable(void)
{
zynq_slcr_unlock();
/* Set Level Shifters DT618760 */
writel(0xF, &slcr_base->lvl_shftr_en);
/* Enable AXI interface by de-asserting FPGA resets */
writel(0x0, &slcr_base->fpga_rst_ctrl);
zynq_slcr_lock();
}
u32 zynq_slcr_get_boot_mode(void)
{
/* Get the bootmode register value */
return readl(&slcr_base->boot_mode);
}
u32 zynq_slcr_get_idcode(void)
{
return (readl(&slcr_base->pss_idcode) & SLCR_IDCODE_MASK) >>
SLCR_IDCODE_SHIFT;
}
/*
* zynq_slcr_get_mio_pin_status - Get the MIO pin status of peripheral.
*
* @periph: Name of the peripheral
*
* Returns count to indicate the number of pins configured for the
* given @periph.
*/
int zynq_slcr_get_mio_pin_status(const char *periph)
{
const struct zynq_slcr_mio_get_status *mio_ptr;
int val, i, j;
int mio = 0;
for (i = 0; i < ARRAY_SIZE(mio_periphs); i++) {
if (strcmp(periph, mio_periphs[i].peri_name) == 0) {
mio_ptr = &mio_periphs[i];
for (j = 0; j < mio_ptr->num_pins; j++) {
val = readl(&slcr_base->mio_pin
[mio_ptr->get_pins[j]]);
if ((val & mio_ptr->mask) == mio_ptr->check_val)
mio++;
}
break;
}
}
return mio;
}
/*
* (C) Copyright 2014 Xilinx, Inc. Michal Simek
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <debug_uart.h>
#include <spl.h>
#include <asm/io.h>
#include <asm/spl.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
#ifndef CONFIG_EZYNQ
__weak void ps7_init(void)
{
puts("Please copy ps7_init.c/h from hw project\n");
}
#endif
DECLARE_GLOBAL_DATA_PTR;
void board_init_f(ulong dummy)
{
/* Clear the BSS. */
//memset(__bss_start, 0, __bss_end - __bss_start);
/* Set global data pointer. */
//gd = &gdata;
#ifndef CONFIG_EZYNQ
ps7_init();
#endif
arch_cpu_init();
#ifdef CONFIG_EZYNQ
puts("NOT REQUIRED: Copying ps7_init.c/h from hw project\n");
#endif
// board_init_r(NULL, 0);
}
#ifdef CONFIG_SPL_BOARD_INIT
void spl_board_init(void)
{
preloader_console_init();
board_init();
}
#endif
u32 spl_boot_device(void)
{
u32 mode;
switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
#ifdef CONFIG_SPL_SPI_SUPPORT
case ZYNQ_BM_QSPI:
puts("qspi boot\n");
mode = BOOT_DEVICE_SPI;
break;
#endif
case ZYNQ_BM_NAND:
mode = BOOT_DEVICE_NAND;
break;
case ZYNQ_BM_NOR:
mode = BOOT_DEVICE_NOR;
break;
#ifdef CONFIG_SPL_MMC_SUPPORT
case ZYNQ_BM_SD:
puts("mmc boot\n");
mode = BOOT_DEVICE_MMC1;
break;
#endif
case ZYNQ_BM_JTAG:
mode = BOOT_DEVICE_RAM;
break;
default:
puts("Unsupported boot mode selected\n");
hang();
}
return mode;
}
#ifdef CONFIG_SPL_MMC_SUPPORT
u32 spl_boot_mode(void)
{
return MMCSD_MODE_FS;
}
#endif
#ifdef CONFIG_SPL_OS_BOOT
int spl_start_uboot(void)
{
/* boot linux */
return 0;
}
#endif
......@@ -75,19 +75,19 @@ int board_late_init(void)
{
switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
case ZYNQ_BM_NOR:
setenv("modeboot", "norboot");
env_set("modeboot", "norboot");
break;
case ZYNQ_BM_SD:
setenv("modeboot", "sdboot");
env_set("modeboot", "sdboot");
break;
case ZYNQ_BM_NAND:
setenv("modeboot", "nandboot");
env_set("modeboot", "nandboot");
break;
case ZYNQ_BM_JTAG:
setenv("modeboot", "jtagboot");
env_set("modeboot", "jtagboot");
break;
default:
setenv("modeboot", "");
env_set("modeboot", "");
break;
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -8,7 +8,8 @@ CONFIG_FIT_VERBOSE=y
CONFIG_FIT_SIGNATURE=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y
#CONFIG_CMD_GPIO=y
CONFIG_CMD_GPIO=n
# CONFIG_CMD_SETEXPR is not set
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPI_FLASH=n
......@@ -32,3 +33,18 @@ CONFIG_CMD_BOOTEFI=n
CONFIG_CMD_FAT=y
CONFIG_CMD_MMC=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_MALLOC_LEN=0x2000000
CONFIG_SYS_TEXT_BASE=0x4000000
CONFIG_CMD_UBI=y
# copied from microzed_defconfig
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_SPL_NAND_IDENT=y
CONFIG_SPL_DOS_PARTITION=y
CONFIG_SPL_BLK=y
CONFIG_SPL_DM=y
CONFIG_BLK=y
CONFIG_ARM=y
CONFIG_ARCH_ZYNQ=y
CONFIG_TARGET_ZYNQ_MICROZED=y
CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed"
CONFIG_SPL=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_FIT_SIGNATURE=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPI_FLASH=n
CONFIG_SPI_FLASH_SPANSION=n
CONFIG_SPI_FLASH_STMICRO=n
CONFIG_SPI_FLASH_WINBOND=n
CONFIG_ZYNQ_GEM=n
CONFIG_ZYNQ_QSPI=n
CONFIG_OF_SEPARATE=y
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
ifdef CONFIG_SPL_BUILD
......@@ -13,7 +11,6 @@ endif
obj-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o
obj-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o
obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
obj-$(CONFIG_SPL_NAND_ELPHEL393) += elphel393_nand_spl.o
obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
......@@ -21,8 +18,9 @@ obj-$(CONFIG_SPL_NAND_BBT) += nand_bbt.o
obj-$(CONFIG_SPL_NAND_IDS) += nand_ids.o
obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o
obj-$(CONFIG_SPL_NAND_IDENT) += nand_ids.o nand_timings.o
obj-$(CONFIG_SPL_NAND_INIT) += nand.o
obj-$(CONFIG_SPL_NAND_INIT) += ../mtdcore.o ../mtd_uboot.o
obj-$(CONFIG_SPL_NAND_INIT) += ../../mtdcore.o ../../mtd_uboot.o
ifeq ($(CONFIG_SPL_ENV_SUPPORT),y)
obj-$(CONFIG_ENV_IS_IN_NAND) += nand_util.o
endif
......@@ -47,32 +45,29 @@ obj-$(CONFIG_NAND_ECC_BCH) += nand_bch.o
obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o
obj-$(CONFIG_NAND_ARASAN) += arasan_nfc.o
obj-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o
obj-$(CONFIG_NAND_DAVINCI) += davinci_nand.o
obj-$(CONFIG_NAND_DENALI) += denali.o
obj-$(CONFIG_NAND_DENALI_DT) += denali_dt.o
obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o
obj-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
obj-$(CONFIG_NAND_FSMC) += fsmc_nand.o
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_LPC32XX_SLC) += lpc32xx_nand_slc.o
obj-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o
obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o
obj-$(CONFIG_NAND_MXC) += mxc_nand.o
obj-$(CONFIG_NAND_MXS) += mxs_nand.o
obj-$(CONFIG_NAND_NDFC) += ndfc.o
obj-$(CONFIG_NAND_MXS_DT) += mxs_nand_dt.o
obj-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o
obj-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
obj-$(CONFIG_NAND_SPEAR) += spr_nand.o
obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o
obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o
obj-$(CONFIG_NAND_PLAT) += nand_plat.o
obj-$(CONFIG_NAND_DOCG4) += docg4.o
obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o
obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o
else # minimal SPL drivers
......
......@@ -9,7 +9,7 @@
#include <common.h>
#include <malloc.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <linux/errno.h>
#include <nand.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
......@@ -18,11 +18,12 @@
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
extern nand_info_t nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
//extern nand_info_t nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
static struct mtd_info *mtd;
static int is_badblock(struct mtd_info *mtd, loff_t offs, int allowbbt)
{
register struct nand_chip *chip = mtd->priv;
register struct nand_chip *chip = mtd_to_nand(mtd);
unsigned int block = offs >> chip->phys_erase_shift;
unsigned int page = offs >> chip->page_shift;
unsigned long data_width = 4;
......@@ -51,9 +52,11 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf)
udelay(10000);
//if (mxs_nand_init()) return -ENODEV;
mtd = &nand_info[0];
//mtd = &nand_info[0];
//mtd.priv = &nand_chip;
chip = mtd->priv;
//chip = mtd->priv;
chip = mtd_to_nand(mtd);
page = offs >> chip->page_shift;
nand_page_per_block = mtd->erasesize / mtd->writesize;
......
This diff is collapsed.
......@@ -42,6 +42,7 @@
#endif
#define CONFIG_SPL_NAND_ELPHEL393
#define CONFIG_SPL_NAND_IDENT
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x100000 /*look-up in dts!*/
......@@ -61,6 +62,8 @@
#define CONFIG_SPL_NAND_BBT
#define CONFIG_SPL_NAND_IDS
//#define CONFIG_SPL_BLK
/* Load U-Boot to this address */
#define CONFIG_SYS_NAND_U_BOOT_DST CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_NAND_U_BOOT_DST
......@@ -100,13 +103,15 @@
#define CONFIG_MTD_DEVICE
#define CONFIG_SPL_STACK_R_ADDR 0x200000
/* UBI support in full U-Boot */
#define CONFIG_MTD_PARTITIONS
//#define CONFIG_MTD_PARTITIONS
#define CONFIG_CMD_MTDPARTS
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#define CONFIG_RBTREE
#define CONFIG_LZO
//#define CONFIG_CMD_UBI
//#define CONFIG_CMD_UBIFS
//#define CONFIG_RBTREE
//#define CONFIG_LZO
#define MTDIDS_DEFAULT "nand0=nand"
#define MTDPARTS_DEFAULT "mtdparts=nand:1m(u-boot-spl)," \
"4m(u-boot)," \
......
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> et al.
*
* SPDX-License-Identifier: GPL-2.0+
*
*/
#ifndef __MTD_MTD_H__
......@@ -20,8 +19,12 @@
#else
#include <linux/compat.h>
#include <mtd/mtd-abi.h>
#include <asm/errno.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <div64.h>
#if IS_ENABLED(CONFIG_DM)
#include <dm/device.h>
#endif
#define MAX_MTD_DEVICES 32
#endif
......@@ -76,10 +79,6 @@ struct mtd_erase_region_info {
* mode = MTD_OPS_PLACE_OOB or MTD_OPS_RAW)
* @datbuf: data buffer - if NULL only oob data are read/written
* @oobbuf: oob data buffer
*
* Note, it is allowed to read more than one OOB area at one go, but not write.
* The interface assumes that the OOB write requests program only one page's
* OOB area.
*/
struct mtd_oob_ops {
unsigned int mode;
......@@ -103,6 +102,36 @@ struct mtd_oob_ops {
#else
#define MTD_MAX_ECCPOS_ENTRIES_LARGE 680
#endif
/**
* struct mtd_oob_region - oob region definition
* @offset: region offset
* @length: region length
*
* This structure describes a region of the OOB area, and is used
* to retrieve ECC or free bytes sections.
* Each section is defined by an offset within the OOB area and a
* length.
*/
struct mtd_oob_region {
u32 offset;
u32 length;
};
/*
* struct mtd_ooblayout_ops - NAND OOB layout operations
* @ecc: function returning an ECC region in the OOB area.
* Should return -ERANGE if %section exceeds the total number of
* ECC sections.
* @free: function returning a free region in the OOB area.
* Should return -ERANGE if %section exceeds the total number of
* free sections.
*/
struct mtd_ooblayout_ops {
int (*ecc)(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobecc);
int (*free)(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobfree);
};
/*
* Internal ECC layout control structure. For historical reasons, there is a
......@@ -179,6 +208,9 @@ struct mtd_info {
#endif
int index;
/* OOB layout description */
const struct mtd_ooblayout_ops *ooblayout;
/* ECC layout structure pointer - read only! */
struct nand_ecclayout *ecclayout;
......@@ -276,8 +308,93 @@ struct mtd_info {
struct udevice *dev;
#endif
int usecount;
/* MTD devices do not have any parent. MTD partitions do. */
struct mtd_info *parent;
/*
* Offset of the partition relatively to the parent offset.
* Is 0 for real MTD devices (ie. not partitions).
*/
u64 offset;
/*
* List node used to add an MTD partition to the parent
* partition list.
*/
struct list_head node;
/*
* List of partitions attached to this MTD device (the parent
* MTD device can itself be a partition).
*/
struct list_head partitions;
};
#if IS_ENABLED(CONFIG_DM)
static inline void mtd_set_of_node(struct mtd_info *mtd,
const struct device_node *np)
{
mtd->dev->node.np = np;
}
static inline const struct device_node *mtd_get_of_node(struct mtd_info *mtd)
{
return mtd->dev->node.np;
}
#else
struct device_node;
static inline void mtd_set_of_node(struct mtd_info *mtd,
const struct device_node *np)
{
}
static inline const struct device_node *mtd_get_of_node(struct mtd_info *mtd)
{
return NULL;
}
#endif
static inline bool mtd_is_partition(const struct mtd_info *mtd)
{
return mtd->parent;
}
static inline bool mtd_has_partitions(const struct mtd_info *mtd)
{
return !list_empty(&mtd->partitions);
}
int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobecc);
int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte,
int *section,
struct mtd_oob_region *oobregion);
int mtd_ooblayout_get_eccbytes(struct mtd_info *mtd, u8 *eccbuf,
const u8 *oobbuf, int start, int nbytes);
int mtd_ooblayout_set_eccbytes(struct mtd_info *mtd, const u8 *eccbuf,
u8 *oobbuf, int start, int nbytes);
int mtd_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobfree);
int mtd_ooblayout_get_databytes(struct mtd_info *mtd, u8 *databuf,
const u8 *oobbuf, int start, int nbytes);
int mtd_ooblayout_set_databytes(struct mtd_info *mtd, const u8 *databuf,
u8 *oobbuf, int start, int nbytes);
int mtd_ooblayout_count_freebytes(struct mtd_info *mtd);
int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd);
static inline void mtd_set_ooblayout(struct mtd_info *mtd,
const struct mtd_ooblayout_ops *ooblayout)
{
mtd->ooblayout = ooblayout;
}
static inline int mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops)
{
return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize;
}
int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
#ifndef __UBOOT__
int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
......@@ -294,17 +411,7 @@ int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
const u_char *buf);
int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
{
ops->retlen = ops->oobretlen = 0;
if (!mtd->_write_oob)
return -EOPNOTSUPP;
if (!(mtd->flags & MTD_WRITEABLE))
return -EROFS;
return mtd->_write_oob(mtd, to, ops);
}
int mtd_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops);
int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
struct otp_info *buf);
......@@ -427,6 +534,7 @@ extern int unregister_mtd_user (struct mtd_notifier *old);
#endif
void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size);
/* ELPHEL */
/*#ifdef CONFIG_MTD_PARTITIONS*/
#if defined(CONFIG_MTD_PARTITIONS) && !defined(CONFIG_SPL_BUILD)
void mtd_erase_callback(struct erase_info *instr);
......@@ -438,38 +546,6 @@ static inline void mtd_erase_callback(struct erase_info *instr)
}
#endif
#ifdef __UBOOT__
/*
* Debugging macro and defines
*/
#define MTD_DEBUG_LEVEL0 (0) /* Quiet */
#define MTD_DEBUG_LEVEL1 (1) /* Audible */
#define MTD_DEBUG_LEVEL2 (2) /* Loud */
#define MTD_DEBUG_LEVEL3 (3) /* Noisy */
#ifdef CONFIG_MTD_DEBUG
#define pr_debug(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#define MTDDEBUG(n, args...) \
do { \
if (n <= CONFIG_MTD_DEBUG_VERBOSE) \
printk(KERN_INFO args); \
} while(0)
#else /* CONFIG_MTD_DEBUG */
#define pr_debug(args...)
#define MTDDEBUG(n, args...) \
do { \
if (0) \
printk(KERN_INFO args); \
} while(0)
#endif /* CONFIG_MTD_DEBUG */
#define pr_info(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#define pr_warn(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#define pr_err(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#define pr_crit(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#define pr_cont(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#define pr_notice(args...) MTDDEBUG(MTD_DEBUG_LEVEL0, args)
#endif
static inline int mtd_is_bitflip(int err) {
return err == -EUCLEAN;
}
......@@ -491,10 +567,26 @@ int del_mtd_device(struct mtd_info *mtd);
int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
int del_mtd_partitions(struct mtd_info *);
struct mtd_info *__mtd_next_device(int i);
#define mtd_for_each_device(mtd) \
for ((mtd) = __mtd_next_device(0); \
(mtd) != NULL; \
(mtd) = __mtd_next_device(mtd->index + 1))
int mtd_arg_off(const char *arg, int *idx, loff_t *off, loff_t *size,
loff_t *maxsize, int devtype, uint64_t chipsize);
int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off,
loff_t *size, loff_t *maxsize, int devtype,
uint64_t chipsize);
/* drivers/mtd/mtdcore.c */
void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset,
const uint64_t length, uint64_t *len_incl_bad,
int *truncated);
/* drivers/mtd/mtd_uboot.c */
int mtd_search_alternate_name(const char *mtdname, char *altname,
unsigned int max_len);
#endif
#endif /* __MTD_MTD_H__ */