// SPDX-License-Identifier: GPL-2.0
/*
* Evatronix/Renesas R-Car Gen3, RZ/N1D, RZ/N1S, RZ/N1L NAND controller driver
*
* Copyright (C) 2021 Schneider Electric
* Author: Miquel RAYNAL <miquel.raynal@bootlin.com>
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#define COMMAND_REG 0x00
#define COMMAND_SEQ(x) FIELD_PREP(GENMASK(5, 0), (x))
#define COMMAND_SEQ_10 COMMAND_SEQ(0x2A)
#define COMMAND_SEQ_12 COMMAND_SEQ(0x0C)
#define COMMAND_SEQ_18 COMMAND_SEQ(0x32)
#define COMMAND_SEQ_19 COMMAND_SEQ(0x13)
#define COMMAND_SEQ_GEN_IN COMMAND_SEQ_18
#define COMMAND_SEQ_GEN_OUT COMMAND_SEQ_19
#define COMMAND_SEQ_READ_PAGE COMMAND_SEQ_10
#define COMMAND_SEQ_WRITE_PAGE COMMAND_SEQ_12
#define COMMAND_INPUT_SEL_AHBS 0
#define COMMAND_INPUT_SEL_DMA BIT(6)
#define COMMAND_FIFO_SEL 0
#define COMMAND_DATA_SEL BIT(7)
#define COMMAND_0(x) FIELD_PREP(GENMASK(15, 8), (x))
#define COMMAND_1(x) FIELD_PREP(GENMASK(23, 16), (x))
#define COMMAND_2(x) FIELD_PREP(GENMASK(31, 24), (x))
#define CONTROL_REG 0x04
#define CONTROL_CHECK_RB_LINE 0
#define CONTROL_ECC_BLOCK_SIZE(x) FIELD_PREP(GENMASK(2, 1), (x))
#define CONTROL_ECC_BLOCK_SIZE_256 CONTROL_ECC_BLOCK_SIZE(0)
#define CONTROL_ECC_BLOCK_SIZE_512 CONTROL_ECC_BLOCK_SIZE(1)
#define CONTROL_ECC_BLOCK_SIZE_1024 CONTROL_ECC_BLOCK_SIZE(2)
#define CONTROL_INT_EN BIT(4)
#define CONTROL_ECC_EN BIT(5)
#define CONTROL_BLOCK_SIZE(x) FIELD_PREP(GENMASK(7, 6), (x))
#define CONTROL_BLOCK_SIZE_32P CONTROL_BLOCK_SIZE(0)
#define CONTROL_BLOCK_SIZE_64P CONTROL_BLOCK_SIZE(1)
#define CONTROL_BLOCK_SIZE_128P CONTROL_BLOCK_SIZE(2)
#define CONTROL_BLOCK_SIZE_256P CONTROL_BLOCK_SIZE(3)
#define STATUS_REG 0x8
#define MEM_RDY(cs, reg) (FIELD_GET(GENMASK(3, 0), (reg)) & BIT(cs))
#define CTRL_RDY(reg) (FIELD_GET(BIT(8), (reg)) == 0)
#define ECC_CTRL_REG 0x18
#define ECC_CTRL_CAP(x) FIELD_PREP(GENMASK(2, 0), (x))
#define ECC_CTRL_CAP_2B ECC_CTRL_CAP(0)
#define ECC_CTRL_CAP_4B ECC_CTRL_CAP(1)
#define ECC_CTRL_CAP_8B ECC_CTRL_CAP(2)
#define ECC_CTRL_CAP_16B ECC_CTRL_CAP(3)
#define ECC_CTRL_CAP_24B ECC_CTRL_CAP(4)
#define ECC_CTRL_CAP_32B ECC_CTRL_CAP(5)
#define ECC_CTRL_ERR_THRESHOLD(x) FIELD_PREP(GENMASK(13, 8), (x))
#define INT_MASK_REG 0x10
#define INT_STATUS_REG 0x14
#define INT_CMD_END BIT(1)
#define INT_DMA_END BIT(3)
#define INT_MEM_RDY(cs) FIELD_PREP(GENMASK(11, 8), BIT(cs))
#define INT_DMA_ENDED BIT(3)
#define MEM_IS_RDY(cs, reg) (FIELD_GET(GENMASK(11, 8), (reg)) & BIT(cs))
#define DMA_HAS_ENDED(reg) FIELD_GET(BIT(3), (reg))
#define ECC_OFFSET_REG 0x1C
#define ECC_OFFSET(x) FIELD_PREP(GENMASK(15, 0), (x))
#define ECC_STAT_REG 0x20
#define ECC_STAT_CORRECTABLE(cs, reg) (FIELD_GET(GENMASK(3, 0), (reg)) & BIT(cs))
#define ECC_STAT_UNCORRECTABLE(cs, reg) (FIELD_GET(GENMASK(11, 8), (reg)) & BIT(cs))
#define ADDR0_COL_REG 0x24
#define ADDR0_COL(x) FIELD_PREP(GENMASK(15, 0), (x))
#define ADDR0_ROW_REG 0x28
#define ADDR0_ROW(x) FIELD_PREP(GENMASK(23, 0), (x))
#define ADDR1_COL_REG 0x2C
#define ADDR1_COL(x) FIELD_PREP(GENMASK(15, 0), (x))
#define ADDR1_ROW_REG 0x30
#define ADDR1_ROW(x) FIELD_PREP(GENMASK(23, 0), (x))
#define FIFO_DATA_REG 0x38
#define DATA_REG 0x3C
#define DATA_REG_SIZE_REG 0x40
#define DMA_ADDR_LOW_REG 0x64
#define DMA_ADDR_HIGH_REG 0x68
#define DMA_CNT_REG 0x6C
#define DMA_CTRL_REG 0x70
#define DMA_CTRL_INCREMENT_BURST_4 0
#define DMA_CTRL_REGISTER_MANAGED_MODE 0
#define DMA_CTRL_START BIT(7)
#define MEM_CTRL_REG 0x80
#define MEM_CTRL_CS(cs) FIELD_PREP(GENMASK(1, 0), (cs))
#define MEM_CTRL_DIS_WP(cs) FIELD_PREP(GENMASK(11, 8), BIT((cs)))
#define DATA_SIZE_REG 0x84
#define DATA_SIZE(x) FIELD_PREP(GENMASK(14, 0), (x))
#define TIMINGS_ASYN_REG 0x88
#define TIMINGS_ASYN_TRWP(x) FIELD_PREP(GENMASK(3, 0), max((x), 1U) - 1)
#define TIMINGS_ASYN_TRWH(x) FIELD_PREP(GENMASK(7, 4), max((x), 1U) - 1)
#define TIM_SEQ0_REG 0x90
#define TIM_SEQ0_TCCS(x) FIELD_PREP(GENMASK(5, 0), max((x), 1U) - 1)
#define TIM_SEQ0_TADL(x) FIELD_PREP(GENMASK(13, 8), max((x), 1U) - 1)
#define TIM_SEQ0_TRHW(x) FIELD_PREP(GENMASK(21, 16), max