#ifndef CONFIG_SKIP_LOWLEVEL_INIT
/*
+ * In the case of non-SPL based booting we'll want to call these
+ * functions a tiny bit later as it will require gd to be set and cleared
+ * and that's not true in s_init in this case so we cannot do it there.
+ */
+int board_early_init_f(void)
+{
+ prcm_init();
+ set_mux_conf_regs();
+
+ return 0;
+}
+
+/*
* This function is the place to do per-board things such as ramp up the
* MPU clock frequency.
*/
set_uart_mux_conf();
setup_clocks_for_console();
uart_soft_reset();
-#ifdef CONFIG_NOR_BOOT
+#if defined(CONFIG_NOR_BOOT) || defined(CONFIG_QSPI_BOOT)
gd->baudrate = CONFIG_BAUDRATE;
serial_init();
gd->have_console = 1;
gd = &gdata;
preloader_console_init();
#endif
- prcm_init();
- set_mux_conf_regs();
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
/* Enable RTC32K clock */
rtc32k_enable();
#endif
+#ifdef CONFIG_SPL_BUILD
+ board_early_init_f();
sdram_init();
+#endif
}
#endif
};
}
+/*
+ * Before scaling up the clocks we need to have the PMIC scale up the
+ * voltages first. This will be dependent on which PMIC is in use
+ * and in some cases we may not be scaling things up at all and thus not
+ * need to do anything here.
+ */
+__weak void scale_vcores(void)
+{
+}
+
void prcm_init()
{
enable_basic_clocks();
+ scale_vcores();
setup_dplls();
}
void setup_clocks_for_console(void)
{
+ u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED;
+
/* Do not add any spl_debug prints in this function */
clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
CD_CLKCTRL_CLKTRCTRL_SW_WKUP <<
MODULE_CLKCTRL_MODULEMODE_MASK,
MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
MODULE_CLKCTRL_MODULEMODE_SHIFT);
+
+ while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) ||
+ (idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) {
+ clkctrl = readl(&cmwkup->wkup_uart0ctrl);
+ idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
+ MODULE_CLKCTRL_IDLEST_SHIFT;
+ }
}
void enable_basic_clocks(void)
int dram_init(void)
{
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ sdram_init();
+#endif
+
/* dram_init must store complete ramsize in gd->ram_size */
gd->ram_size = get_ram_size(
(void *)CONFIG_SYS_SDRAM_BASE,
*/
#include <common.h>
+#include <ns16550.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/hardware.h>
share_all_segments(11); /* PCIE */
#endif
+ /*
+ * just initialise the COM2 port so that TI specific
+ * UART register PWREMU_MGMT is initialized. Linux UART
+ * driver doesn't handle this.
+ */
+ NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM2),
+ CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE);
+
return 0;
}
struct gpmc *gpmc_cfg;
#if defined(CONFIG_CMD_NAND)
-#if defined(GPMC_NAND_ECC_SP_x8_LAYOUT) || defined(GPMC_NAND_ECC_LP_x8_LAYOUT)
-static const u32 gpmc_m_nand[GPMC_MAX_REG] = {
- SMNAND_GPMC_CONFIG1,
- SMNAND_GPMC_CONFIG2,
- SMNAND_GPMC_CONFIG3,
- SMNAND_GPMC_CONFIG4,
- SMNAND_GPMC_CONFIG5,
- SMNAND_GPMC_CONFIG6,
- 0,
-};
-#else
static const u32 gpmc_m_nand[GPMC_MAX_REG] = {
M_NAND_GPMC_CONFIG1,
M_NAND_GPMC_CONFIG2,
M_NAND_GPMC_CONFIG5,
M_NAND_GPMC_CONFIG6, 0
};
-#endif
#endif /* CONFIG_CMD_NAND */
#if defined(CONFIG_CMD_ONENAND)
const struct dpll_params *get_dpll_core_params(void);
const struct dpll_params *get_dpll_per_params(void);
const struct dpll_params *get_dpll_ddr_params(void);
+void scale_vcores(void);
void do_setup_dpll(const struct dpll_regs *, const struct dpll_params *);
void prcm_init(void);
void enable_basic_clocks(void);
#define TCLR_PRE BIT(5) /* Pre-scaler enable */
#define TCLR_PTV_SHIFT (2) /* Pre-scaler shift value */
#define TCLR_PRE_DISABLE CL_BIT(5) /* Pre-scalar disable */
-
+#define TCLR_CE BIT(6) /* compare mode enable */
+#define TCLR_SCPWM BIT(7) /* pwm outpin behaviour */
+#define TCLR_TCM BIT(8) /* edge detection of input pin*/
+#define TCLR_TRG_SHIFT (10) /* trigmode on pwm outpin */
+#define TCLR_PT BIT(12) /* pulse/toggle mode of outpin*/
+#define TCLR_CAPTMODE BIT(13) /* capture mode */
+#define TCLR_GPOCFG BIT(14) /* 0=output,1=input */
+
+#define TCFG_RESET BIT(0) /* software reset */
+#define TCFG_EMUFREE BIT(1) /* behaviour of tmr on debug */
+#define TCFG_IDLEMOD_SHIFT (2) /* power management */
/* device type */
#define DEVICE_MASK (BIT(8) | BIT(9) | BIT(10))
#define TST_DEVICE 0x0
unsigned int wkctrlclkctrl; /* offset 0x04 */
unsigned int wkgpio0clkctrl; /* offset 0x08 */
unsigned int wkl4wkclkctrl; /* offset 0x0c */
- unsigned int resv2[4];
+ unsigned int timer0clkctrl; /* offset 0x10 */
+ unsigned int resv2[3];
unsigned int idlestdpllmpu; /* offset 0x20 */
unsigned int resv3[2];
unsigned int clkseldpllmpu; /* offset 0x2c */
unsigned int wkup_uart0ctrl; /* offset 0xB4 */
unsigned int wkup_i2c0ctrl; /* offset 0xB8 */
unsigned int wkup_adctscctrl; /* offset 0xBC */
- unsigned int resv12[6];
+ unsigned int resv12;
+ unsigned int timer1clkctrl; /* offset 0xC4 */
+ unsigned int resv13[4];
unsigned int divm6dpllcore; /* offset 0xD8 */
};
unsigned int epwmss2clkctrl; /* offset 0xD8 */
unsigned int l3instrclkctrl; /* offset 0xDC */
unsigned int l3clkctrl; /* Offset 0xE0 */
- unsigned int resv8[4];
+ unsigned int resv8[2];
+ unsigned int timer5clkctrl; /* offset 0xEC */
+ unsigned int timer6clkctrl; /* offset 0xF0 */
unsigned int mmc1clkctrl; /* offset 0xF4 */
unsigned int mmc2clkctrl; /* offset 0xF8 */
unsigned int resv9[8];
/* Encapsulating Display pll registers */
struct cm_dpll {
- unsigned int resv1[2];
+ unsigned int resv1;
+ unsigned int clktimer7clk; /* offset 0x04 */
unsigned int clktimer2clk; /* offset 0x08 */
- unsigned int resv2[10];
+ unsigned int clktimer3clk; /* offset 0x0C */
+ unsigned int clktimer4clk; /* offset 0x10 */
+ unsigned int resv2;
+ unsigned int clktimer5clk; /* offset 0x18 */
+ unsigned int clktimer6clk; /* offset 0x1C */
+ unsigned int resv3[2];
+ unsigned int clktimer1clk; /* offset 0x28 */
+ unsigned int resv4[2];
unsigned int clklcdcpixelclk; /* offset 0x34 */
};
#else
#define K2HK_LPSC_ARM_SREFLEX 51
#define K2HK_LPSC_TETRIS 52
-#define K2HK_UART0_BASE 0x02530c00
-
/* DDR3A definitions */
#define K2HK_DDR3A_EMIF_CTRL_BASE 0x21010000
#define K2HK_DDR3A_EMIF_DATA_BASE 0x80000000
#define KS2_DDR3_PMCTL_OFFSET 0x38
#define KS2_DDR3_ZQCFG_OFFSET 0xC8
+#define KS2_UART0_BASE 0x02530c00
+#define KS2_UART1_BASE 0x02531000
+
#ifdef CONFIG_SOC_K2HK
#include <asm/arch/hardware-k2hk.h>
#endif
#define GPMC_CS_ENABLE 0x1
-#define SMNAND_GPMC_CONFIG1 0x00000800
-#define SMNAND_GPMC_CONFIG2 0x00141400
-#define SMNAND_GPMC_CONFIG3 0x00141400
-#define SMNAND_GPMC_CONFIG4 0x0F010F01
-#define SMNAND_GPMC_CONFIG5 0x010C1414
-#define SMNAND_GPMC_CONFIG6 0x1F0F0A80
-#define SMNAND_GPMC_CONFIG7 0x00000C44
-
#define M_NAND_GPMC_CONFIG1 0x00001800
#define M_NAND_GPMC_CONFIG2 0x00141400
#define M_NAND_GPMC_CONFIG3 0x00141400
int board_init(void)
{
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+#ifdef CONFIG_NAND
gpmc_init();
+#endif
return 0;
}
};
#ifdef CONFIG_MMC
static struct module_pin_mux mmc1_pin_mux[] = {
+ {OFFSET(gpmc_ad7), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT7 */
+ {OFFSET(gpmc_ad6), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT6 */
+ {OFFSET(gpmc_ad5), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT5 */
+ {OFFSET(gpmc_ad4), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT4 */
+
{OFFSET(gpmc_ad3), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT3 */
{OFFSET(gpmc_ad2), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT2 */
{OFFSET(gpmc_ad1), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT1 */
{OFFSET(mmc0_dat3), (MODE(3) | PULLUDEN | RXACTIVE)},
/* TIMER6 (MMC0_DAT2) - PWM_BACK_3V3, later used as MODE3 for PWM */
{OFFSET(mmc0_dat2), (MODE(7) | PULLUDEN | RXACTIVE)},
- /* GPIO2_28 (MMC0_DAT1) - MII_nNAND */
+ /* GPIO2_27 (MMC0_DAT1) - MII_nNAND */
{OFFSET(mmc0_dat1), (MODE(7) | PULLUDEN | RXACTIVE)},
/* GPIO2_29 (MMC0_DAT0) - NAND_1n0 */
{OFFSET(mmc0_dat0), (MODE(7) | PULLUDEN | RXACTIVE)},
* DISPLAY_ONOFF (Backlight Enable at LVDS Versions)
*/
{OFFSET(ecap0_in_pwm0_out), (MODE(7) | PULLUDEN | RXACTIVE)},
- /* GPIO0_19 (DMA_INTR0) - ISPLAY_MODE (CPLD) */
+ /* GPIO0_19 (DMA_INTR0) - DISPLAY_MODE (CPLD) */
{OFFSET(xdma_event_intr0), (MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE)},
/* GPIO0_20 (DMA_INTR1) - REP-Switch */
{OFFSET(xdma_event_intr1), (MODE(7) | PULLUP_EN | RXACTIVE)},
};
static u32 gpmc_nand_config[GPMC_MAX_REG] = {
- SMNAND_GPMC_CONFIG1,
- SMNAND_GPMC_CONFIG2,
- SMNAND_GPMC_CONFIG3,
- SMNAND_GPMC_CONFIG4,
- SMNAND_GPMC_CONFIG5,
- SMNAND_GPMC_CONFIG6,
+ M_NAND_GPMC_CONFIG1,
+ M_NAND_GPMC_CONFIG2,
+ M_NAND_GPMC_CONFIG3,
+ M_NAND_GPMC_CONFIG4,
+ M_NAND_GPMC_CONFIG5,
+ M_NAND_GPMC_CONFIG6,
0,
};
# SPDX-License-Identifier: GPL-2.0+
#
-ifdef CONFIG_SPL_BUILD
+ifeq ($(CONFIG_SKIP_LOWLEVEL_INIT),)
obj-y := mux.o
endif
#include <asm/arch/gpio.h>
#include <asm/emif.h>
#include "board.h"
+#include <power/tps65218.h>
#include <miiphy.h>
#include <cpsw.h>
return 0;
}
-#ifdef CONFIG_SPL_BUILD
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
#define NUM_OPPS 6
const struct dpll_params *get_dpll_ddr_params(void)
{
- struct am43xx_board_id header;
-
- enable_i2c0_pin_mux();
- i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
- if (read_eeprom(&header) < 0)
- puts("Could not get board ID.\n");
-
if (board_is_eposevm())
return &epos_evm_dpll_ddr;
else if (board_is_gpevm())
static int get_opp_offset(int max_off, int min_off)
{
struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
- int opp = readl(&ctrl->dev_attr), offset, i;
+ int opp, offset, i;
+
+ /* Bits 0:11 are defined to be the MPU_MAX_FREQ */
+ opp = readl(&ctrl->dev_attr) & ~0xFFFFF000;
for (i = max_off; i >= min_off; i--) {
offset = opp & (1 << i);
return &dpll_per[ind];
}
+void scale_vcores(void)
+{
+ const struct dpll_params *mpu_params;
+ int mpu_vdd;
+ struct am43xx_board_id header;
+
+ enable_i2c0_pin_mux();
+ i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
+ if (read_eeprom(&header) < 0)
+ puts("Could not get board ID.\n");
+
+ /* Get the frequency */
+ mpu_params = get_dpll_mpu_params();
+
+ if (i2c_probe(TPS65218_CHIP_PM))
+ return;
+
+ if (mpu_params->m == 1000) {
+ mpu_vdd = TPS65218_DCDC_VOLT_SEL_1330MV;
+ } else if (mpu_params->m == 600) {
+ mpu_vdd = TPS65218_DCDC_VOLT_SEL_1100MV;
+ } else {
+ puts("Unknown MPU clock, not scaling\n");
+ return;
+ }
+
+ /* Set DCDC1 (CORE) voltage to 1.1V */
+ if (tps65218_voltage_update(TPS65218_DCDC1,
+ TPS65218_DCDC_VOLT_SEL_1100MV)) {
+ puts("tps65218_voltage_update failure\n");
+ return;
+ }
+
+ /* Set DCDC2 (MPU) voltage */
+ if (tps65218_voltage_update(TPS65218_DCDC2, mpu_vdd)) {
+ puts("tps65218_voltage_update failure\n");
+ return;
+ }
+}
+
void set_uart_mux_conf(void)
{
enable_uart0_pin_mux();
Active arm armv7 am33xx ti am335x am335x_evm_uart5 am335x_evm:SERIAL6,CONS_INDEX=6,NAND Tom Rini <trini@ti.com>
Active arm armv7 am33xx ti am335x am335x_evm_usbspl am335x_evm:SERIAL1,CONS_INDEX=1,NAND,SPL_USBETH_SUPPORT Tom Rini <trini@ti.com>
Active arm armv7 am33xx ti am43xx am43xx_evm am43xx_evm:SERIAL1,CONS_INDEX=1 Lokesh Vutla <lokeshvutla@ti.com>
+Active arm armv7 am33xx ti am43xx am43xx_evm_qspiboot am43xx_evm:SERIAL1,CONS_INDEX=1,QSPI,QSPI_BOOT Lokesh Vutla <lokeshvutla@ti.com>
Active arm armv7 am33xx ti ti814x ti814x_evm - Matt Porter <matt.porter@linaro.org>
Active arm armv7 am33xx ti ti816x ti816x_evm - -
Active arm armv7 at91 atmel sama5d3_xplained sama5d3_xplained_mmc sama5d3_xplained:SAMA5D3,SYS_USE_MMC Bo Shen <voice.shen@atmel.com>
This is used by SoC platforms which do not have built-in ELM
hardware engine required for BCH ECC correction.
+ CONFIG_SYS_NAND_BUSWIDTH_16BIT
+ Indicates that NAND device has 16-bit wide data-bus. In absence of this
+ config, bus-width of NAND device is assumed to be either 8-bit and later
+ determined by reading ONFI params.
+ Above config is useful when NAND device's bus-width information cannot
+ be determined from on-chip ONFI params, like in following scenarios:
+ - SPL boot does not support reading of ONFI parameters. This is done to
+ keep SPL code foot-print small.
+ - In current U-Boot flow using nand_init(), driver initialization
+ happens in board_nand_init() which is called before any device probe
+ (nand_scan_ident + nand_scan_tail), thus device's ONFI parameters are
+ not available while configuring controller. So a static CONFIG_NAND_xx
+ is needed to know the device's bus-width in advance.
+ Some drivers using above config are:
+ drivers/mtd/nand/mxc_nand.c
+ drivers/mtd/nand/ndfc.c
+ drivers/mtd/nand/omap_gpmc.c
+
Platform specific options
=========================
8-bit BCH code with
- ecc calculation using GPMC hardware engine,
- error detection using ELM hardware engine.
+ OMAP_ECC_BCH16_CODE_HW
+ 16-bit BCH code with
+ - ecc calculation using GPMC hardware engine,
+ - error detection using ELM hardware engine.
+
+ How to select ECC scheme on OMAP and AMxx platforms ?
+ -----------------------------------------------------
+ Though higher ECC schemes have more capability to detect and correct
+ bit-flips, but still selection of ECC scheme is dependent on following
+ - hardware engines present in SoC.
+ Some legacy OMAP SoC do not have ELM h/w engine thus such
+ SoC cannot support BCHx_HW ECC schemes.
+ - size of OOB/Spare region
+ With higher ECC schemes, more OOB/Spare area is required to
+ store ECC. So choice of ECC scheme is limited by NAND oobsize.
+
+ In general following expression can help:
+ NAND_OOBSIZE >= 2 + (NAND_PAGESIZE / 512) * ECC_BYTES
+ where
+ NAND_OOBSIZE = number of bytes available in
+ OOB/spare area per NAND page.
+ NAND_PAGESIZE = bytes in main-area of NAND page.
+ ECC_BYTES = number of ECC bytes generated to
+ protect 512 bytes of data, which is:
+ 3 for HAM1_xx ecc schemes
+ 7 for BCH4_xx ecc schemes
+ 14 for BCH8_xx ecc schemes
+ 26 for BCH16_xx ecc schemes
+
+ example to check for BCH16 on 2K page NAND
+ NAND_PAGESIZE = 2048
+ NAND_OOBSIZE = 64
+ 2 + (2048 / 512) * 26 = 106 > NAND_OOBSIZE
+ Thus BCH16 cannot be supported on 2K page NAND.
+
+ However, for 4K pagesize NAND
+ NAND_PAGESIZE = 4096
+ NAND_OOBSIZE = 64
+ ECC_BYTES = 26
+ 2 + (4096 / 512) * 26 = 210 < NAND_OOBSIZE
+ Thus BCH16 can be supported on 4K page NAND.
+
NOTE:
=====
}
/* Shift the offset from byte addressing to word addressing. */
- if (this->options & NAND_BUSWIDTH_16)
+ if ((this->options & NAND_BUSWIDTH_16) && !nand_opcode_8bits(cmd))
offs >>= 1;
/* Set ALE and clear CLE to start address cycle */
hwctrl(&mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
- if (this->options & NAND_BUSWIDTH_16)
+ if ((this->options & NAND_BUSWIDTH_16) && !nand_opcode_8bits(cmd))
offs >>= 1;
hwctrl(&mtd, offs & 0xff, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
/* Serially input address */
if (column != -1) {
/* Adjust columns for 16 bit buswidth */
- if (chip->options & NAND_BUSWIDTH_16)
+ if ((chip->options & NAND_BUSWIDTH_16) &&
+ !nand_opcode_8bits(command))
column >>= 1;
chip->cmd_ctrl(mtd, column, ctrl);
ctrl &= ~NAND_CTRL_CHANGE;
/* Serially input address */
if (column != -1) {
/* Adjust columns for 16 bit buswidth */
- if (chip->options & NAND_BUSWIDTH_16)
+ if ((chip->options & NAND_BUSWIDTH_16) &&
+ !nand_opcode_8bits(command))
column >>= 1;
chip->cmd_ctrl(mtd, column, ctrl);
ctrl &= ~NAND_CTRL_CHANGE;
int *busw)
{
struct nand_onfi_params *p = &chip->onfi_params;
- int i;
+ int i, j;
int val;
/* Try ONFI for unknown chip or LP */
chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
for (i = 0; i < 3; i++) {
- chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
+ for (j = 0; j < sizeof(*p); j++)
+ ((uint8_t *)p)[j] = chip->read_byte(mtd);
if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
le16_to_cpu(p->crc)) {
pr_info("ONFI param page %d valid\n", i);
}
/* Shift the offset from byte addressing to word addressing. */
- if (this->options & NAND_BUSWIDTH_16)
+ if ((this->options & NAND_BUSWIDTH_16) && !nand_opcode_8bits(cmd))
offs >>= 1;
/* Begin command latch cycle */
#include <common.h>
#include <asm/io.h>
#include <asm/errno.h>
-#include <linux/mtd/omap_gpmc.h>
#include <linux/mtd/omap_elm.h>
#include <asm/arch/hardware.h>
+#define DRIVER_NAME "omap-elm"
#define ELM_DEFAULT_POLY (0)
struct elm *elm_cfg;
/**
- * elm_load_syndromes - Load BCH syndromes based on nibble selection
+ * elm_load_syndromes - Load BCH syndromes based on bch_type selection
* @syndrome: BCH syndrome
- * @nibbles:
+ * @bch_type: BCH4/BCH8/BCH16
* @poly: Syndrome Polynomial set to use
- *
- * Load BCH syndromes based on nibble selection
*/
-static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly)
+static void elm_load_syndromes(u8 *syndrome, enum bch_level bch_type, u8 poly)
{
u32 *ptr;
u32 val;
(syndrome[7] << 24);
writel(val, ptr);
- /* BCH 8-bit with 26 nibbles (4*8=32) */
- if (nibbles > 13) {
+ if (bch_type == BCH_8_BIT || bch_type == BCH_16_BIT) {
/* reg 2 */
ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[2];
val = syndrome[8] | (syndrome[9] << 8) | (syndrome[10] << 16) |
writel(val, ptr);
}
- /* BCH 16-bit with 52 nibbles (7*8=56) */
- if (nibbles > 26) {
+ if (bch_type == BCH_16_BIT) {
/* reg 4 */
ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[4];
val = syndrome[16] | (syndrome[17] << 8) |
/**
* elm_check_errors - Check for BCH errors and return error locations
* @syndrome: BCH syndrome
- * @nibbles:
+ * @bch_type: BCH4/BCH8/BCH16
* @error_count: Returns number of errrors in the syndrome
* @error_locations: Returns error locations (in decimal) in this array
*
* and locations in the array passed. Returns -1 if error is not correctable,
* else returns 0
*/
-int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
+int elm_check_error(u8 *syndrome, enum bch_level bch_type, u32 *error_count,
u32 *error_locations)
{
u8 poly = ELM_DEFAULT_POLY;
s8 i;
u32 location_status;
- elm_load_syndromes(syndrome, nibbles, poly);
+ elm_load_syndromes(syndrome, bch_type, poly);
/* start processing */
writel((readl(&elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6])
/* check if correctable */
location_status = readl(&elm_cfg->error_location[poly].location_status);
- if (!(location_status & ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK))
- return -1;
+ if (!(location_status & ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK)) {
+ printf("%s: uncorrectable ECC errors\n", DRIVER_NAME);
+ return -EBADMSG;
+ }
/* get error count */
*error_count = readl(&elm_cfg->error_location[poly].location_status) &
}
/*
- * Generic BCH interface
+ * Driver configurations
*/
-struct nand_bch_priv {
- uint8_t mode;
- uint8_t type;
- uint8_t nibbles;
+struct omap_nand_info {
struct bch_control *control;
enum omap_ecc ecc_scheme;
};
-/* bch types */
-#define ECC_BCH4 0
-#define ECC_BCH8 1
-#define ECC_BCH16 2
-
-/* BCH nibbles for diff bch levels */
-#define ECC_BCH4_NIBBLES 13
-#define ECC_BCH8_NIBBLES 26
-#define ECC_BCH16_NIBBLES 52
-
/*
* This can be a single instance cause all current users have only one NAND
* with nearly the same setup (BCH8, some with ELM and others with sw BCH
* library).
* When some users with other BCH strength will exists this have to change!
*/
-static __maybe_unused struct nand_bch_priv bch_priv = {
- .type = ECC_BCH8,
- .nibbles = ECC_BCH8_NIBBLES,
+static __maybe_unused struct omap_nand_info omap_nand_info = {
.control = NULL
};
static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
{
struct nand_chip *nand = mtd->priv;
- struct nand_bch_priv *bch = nand->priv;
+ struct omap_nand_info *info = nand->priv;
unsigned int dev_width = (nand->options & NAND_BUSWIDTH_16) ? 1 : 0;
unsigned int ecc_algo = 0;
unsigned int bch_type = 0;
u32 ecc_config_val = 0;
/* configure GPMC for specific ecc-scheme */
- switch (bch->ecc_scheme) {
+ switch (info->ecc_scheme) {
case OMAP_ECC_HAM1_CODE_SW:
return;
case OMAP_ECC_HAM1_CODE_HW:
eccsize1 = 2; /* non-ECC bits in nibbles per sector */
}
break;
+ case OMAP_ECC_BCH16_CODE_HW:
+ ecc_algo = 0x1;
+ bch_type = 0x2;
+ if (mode == NAND_ECC_WRITE) {
+ bch_wrapmode = 0x01;
+ eccsize0 = 0; /* extra bits in nibbles per sector */
+ eccsize1 = 52; /* OOB bits in nibbles per sector */
+ } else {
+ bch_wrapmode = 0x01;
+ eccsize0 = 52; /* ECC bits in nibbles per sector */
+ eccsize1 = 0; /* non-ECC bits in nibbles per sector */
+ }
+ break;
default:
return;
}
uint8_t *ecc_code)
{
struct nand_chip *chip = mtd->priv;
- struct nand_bch_priv *bch = chip->priv;
+ struct omap_nand_info *info = chip->priv;
uint32_t *ptr, val = 0;
int8_t i = 0, j;
- switch (bch->ecc_scheme) {
+ switch (info->ecc_scheme) {
case OMAP_ECC_HAM1_CODE_HW:
val = readl(&gpmc_cfg->ecc1_result);
ecc_code[0] = val & 0xFF;
ptr--;
}
break;
+ case OMAP_ECC_BCH16_CODE_HW:
+ val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[2]);
+ ecc_code[i++] = (val >> 8) & 0xFF;
+ ecc_code[i++] = (val >> 0) & 0xFF;
+ val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[1]);
+ ecc_code[i++] = (val >> 24) & 0xFF;
+ ecc_code[i++] = (val >> 16) & 0xFF;
+ ecc_code[i++] = (val >> 8) & 0xFF;
+ ecc_code[i++] = (val >> 0) & 0xFF;
+ val = readl(&gpmc_cfg->bch_result_4_6[0].bch_result_x[0]);
+ ecc_code[i++] = (val >> 24) & 0xFF;
+ ecc_code[i++] = (val >> 16) & 0xFF;
+ ecc_code[i++] = (val >> 8) & 0xFF;
+ ecc_code[i++] = (val >> 0) & 0xFF;
+ for (j = 3; j >= 0; j--) {
+ val = readl(&gpmc_cfg->bch_result_0_3[0].bch_result_x[j]
+ );
+ ecc_code[i++] = (val >> 24) & 0xFF;
+ ecc_code[i++] = (val >> 16) & 0xFF;
+ ecc_code[i++] = (val >> 8) & 0xFF;
+ ecc_code[i++] = (val >> 0) & 0xFF;
+ }
+ break;
default:
return -EINVAL;
}
/* ECC scheme specific syndrome customizations */
- switch (bch->ecc_scheme) {
+ switch (info->ecc_scheme) {
case OMAP_ECC_HAM1_CODE_HW:
break;
#ifdef CONFIG_BCH
case OMAP_ECC_BCH8_CODE_HW:
ecc_code[chip->ecc.bytes - 1] = 0x00;
break;
+ case OMAP_ECC_BCH16_CODE_HW:
+ break;
default:
return -EINVAL;
}
uint8_t *read_ecc, uint8_t *calc_ecc)
{
struct nand_chip *chip = mtd->priv;
- struct nand_bch_priv *bch = chip->priv;
- uint32_t eccbytes = chip->ecc.bytes;
+ struct omap_nand_info *info = chip->priv;
+ struct nand_ecc_ctrl *ecc = &chip->ecc;
uint32_t error_count = 0, error_max;
- uint32_t error_loc[8];
+ uint32_t error_loc[ELM_MAX_ERROR_COUNT];
+ enum bch_level bch_type;
uint32_t i, ecc_flag = 0;
uint8_t count, err = 0;
uint32_t byte_pos, bit_pos;
/* check calculated ecc */
- for (i = 0; i < chip->ecc.bytes && !ecc_flag; i++) {
+ for (i = 0; i < ecc->bytes && !ecc_flag; i++) {
if (calc_ecc[i] != 0x00)
ecc_flag = 1;
}
/* check for whether its a erased-page */
ecc_flag = 0;
- for (i = 0; i < chip->ecc.bytes && !ecc_flag; i++) {
+ for (i = 0; i < ecc->bytes && !ecc_flag; i++) {
if (read_ecc[i] != 0xff)
ecc_flag = 1;
}
* while reading ECC result we read it in big endian.
* Hence while loading to ELM we have rotate to get the right endian.
*/
- switch (bch->ecc_scheme) {
+ switch (info->ecc_scheme) {
case OMAP_ECC_BCH8_CODE_HW:
- omap_reverse_list(calc_ecc, eccbytes - 1);
+ bch_type = BCH_8_BIT;
+ omap_reverse_list(calc_ecc, ecc->bytes - 1);
+ break;
+ case OMAP_ECC_BCH16_CODE_HW:
+ bch_type = BCH_16_BIT;
+ omap_reverse_list(calc_ecc, ecc->bytes);
break;
default:
return -EINVAL;
}
/* use elm module to check for errors */
- elm_config((enum bch_level)(bch->type));
- if (elm_check_error(calc_ecc, bch->nibbles, &error_count, error_loc)) {
- printf("nand: error: uncorrectable ECC errors\n");
- return -EINVAL;
- }
+ elm_config(bch_type);
+ err = elm_check_error(calc_ecc, bch_type, &error_count, error_loc);
+ if (err)
+ return err;
+
/* correct bch error */
for (count = 0; count < error_count; count++) {
- switch (bch->type) {
- case ECC_BCH8:
+ switch (info->ecc_scheme) {
+ case OMAP_ECC_BCH8_CODE_HW:
/* 14th byte in ECC is reserved to match ROM layout */
- error_max = SECTOR_BYTES + (eccbytes - 1);
+ error_max = SECTOR_BYTES + (ecc->bytes - 1);
+ break;
+ case OMAP_ECC_BCH16_CODE_HW:
+ error_max = SECTOR_BYTES + ecc->bytes;
break;
default:
return -EINVAL;
/* cannot correct more than 8 errors */
unsigned int errloc[8];
struct nand_chip *chip = mtd->priv;
- struct nand_bch_priv *chip_priv = chip->priv;
- struct bch_control *bch = chip_priv->control;
+ struct omap_nand_info *info = chip->priv;
- count = decode_bch(bch, NULL, 512, read_ecc, calc_ecc, NULL, errloc);
+ count = decode_bch(info->control, NULL, 512, read_ecc, calc_ecc,
+ NULL, errloc);
if (count > 0) {
/* correct errors */
for (i = 0; i < count; i++) {
static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd->priv;
- struct nand_bch_priv *chip_priv = chip->priv;
- struct bch_control *bch = NULL;
-
- if (chip_priv)
- bch = chip_priv->control;
+ struct omap_nand_info *info = chip->priv;
- if (bch) {
- free_bch(bch);
- chip_priv->control = NULL;
+ if (info->control) {
+ free_bch(info->control);
+ info->control = NULL;
}
}
#endif /* CONFIG_BCH */
*/
static int omap_select_ecc_scheme(struct nand_chip *nand,
enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
- struct nand_bch_priv *bch = nand->priv;
+ struct omap_nand_info *info = nand->priv;
struct nand_ecclayout *ecclayout = &omap_ecclayout;
int eccsteps = pagesize / SECTOR_BYTES;
int i;
debug("nand: selected OMAP_ECC_HAM1_CODE_SW\n");
/* For this ecc-scheme, ecc.bytes, ecc.layout, ... are
* initialized in nand_scan_tail(), so just set ecc.mode */
- bch_priv.control = NULL;
- bch_priv.type = 0;
+ info->control = NULL;
nand->ecc.mode = NAND_ECC_SOFT;
nand->ecc.layout = NULL;
nand->ecc.size = 0;
- bch->ecc_scheme = OMAP_ECC_HAM1_CODE_SW;
break;
case OMAP_ECC_HAM1_CODE_HW:
(3 * eccsteps) + BADBLOCK_MARKER_LENGTH));
return -EINVAL;
}
- bch_priv.control = NULL;
- bch_priv.type = 0;
+ info->control = NULL;
/* populate ecc specific fields */
memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
nand->ecc.mode = NAND_ECC_HW;
ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
BADBLOCK_MARKER_LENGTH;
- bch->ecc_scheme = OMAP_ECC_HAM1_CODE_HW;
break;
case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
return -EINVAL;
}
/* check if BCH S/W library can be used for error detection */
- bch_priv.control = init_bch(13, 8, 0x201b);
- if (!bch_priv.control) {
+ info->control = init_bch(13, 8, 0x201b);
+ if (!info->control) {
printf("nand: error: could not init_bch()\n");
return -ENODEV;
}
- bch_priv.type = ECC_BCH8;
/* populate ecc specific fields */
memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
nand->ecc.mode = NAND_ECC_HW;
ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
BADBLOCK_MARKER_LENGTH;
- bch->ecc_scheme = OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
break;
#else
printf("nand: error: CONFIG_BCH required for ECC\n");
}
/* intialize ELM for ECC error detection */
elm_init();
- bch_priv.type = ECC_BCH8;
+ info->control = NULL;
/* populate ecc specific fields */
memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
nand->ecc.mode = NAND_ECC_HW;
ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes -
BADBLOCK_MARKER_LENGTH;
- bch->ecc_scheme = OMAP_ECC_BCH8_CODE_HW;
break;
#else
printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
return -EINVAL;
#endif
+ case OMAP_ECC_BCH16_CODE_HW:
+#ifdef CONFIG_NAND_OMAP_ELM
+ debug("nand: using OMAP_ECC_BCH16_CODE_HW\n");
+ /* check ecc-scheme requirements before updating ecc info */
+ if ((26 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) {
+ printf("nand: error: insufficient OOB: require=%d\n", (
+ (26 * eccsteps) + BADBLOCK_MARKER_LENGTH));
+ return -EINVAL;
+ }
+ /* intialize ELM for ECC error detection */
+ elm_init();
+ /* populate ecc specific fields */
+ nand->ecc.mode = NAND_ECC_HW;
+ nand->ecc.size = SECTOR_BYTES;
+ nand->ecc.bytes = 26;
+ nand->ecc.strength = 16;
+ nand->ecc.hwctl = omap_enable_hwecc;
+ nand->ecc.correct = omap_correct_data_bch;
+ nand->ecc.calculate = omap_calculate_ecc;
+ nand->ecc.read_page = omap_read_page_bch;
+ /* define ecc-layout */
+ ecclayout->eccbytes = nand->ecc.bytes * eccsteps;
+ for (i = 0; i < ecclayout->eccbytes; i++)
+ ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH;
+ ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH;
+ ecclayout->oobfree[0].length = oobsize - nand->ecc.bytes -
+ BADBLOCK_MARKER_LENGTH;
+ break;
+#else
+ printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n");
+ return -EINVAL;
+#endif
default:
debug("nand: error: ecc scheme not enabled or supported\n");
return -EINVAL;
if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW)
nand->ecc.layout = ecclayout;
+ info->ecc_scheme = ecc_scheme;
return 0;
}
nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
- nand->priv = &bch_priv;
+ nand->priv = &omap_nand_info;
nand->cmd_ctrl = omap_nand_hwcontrol;
nand->options |= NAND_NO_PADDING | NAND_CACHEPRG;
- /* If we are 16 bit dev, our gpmc config tells us that */
- if ((readl(&gpmc_cfg->cs[cs].config1) & 0x3000) == 0x1000)
- nand->options |= NAND_BUSWIDTH_16;
-
nand->chip_delay = 100;
nand->ecc.layout = &omap_ecclayout;
+ /* configure driver and controller based on NAND device bus-width */
+ gpmc_config = readl(&gpmc_cfg->cs[cs].config1);
+#if defined(CONFIG_SYS_NAND_BUSWIDTH_16BIT)
+ nand->options |= NAND_BUSWIDTH_16;
+ writel(gpmc_config | (0x1 << 12), &gpmc_cfg->cs[cs].config1);
+#else
+ nand->options &= ~NAND_BUSWIDTH_16;
+ writel(gpmc_config & ~(0x1 << 12), &gpmc_cfg->cs[cs].config1);
+#endif
/* select ECC scheme */
#if defined(CONFIG_NAND_OMAP_ECCSCHEME)
err = omap_select_ecc_scheme(nand, CONFIG_NAND_OMAP_ECCSCHEME,
obj-$(CONFIG_POWER_PFUZE100) += pmic_pfuze100.o
obj-$(CONFIG_POWER_TPS65090) += pmic_tps65090.o
obj-$(CONFIG_POWER_TPS65217) += pmic_tps65217.o
+obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o
obj-$(CONFIG_POWER_TPS65910) += pmic_tps65910.o
--- /dev/null
+/*
+ * (C) Copyright 2011-2013
+ * Texas Instruments, <www.ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <power/tps65218.h>
+
+/**
+ * tps65218_reg_write() - Generic function that can write a TPS65218 PMIC
+ * register or bit field regardless of protection
+ * level.
+ *
+ * @prot_level: Register password protection. Use
+ * TPS65218_PROT_LEVEL_NONE,
+ * TPS65218_PROT_LEVEL_1 or TPS65218_PROT_LEVEL_2
+ * @dest_reg: Register address to write.
+ * @dest_val: Value to write.
+ * @mask: Bit mask (8 bits) to be applied. Function will only
+ * change bits that are set in the bit mask.
+ *
+ * @return: 0 for success, not 0 on failure, as per the i2c API
+ */
+int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
+ uchar mask)
+{
+ uchar read_val;
+ uchar xor_reg;
+ int ret;
+
+ /*
+ * If we are affecting only a bit field, read dest_reg and apply the
+ * mask
+ */
+ if (mask != TPS65218_MASK_ALL_BITS) {
+ ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &read_val, 1);
+ if (ret)
+ return ret;
+ read_val &= (~mask);
+ read_val |= (dest_val & mask);
+ dest_val = read_val;
+ }
+
+ if (prot_level > 0) {
+ xor_reg = dest_reg ^ TPS65218_PASSWORD_UNLOCK;
+ ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1,
+ &xor_reg, 1);
+ if (ret)
+ return ret;
+ }
+
+ ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1);
+ if (ret)
+ return ret;
+
+ if (prot_level == TPS65218_PROT_LEVEL_2) {
+ ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1,
+ &xor_reg, 1);
+ if (ret)
+ return ret;
+
+ ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * tps65218_voltage_update() - Function to change a voltage level, as this
+ * is a multi-step process.
+ * @dc_cntrl_reg: DC voltage control register to change.
+ * @volt_sel: New value for the voltage register
+ * @return: 0 for success, not 0 on failure.
+ */
+int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
+{
+ if ((dc_cntrl_reg != TPS65218_DCDC1) &&
+ (dc_cntrl_reg != TPS65218_DCDC2))
+ return 1;
+
+ /* set voltage level */
+ if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, dc_cntrl_reg, volt_sel,
+ TPS65218_MASK_ALL_BITS))
+ return 1;
+
+ /* set GO bit to initiate voltage transition */
+ if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_SLEW,
+ TPS65218_DCDC_GO, TPS65218_DCDC_GO))
+ return 1;
+
+ return 0;
+}
slave->memory_map = (void *)MMAP_START_ADDR_DRA;
#else
slave->memory_map = (void *)MMAP_START_ADDR_AM43x;
+ slave->op_mode_rx = 8;
#endif
memval |= QSPI_CMD_READ | QSPI_SETUP0_NUM_A_BYTES |
#define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/omap-common/u-boot-spl.lds"
/* NAND boot config */
+#define CONFIG_SYS_NAND_BUSWIDTH_16BIT 16
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
#define CONFIG_SYS_NAND_PAGE_COUNT 64
#define CONFIG_SYS_NAND_PAGE_SIZE 2048
#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
#define CONFIG_SYS_I2C_MULTI_EEPROMS
+/* Power */
+#define CONFIG_POWER_TPS65218
+
/* SPL defines. */
#define CONFIG_SPL_TEXT_BASE 0x40300350
#define CONFIG_SPL_MAX_SIZE (220 << 10) /* 220KB */
#define CONFIG_SYS_SPL_ARGS_ADDR (CONFIG_SYS_SDRAM_BASE + \
(128 << 20))
+#define CONFIG_SPL_POWER_SUPPORT
#define CONFIG_SPL_YMODEM_SUPPORT
/* Enabling L2 Cache */
* Since SPL did pll and ddr initialization for us,
* we don't need to do it twice.
*/
-#if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_NOR_BOOT)
+#if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_QSPI_BOOT)
#define CONFIG_SKIP_LOWLEVEL_INIT
#endif
+/*
+ * When building U-Boot such that there is no previous loader
+ * we need to call board_early_init_f. This is taken care of in
+ * s_init when we have SPL used.
+ */
+#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && !defined(CONFIG_SPL)
+#define CONFIG_BOARD_EARLY_INIT_F
+#endif
+
/* Now bring in the rest of the common code. */
#include <configs/ti_armv7_common.h>
-/* Always 128 KiB env size */
-#define CONFIG_ENV_SIZE (128 << 10)
+/* Always 64 KiB env size */
+#define CONFIG_ENV_SIZE (64 << 10)
#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
#define CONFIG_OMAP_USB_PHY
#define CONFIG_AM437X_USB2PHY2_HOST
+#ifdef CONFIG_QSPI_BOOT
+#define CONFIG_SYS_TEXT_BASE 0x30000000
+#undef CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
+#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
+#define CONFIG_ENV_SECT_SIZE (64 << 10) /* 64 KB sectors */
+#define CONFIG_ENV_OFFSET 0x110000
+#define CONFIG_ENV_OFFSET_REDUND 0x120000
+#ifdef MTDIDS_DEFAULT
+#undef MTDIDS_DEFAULT
+#endif
+#ifdef MTDPARTS_DEFAULT
+#undef MTDPARTS_DEFAULT
+#endif
+#define MTDPARTS_DEFAULT "mtdparts=qspi.0:512k(QSPI.u-boot)," \
+ "512k(QSPI.u-boot.backup)," \
+ "512k(QSPI.u-boot-spl-os)," \
+ "64k(QSPI.u-boot-env)," \
+ "64k(QSPI.u-boot-env.backup)," \
+ "8m(QSPI.kernel)," \
+ "-(QSPI.file-system)"
+#endif
+
/* SPI */
#undef CONFIG_OMAP3_SPI
#define CONFIG_TI_QSPI
#define CONFIG_CMD_SF
#define CONFIG_CMD_SPI
#define CONFIG_TI_SPI_MMAP
+#define CONFIG_SPI_FLASH_BAR
#define CONFIG_QSPI_SEL_GPIO 48
#define CONFIG_SF_DEFAULT_SPEED 48000000
#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_3
"loadfdt=load ${devtype} ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}\0" \
"mmcboot=mmc dev ${mmcdev}; " \
"setenv devnum ${mmcdev}; " \
+ "setenv devtype mmc; " \
"if mmc rescan; then " \
"echo SD/MMC found on device ${devnum};" \
"if run loadbootenv; then " \
#ifndef __BUR_AM335X_COMMON_H__
#define __BUR_AM335X_COMMON_H__
/* ------------------------------------------------------------------------- */
+#define CONFIG_SYS_GENERIC_BOARD
+
#define CONFIG_AM33XX
#define CONFIG_OMAP
#define CONFIG_OMAP_COMMON
#define CONFIG_SYS_OMAP24_I2C_SPEED 100000
#define CONFIG_SYS_OMAP24_I2C_SLAVE 1
#define CONFIG_SYS_I2C_OMAP24XX
-
+#define CONFIG_CMD_I2C
/* GPIO */
#define CONFIG_OMAP_GPIO
#define CONFIG_CMD_GPIO
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x200000
#define CONFIG_CMD_NAND
-#define GPMC_NAND_ECC_LP_x8_LAYOUT
#define MTDIDS_DEFAULT "nand0=nand"
#define MTDPARTS_DEFAULT "mtdparts=nand:2m(spl)," \
"1m(u-boot),1m(u-boot-env)," \
/* CS0 */
#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND */
/* devices */
-#define GPMC_NAND_ECC_LP_x8_LAYOUT
/* Environment information */
#define CONFIG_BOOTDELAY 3
#define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */
+#define CONFIG_SYS_NAND_BUSWIDTH_16BIT 16
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
#define CONFIG_SYS_NAND_PAGE_COUNT 64
#define CONFIG_SYS_NAND_PAGE_SIZE 2048
* Board NAND Info.
*/
#define CONFIG_NAND_OMAP_GPMC
+#define CONFIG_SYS_NAND_BUSWIDTH_16BIT 16
#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */
/* to access nand */
#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */
#define CONFIG_SYS_NS16550_SERIAL
#define CONFIG_SYS_NS16550_MEM32
#define CONFIG_SYS_NS16550_REG_SIZE -4
-#define CONFIG_SYS_NS16550_COM1 K2HK_UART0_BASE
+#define CONFIG_SYS_NS16550_COM1 KS2_UART0_BASE
+#define CONFIG_SYS_NS16550_COM2 KS2_UART1_BASE
#define CONFIG_SYS_NS16550_CLK clk_get_rate(K2HK_CLK1_6)
#define CONFIG_CONS_INDEX 1
#define CONFIG_BAUDRATE 115200
/* NAND Configuration */
#define CONFIG_NAND_DAVINCI
+#define CONFIG_CMD_NAND_ECCLAYOUT
#define CONFIG_SYS_NAND_CS 2
#define CONFIG_SYS_NAND_USE_FLASH_BBT
#define CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST
#define CONFIG_SPL_OMAP3_ID_NAND
/* NAND boot config */
+#define CONFIG_SYS_NAND_BUSWIDTH_16BIT 16
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
#define CONFIG_SYS_NAND_PAGE_COUNT 64
#define CONFIG_SYS_NAND_PAGE_SIZE 2048
/* Max number of NAND devices */
#define CONFIG_SYS_MAX_NAND_DEVICE 1
-
+#define CONFIG_SYS_NAND_BUSWIDTH_16BIT 16
/* Timeout values (in ticks) */
#define CONFIG_SYS_FLASH_ERASE_TOUT (100 * CONFIG_SYS_HZ)
#define CONFIG_SYS_FLASH_WRITE_TOUT (100 * CONFIG_SYS_HZ)
/* NAND boot config */
#ifdef CONFIG_NAND
+#define CONFIG_SYS_NAND_BUSWIDTH_16BIT 16
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
#define CONFIG_SYS_NAND_PAGE_COUNT 64
#define CONFIG_SYS_NAND_PAGE_SIZE 2048
#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of */
/* NAND devices */
+#define CONFIG_SYS_NAND_BUSWIDTH_16BIT 16
#define CONFIG_JFFS2_NAND
/* nand device jffs2 lives on */
#define CONFIG_JFFS2_DEV "nand0"
#define CONFIG_SYS_CACHELINE_SIZE 64
/* NAND boot config */
+#define CONFIG_SYS_NAND_BUSWIDTH_16BIT 16
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
#define CONFIG_SYS_NAND_PAGE_COUNT 64
#define CONFIG_SYS_NAND_PAGE_SIZE 2048
#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */
/* to access nand at */
/* CS0 */
+#define CONFIG_SYS_NAND_BUSWIDTH_16BIT 16
/* Environment information */
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
-#define GPMC_NAND_ECC_LP_x8_LAYOUT 1
#define MTDIDS_DEFAULT "nand0=omap2-nand.0"
#define MTDPARTS_DEFAULT "mtdparts=omap2-nand.0:128k(SPL)," \
"128k(SPL.backup1)," \
/* Configure the PISMO */
#define PISMO1_NAND_SIZE GPMC_SIZE_128M
+#define CONFIG_NAND
#define CONFIG_NAND_OMAP_GPMC
#define CONFIG_ENV_IS_IN_NAND
#define SMNAND_ENV_OFFSET 0x180000 /* environment starts here */
#define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */
+#define CONFIG_SYS_NAND_BUSWIDTH_16BIT 16
#define CONFIG_SYS_NAND_PAGE_COUNT 64
#define CONFIG_SYS_NAND_PAGE_SIZE 2048
#define CONFIG_SYS_NAND_OOBSIZE 64
#define CONFIG_SYS_NAND_BASE NAND_BASE /* physical address */
/* to access nand at */
/* CS0 */
-#define GPMC_NAND_ECC_LP_x16_LAYOUT
#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND */
/* devices */
+#define CONFIG_SYS_NAND_BUSWIDTH_16BIT 16
/* Environment information */
#define CONFIG_BOOTDELAY 3
#define CONFIG_SKIP_LOWLEVEL_INIT
#endif
+/*
+ * When building U-Boot such that there is no previous loader
+ * we need to call board_early_init_f. This is taken care of in
+ * s_init when we have SPL used.
+ */
+#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && !defined(CONFIG_SPL)
+#define CONFIG_BOARD_EARLY_INIT_F
+#endif
+
#ifdef CONFIG_NAND
#define CONFIG_SPL_NAND_AM33XX_BCH /* ELM support */
#endif
* under common/spl/. Given our generally common memory map, we set a
* number of related defaults and sizes here.
*/
-#ifndef CONFIG_NOR_BOOT
+#if !defined(CONFIG_NOR_BOOT) && \
+ !(defined(CONFIG_QSPI_BOOT) && defined(CONFIG_AM43XX))
#define CONFIG_SPL
#define CONFIG_SPL_FRAMEWORK
#define CONFIG_SPL_OS_BOOT
/* don't change OMAP_ELM, ECCSCHEME. ROM code only supports this */
#define CONFIG_NAND_OMAP_ELM
#define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH8_CODE_HW
-#define GPMC_NAND_ECC_LP_x16_LAYOUT 1
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)
#define CONFIG_SYS_NAND_PAGE_SIZE 2048
}
#endif
+/**
+ * Check if the opcode's address should be sent only on the lower 8 bits
+ * @command: opcode to check
+ */
+static inline int nand_opcode_8bits(unsigned int command)
+{
+ switch (command) {
+ case NAND_CMD_READID:
+ case NAND_CMD_PARAM:
+ case NAND_CMD_GET_FEATURES:
+ case NAND_CMD_SET_FEATURES:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+
#endif /* __LINUX_MTD_NAND_H */
#define ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK (0x100)
#define ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK (0x1F)
+#define ELM_MAX_CHANNELS 8
+#define ELM_MAX_ERROR_COUNT 16
+
#ifndef __ASSEMBLY__
enum bch_level {
struct location {
u32 location_status; /* 0x800 */
u8 res1[124]; /* 0x804 */
- u32 error_location_x[16]; /* 0x880.... */
+ u32 error_location_x[ELM_MAX_ERROR_COUNT]; /* 0x880, 0x980, .. */
u8 res2[64]; /* 0x8c0 */
};
u8 res2[92]; /* 0x024 */
u32 page_ctrl; /* 0x080 */
u8 res3[892]; /* 0x084 */
- struct syndrome syndrome_fragments[8]; /* 0x400 */
+ struct syndrome syndrome_fragments[ELM_MAX_CHANNELS]; /* 0x400,0x420 */
u8 res4[512]; /* 0x600 */
- struct location error_location[8]; /* 0x800 */
+ struct location error_location[ELM_MAX_CHANNELS]; /* 0x800,0x900 ... */
};
-int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
+int elm_check_error(u8 *syndrome, enum bch_level bch_type, u32 *error_count,
u32 *error_locations);
int elm_config(enum bch_level level);
void elm_reset(void);
#define GPMC_BUF_EMPTY 0
#define GPMC_BUF_FULL 1
+#define GPMC_MAX_SECTORS 8
enum omap_ecc {
/* 1-bit ECC calculation by Software, Error detection by Software */
OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
/* 8-bit ECC calculation by GPMC, Error detection by ELM */
OMAP_ECC_BCH8_CODE_HW,
+ /* 16-bit ECC calculation by GPMC, Error detection by ELM */
+ OMAP_ECC_BCH16_CODE_HW,
};
struct gpmc_cs {
u32 bch_result_x[4];
};
+struct bch_res_4_6 {
+ u32 bch_result_x[3];
+};
+
struct gpmc {
u8 res1[0x10];
u32 sysconfig; /* 0x10 */
u8 res7[12]; /* 0x224 */
u32 testmomde_ctrl; /* 0x230 */
u8 res8[12]; /* 0x234 */
- struct bch_res_0_3 bch_result_0_3[2]; /* 0x240 */
+ struct bch_res_0_3 bch_result_0_3[GPMC_MAX_SECTORS]; /* 0x240,0x250, */
+ u8 res9[16 * 4]; /* 0x2C0 - 0x2FF */
+ struct bch_res_4_6 bch_result_4_6[GPMC_MAX_SECTORS]; /* 0x300,0x310, */
};
/* Used for board specific gpmc initialization */
--- /dev/null
+/*
+ * (C) Copyright 2014
+ * Texas Instruments, <www.ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __POWER_TPS65218_H__
+#define __POWER_TPS65218_H__
+
+/* I2C chip address */
+#define TPS65218_CHIP_PM 0x24
+
+/* Registers */
+enum {
+ TPS65218_CHIPID = 0x00,
+ TPS65218_INT1,
+ TPS65218_INT2,
+ TPS65218_INT_MASK1,
+ TPS65218_INT_MASK2,
+ TPS65218_STATUS,
+ TPS65218_CONTROL,
+ TPS65218_FLAG,
+ TPS65218_PASSWORD = 0x10,
+ TPS65218_ENABLE1,
+ TPS65218_ENABLE2,
+ TPS65218_CONFIG1,
+ TPS65218_CONFIG2,
+ TPS65218_CONFIG3,
+ TPS65218_DCDC1,
+ TPS65218_DCDC2,
+ TPS65218_DCDC3,
+ TPS65218_DCDC4,
+ TPS65218_SLEW,
+ TPS65218_LDO1,
+ TPS65218_SEQ1 = 0x20,
+ TPS65218_SEQ2,
+ TPS65218_SEQ3,
+ TPS65218_SEQ4,
+ TPS65218_SEQ5,
+ TPS65218_SEQ6,
+ TPS65218_SEQ7,
+ TPS65218_PMIC_NUM_OF_REGS,
+};
+
+#define TPS65218_PROT_LEVEL_NONE 0x00
+#define TPS65218_PROT_LEVEL_1 0x01
+#define TPS65218_PROT_LEVEL_2 0x02
+
+#define TPS65218_PASSWORD_LOCK_FOR_WRITE 0x00
+#define TPS65218_PASSWORD_UNLOCK 0x7D
+
+#define TPS65218_DCDC_GO 0x80
+
+#define TPS65218_MASK_ALL_BITS 0xFF
+
+#define TPS65218_DCDC_VOLT_SEL_1100MV 0x19
+#define TPS65218_DCDC_VOLT_SEL_1330MV 0x30
+
+int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
+ uchar mask);
+int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel);
+#endif /* __POWER_TPS65218_H__ */