// SPDX-License-Identifier: GPL-2.0+
/*
* NXP xSPI controller driver.
*
* Copyright 2025 NXP
*
* xSPI is a flexible SPI host controller which supports single
* external devices. This device can have up to eight bidirectional
* data lines, this means xSPI support Single/Dual/Quad/Octal mode
* data transfer (1/2/4/8 bidirectional data lines).
*
* xSPI controller is driven by the LUT(Look-up Table) registers
* LUT registers are a look-up-table for sequences of instructions.
* A valid sequence consists of five LUT registers.
* Maximum 16 LUT sequences can be programmed simultaneously.
*
* LUTs are being created at run-time based on the commands passed
* from the spi-mem framework, thus using single LUT index.
*
* Software triggered Flash read/write access by IP Bus.
*
* Memory mapped read access by AHB Bus.
*
* Based on SPI MEM interface and spi-nxp-fspi.c driver.
*
* Author:
* Haibo Chen <haibo.chen@nxp.com>
* Co-author:
* Han Xu <han.xu@nxp.com>
*/
#include <linux/bitops.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h>
/* Runtime pm timeout */
#define XSPI_RPM_TIMEOUT_MS 50 /* 50ms */
/*
* The driver only uses one single LUT entry, that is updated on
* each call of exec_op(). Index 0 is preset at boot with a basic
* read operation, so let's use the last entry (15).
*/
#define XSPI_SEQID_LUT 15
#define XSPI_MCR 0x0
#define XSPI_MCR_CKN_FA_EN BIT(26)
#define XSPI_MCR_DQS_FA_SEL_MASK GENMASK(25, 24)
#define XSPI_MCR_ISD3FA BIT(17)
#define XSPI_MCR_ISD2FA BIT(16)
#define XSPI_MCR_DOZE BIT(15)
#define XSPI_MCR_MDIS BIT(14)
#define XSPI_MCR_DLPEN BIT(12)
#define XSPI_MCR_CLR_TXF BIT(11)
#define XSPI_MCR_CLR_RXF BIT(10)
#define XSPI_MCR_IPS_TG_RST BIT(9)
#define XSPI_MCR_VAR_LAT_EN BIT(8)
#define XSPI_MCR_DDR_EN BIT(7)
#define XSPI_MCR_DQS_EN BIT(6)
#define XSPI_MCR_DQS_LAT_EN BIT(5)
#define XSPI_MCR_DQS_OUT_EN BIT(4)
#define XSPI_MCR_SWRSTHD BIT(1)
#define XSPI_MCR_SWRSTSD BIT(0)
#define XSPI_IPCR 0x8
#define XSPI_FLSHCR 0xC
#define XSPI_FLSHCR_TDH_MASK GENMASK(17, 16)
#define XSPI_FLSHCR_TCSH_MASK GENMASK(11, 8)
#define XSPI_FLSHCR_TCSS_MASK GENMASK(3, 0)
#define XSPI_BUF0CR 0x10
#define XSPI_BUF1CR 0x14
#define XSPI_BUF2CR 0x18
#define XSPI_BUF3CR 0x1C
#define XSPI_BUF3CR_ALLMST BIT(31)
#define XSPI_BUF3CR_ADATSZ_MASK GENMASK(17, 8)
#define XSPI_BUF3CR_MSTRID_MASK GENMASK(3, 0)
#define XSPI_BFGENCR 0x20
#define XSPI_BFGENCR_SEQID_WR_MASK GENMASK(31, 28)
#define XSPI_BFGENCR_ALIGN_MASK GENMASK(24, 22)
#define XSPI_BFGENCR_PPWF_CLR BIT(20)
#define XSPI_BFGENCR_WR_FLUSH_EN BIT(21)
#define XSPI_BFGENCR_SEQID_WR_EN BIT(17)
#define XSPI_BFGENCR_SEQID_MASK GENMASK(15, 12)
#define XSPI_BUF0IND 0x30
#define XSPI_BUF1IND 0x34
#define XSPI_BUF2IND 0x38
#define XSPI_DLLCRA 0x60
#define XSPI_DLLCRA_DLLEN BIT(31)
#define XSPI_DLLCRA_FREQEN BIT(30)
#define XSPI_DLLCRA_DLL_REFCNTR_MASK GENMASK(27, 24)
#define XSPI_DLLCRA_DLLRES_MASK GENMASK(23, 20)
#define XSPI_DLLCRA_SLV_FINE_MASK GENMASK(19, 16)
#define XSPI_DLLCRA_SLV_DLY_MASK GENMASK(14, 12)
#define XSPI_DLLCRA_SLV_DLY_COARSE_MASK GENMASK(11, 8)
#define XSPI_DLLCRA_SLV_DLY_FINE_MASK GENMASK(7, 5)
#define XSPI_DLLCRA_DLL_CDL8 BIT(4)
#define XSPI_DLLCRA_SLAVE_AUTO_UPDT BIT(3)
#define XSPI_DLLCRA_SLV_EN BIT(2)
#define XSPI_DLLCRA_SLV_DLL_BYPASS BIT(1)
#define XSPI_DLLCRA_SLV_UPD BIT(0)
#define XSPI_SFAR 0x100
#define XSPI_SFACR 0x104
#define XSPI_SFACR_FORCE_A10 BIT(22)
#define XSPI_SFACR_WA_4B_EN BIT(21)
#define XSPI_SFACR_CAS_INTRLVD BIT(20)
#define XSPI_SFACR_RX_BP_EN BIT(18)
#define XSPI_SFACR_BYTE_SWAP BIT(17)
#define XSPI_SFACR_WA BIT(16)
#define XSPI_SFACR_CAS_MASK GENMASK(3, 0)
#define XSPI_SMPR 0x108
#define XSPI_SMPR_DLLFSMPFA_MASK GENMASK(26, 24)
#define XSPI