+// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2004-2008 Texas Instruments, <www.ti.com>
* Rohit Choraria <rohitkc@ti.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/io.h>
-#include <asm/errno.h>
+#include <linux/errno.h>
#include <asm/arch/mem.h>
#include <linux/mtd/omap_gpmc.h>
#include <linux/mtd/nand_ecc.h>
static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
uint32_t ctrl)
{
- register struct nand_chip *this = mtd->priv;
- struct omap_nand_info *info = this->priv;
+ register struct nand_chip *this = mtd_to_nand(mtd);
+ struct omap_nand_info *info = nand_get_controller_data(this);
int cs = info->cs;
/*
/* Check wait pin as dev ready indicator */
static int omap_dev_ready(struct mtd_info *mtd)
{
- register struct nand_chip *this = mtd->priv;
- struct omap_nand_info *info = this->priv;
+ register struct nand_chip *this = mtd_to_nand(mtd);
+ struct omap_nand_info *info = nand_get_controller_data(this);
return gpmc_cfg->status & (1 << (8 + info->ws));
}
return 0;
printf("Error: Bad compare! failed\n");
/* detected 2 bit error */
- return -1;
+ return -EBADMSG;
}
}
return 0;
__maybe_unused
static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
{
- struct nand_chip *nand = mtd->priv;
- struct omap_nand_info *info = nand->priv;
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct omap_nand_info *info = nand_get_controller_data(nand);
unsigned int dev_width = (nand->options & NAND_BUSWIDTH_16) ? 1 : 0;
unsigned int ecc_algo = 0;
unsigned int bch_type = 0;
static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
uint8_t *ecc_code)
{
- struct nand_chip *chip = mtd->priv;
- struct omap_nand_info *info = chip->priv;
- uint32_t *ptr, val = 0;
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct omap_nand_info *info = nand_get_controller_data(chip);
+ const uint32_t *ptr;
+ uint32_t val = 0;
int8_t i = 0, j;
switch (info->ecc_scheme) {
{
int ret;
uint32_t cnt;
- struct omap_nand_info *info = chip->priv;
+ struct omap_nand_info *info = nand_get_controller_data(chip);
ret = omap_prefetch_enable(PREFETCH_FIFOTHRESHOLD_MAX, len, 0, info->cs);
if (ret < 0)
static inline void omap_nand_read(struct mtd_info *mtd, uint8_t *buf, int len)
{
- struct nand_chip *chip = mtd->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
if (chip->options & NAND_BUSWIDTH_16)
nand_read_buf16(mtd, buf, len);
{
int ret;
uint32_t head, tail;
- struct nand_chip *chip = mtd->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
/*
* If the destination buffer is unaligned, start with reading
static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
uint8_t *read_ecc, uint8_t *calc_ecc)
{
- struct nand_chip *chip = mtd->priv;
- struct omap_nand_info *info = chip->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct omap_nand_info *info = nand_get_controller_data(chip);
struct nand_ecc_ctrl *ecc = &chip->ecc;
uint32_t error_count = 0, error_max;
uint32_t error_loc[ELM_MAX_ERROR_COUNT];
int i, count;
/* cannot correct more than 8 errors */
unsigned int errloc[8];
- struct nand_chip *chip = mtd->priv;
- struct omap_nand_info *info = chip->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct omap_nand_info *info = nand_get_controller_data(chip);
- count = decode_bch(info->control, NULL, 512, read_ecc, calc_ecc,
- NULL, errloc);
+ count = decode_bch(info->control, NULL, SECTOR_BYTES,
+ read_ecc, calc_ecc, NULL, errloc);
if (count > 0) {
/* correct errors */
for (i = 0; i < count; i++) {
/* correct data only, not ecc bytes */
- if (errloc[i] < 8*512)
- data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
+ if (errloc[i] < SECTOR_BYTES << 3)
+ data[errloc[i] >> 3] ^= 1 << (errloc[i] & 7);
debug("corrected bitflip %u\n", errloc[i]);
#ifdef DEBUG
puts("read_ecc: ");
*/
static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
{
- struct nand_chip *chip = mtd->priv;
- struct omap_nand_info *info = chip->priv;
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ struct omap_nand_info *info = nand_get_controller_data(chip);
if (info->control) {
free_bch(info->control);
*/
static int omap_select_ecc_scheme(struct nand_chip *nand,
enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
- struct omap_nand_info *info = nand->priv;
+ struct omap_nand_info *info = nand_get_controller_data(nand);
struct nand_ecclayout *ecclayout = &omap_ecclayout;
int eccsteps = pagesize / SECTOR_BYTES;
int i;
int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
{
struct nand_chip *nand;
- struct mtd_info *mtd;
+ struct mtd_info *mtd = get_nand_dev_by_index(nand_curr_device);
int err = 0;
- if (nand_curr_device < 0 ||
- nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
- !nand_info[nand_curr_device].name) {
+ if (!mtd) {
printf("nand: error: no NAND devices found\n");
return -ENODEV;
}
- mtd = &nand_info[nand_curr_device];
- nand = mtd->priv;
+ nand = mtd_to_nand(mtd);
nand->options |= NAND_OWN_BUFFERS;
nand->options &= ~NAND_SUBPAGE_READ;
/* Setup the ecc configurations again */
err = omap_select_ecc_scheme(nand,
OMAP_ECC_BCH8_CODE_HW,
mtd->writesize, mtd->oobsize);
+ } else if (eccstrength == 16) {
+ err = omap_select_ecc_scheme(nand,
+ OMAP_ECC_BCH16_CODE_HW,
+ mtd->writesize, mtd->oobsize);
} else {
printf("nand: error: unsupported ECC scheme\n");
return -EINVAL;
omap_nand_info[cs].control = NULL;
omap_nand_info[cs].cs = cs;
omap_nand_info[cs].ws = wscfg[cs];
- nand->priv = &omap_nand_info[cs];
+ nand_set_controller_data(nand, &omap_nand_info[cs]);
nand->cmd_ctrl = omap_nand_hwcontrol;
nand->options |= NAND_NO_PADDING | NAND_CACHEPRG;
nand->chip_delay = 100;