cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

spi-npcm-fiu.c (21840B)


      1// SPDX-License-Identifier: GPL-2.0
      2// Copyright (c) 2019 Nuvoton Technology corporation.
      3
      4#include <linux/bits.h>
      5#include <linux/init.h>
      6#include <linux/kernel.h>
      7#include <linux/device.h>
      8#include <linux/module.h>
      9#include <linux/ioport.h>
     10#include <linux/clk.h>
     11#include <linux/platform_device.h>
     12#include <linux/io.h>
     13#include <linux/vmalloc.h>
     14#include <linux/regmap.h>
     15#include <linux/of_device.h>
     16#include <linux/spi/spi-mem.h>
     17#include <linux/mfd/syscon.h>
     18
     19/* NPCM7xx GCR module */
     20#define NPCM7XX_INTCR3_OFFSET		0x9C
     21#define NPCM7XX_INTCR3_FIU_FIX		BIT(6)
     22
     23/* Flash Interface Unit (FIU) Registers */
     24#define NPCM_FIU_DRD_CFG		0x00
     25#define NPCM_FIU_DWR_CFG		0x04
     26#define NPCM_FIU_UMA_CFG		0x08
     27#define NPCM_FIU_UMA_CTS		0x0C
     28#define NPCM_FIU_UMA_CMD		0x10
     29#define NPCM_FIU_UMA_ADDR		0x14
     30#define NPCM_FIU_PRT_CFG		0x18
     31#define NPCM_FIU_UMA_DW0		0x20
     32#define NPCM_FIU_UMA_DW1		0x24
     33#define NPCM_FIU_UMA_DW2		0x28
     34#define NPCM_FIU_UMA_DW3		0x2C
     35#define NPCM_FIU_UMA_DR0		0x30
     36#define NPCM_FIU_UMA_DR1		0x34
     37#define NPCM_FIU_UMA_DR2		0x38
     38#define NPCM_FIU_UMA_DR3		0x3C
     39#define NPCM_FIU_MAX_REG_LIMIT		0x80
     40
     41/* FIU Direct Read Configuration Register */
     42#define NPCM_FIU_DRD_CFG_LCK		BIT(31)
     43#define NPCM_FIU_DRD_CFG_R_BURST	GENMASK(25, 24)
     44#define NPCM_FIU_DRD_CFG_ADDSIZ		GENMASK(17, 16)
     45#define NPCM_FIU_DRD_CFG_DBW		GENMASK(13, 12)
     46#define NPCM_FIU_DRD_CFG_ACCTYPE	GENMASK(9, 8)
     47#define NPCM_FIU_DRD_CFG_RDCMD		GENMASK(7, 0)
     48#define NPCM_FIU_DRD_ADDSIZ_SHIFT	16
     49#define NPCM_FIU_DRD_DBW_SHIFT		12
     50#define NPCM_FIU_DRD_ACCTYPE_SHIFT	8
     51
     52/* FIU Direct Write Configuration Register */
     53#define NPCM_FIU_DWR_CFG_LCK		BIT(31)
     54#define NPCM_FIU_DWR_CFG_W_BURST	GENMASK(25, 24)
     55#define NPCM_FIU_DWR_CFG_ADDSIZ		GENMASK(17, 16)
     56#define NPCM_FIU_DWR_CFG_ABPCK		GENMASK(11, 10)
     57#define NPCM_FIU_DWR_CFG_DBPCK		GENMASK(9, 8)
     58#define NPCM_FIU_DWR_CFG_WRCMD		GENMASK(7, 0)
     59#define NPCM_FIU_DWR_ADDSIZ_SHIFT	16
     60#define NPCM_FIU_DWR_ABPCK_SHIFT	10
     61#define NPCM_FIU_DWR_DBPCK_SHIFT	8
     62
     63/* FIU UMA Configuration Register */
     64#define NPCM_FIU_UMA_CFG_LCK		BIT(31)
     65#define NPCM_FIU_UMA_CFG_CMMLCK		BIT(30)
     66#define NPCM_FIU_UMA_CFG_RDATSIZ	GENMASK(28, 24)
     67#define NPCM_FIU_UMA_CFG_DBSIZ		GENMASK(23, 21)
     68#define NPCM_FIU_UMA_CFG_WDATSIZ	GENMASK(20, 16)
     69#define NPCM_FIU_UMA_CFG_ADDSIZ		GENMASK(13, 11)
     70#define NPCM_FIU_UMA_CFG_CMDSIZ		BIT(10)
     71#define NPCM_FIU_UMA_CFG_RDBPCK		GENMASK(9, 8)
     72#define NPCM_FIU_UMA_CFG_DBPCK		GENMASK(7, 6)
     73#define NPCM_FIU_UMA_CFG_WDBPCK		GENMASK(5, 4)
     74#define NPCM_FIU_UMA_CFG_ADBPCK		GENMASK(3, 2)
     75#define NPCM_FIU_UMA_CFG_CMBPCK		GENMASK(1, 0)
     76#define NPCM_FIU_UMA_CFG_ADBPCK_SHIFT	2
     77#define NPCM_FIU_UMA_CFG_WDBPCK_SHIFT	4
     78#define NPCM_FIU_UMA_CFG_DBPCK_SHIFT	6
     79#define NPCM_FIU_UMA_CFG_RDBPCK_SHIFT	8
     80#define NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT	11
     81#define NPCM_FIU_UMA_CFG_WDATSIZ_SHIFT	16
     82#define NPCM_FIU_UMA_CFG_DBSIZ_SHIFT	21
     83#define NPCM_FIU_UMA_CFG_RDATSIZ_SHIFT	24
     84
     85/* FIU UMA Control and Status Register */
     86#define NPCM_FIU_UMA_CTS_RDYIE		BIT(25)
     87#define NPCM_FIU_UMA_CTS_RDYST		BIT(24)
     88#define NPCM_FIU_UMA_CTS_SW_CS		BIT(16)
     89#define NPCM_FIU_UMA_CTS_DEV_NUM	GENMASK(9, 8)
     90#define NPCM_FIU_UMA_CTS_EXEC_DONE	BIT(0)
     91#define NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT	8
     92
     93/* FIU UMA Command Register */
     94#define NPCM_FIU_UMA_CMD_DUM3		GENMASK(31, 24)
     95#define NPCM_FIU_UMA_CMD_DUM2		GENMASK(23, 16)
     96#define NPCM_FIU_UMA_CMD_DUM1		GENMASK(15, 8)
     97#define NPCM_FIU_UMA_CMD_CMD		GENMASK(7, 0)
     98
     99/* FIU UMA Address Register */
    100#define NPCM_FIU_UMA_ADDR_UMA_ADDR	GENMASK(31, 0)
    101#define NPCM_FIU_UMA_ADDR_AB3		GENMASK(31, 24)
    102#define NPCM_FIU_UMA_ADDR_AB2		GENMASK(23, 16)
    103#define NPCM_FIU_UMA_ADDR_AB1		GENMASK(15, 8)
    104#define NPCM_FIU_UMA_ADDR_AB0		GENMASK(7, 0)
    105
    106/* FIU UMA Write Data Bytes 0-3 Register */
    107#define NPCM_FIU_UMA_DW0_WB3		GENMASK(31, 24)
    108#define NPCM_FIU_UMA_DW0_WB2		GENMASK(23, 16)
    109#define NPCM_FIU_UMA_DW0_WB1		GENMASK(15, 8)
    110#define NPCM_FIU_UMA_DW0_WB0		GENMASK(7, 0)
    111
    112/* FIU UMA Write Data Bytes 4-7 Register */
    113#define NPCM_FIU_UMA_DW1_WB7		GENMASK(31, 24)
    114#define NPCM_FIU_UMA_DW1_WB6		GENMASK(23, 16)
    115#define NPCM_FIU_UMA_DW1_WB5		GENMASK(15, 8)
    116#define NPCM_FIU_UMA_DW1_WB4		GENMASK(7, 0)
    117
    118/* FIU UMA Write Data Bytes 8-11 Register */
    119#define NPCM_FIU_UMA_DW2_WB11		GENMASK(31, 24)
    120#define NPCM_FIU_UMA_DW2_WB10		GENMASK(23, 16)
    121#define NPCM_FIU_UMA_DW2_WB9		GENMASK(15, 8)
    122#define NPCM_FIU_UMA_DW2_WB8		GENMASK(7, 0)
    123
    124/* FIU UMA Write Data Bytes 12-15 Register */
    125#define NPCM_FIU_UMA_DW3_WB15		GENMASK(31, 24)
    126#define NPCM_FIU_UMA_DW3_WB14		GENMASK(23, 16)
    127#define NPCM_FIU_UMA_DW3_WB13		GENMASK(15, 8)
    128#define NPCM_FIU_UMA_DW3_WB12		GENMASK(7, 0)
    129
    130/* FIU UMA Read Data Bytes 0-3 Register */
    131#define NPCM_FIU_UMA_DR0_RB3		GENMASK(31, 24)
    132#define NPCM_FIU_UMA_DR0_RB2		GENMASK(23, 16)
    133#define NPCM_FIU_UMA_DR0_RB1		GENMASK(15, 8)
    134#define NPCM_FIU_UMA_DR0_RB0		GENMASK(7, 0)
    135
    136/* FIU UMA Read Data Bytes 4-7 Register */
    137#define NPCM_FIU_UMA_DR1_RB15		GENMASK(31, 24)
    138#define NPCM_FIU_UMA_DR1_RB14		GENMASK(23, 16)
    139#define NPCM_FIU_UMA_DR1_RB13		GENMASK(15, 8)
    140#define NPCM_FIU_UMA_DR1_RB12		GENMASK(7, 0)
    141
    142/* FIU UMA Read Data Bytes 8-11 Register */
    143#define NPCM_FIU_UMA_DR2_RB15		GENMASK(31, 24)
    144#define NPCM_FIU_UMA_DR2_RB14		GENMASK(23, 16)
    145#define NPCM_FIU_UMA_DR2_RB13		GENMASK(15, 8)
    146#define NPCM_FIU_UMA_DR2_RB12		GENMASK(7, 0)
    147
    148/* FIU UMA Read Data Bytes 12-15 Register */
    149#define NPCM_FIU_UMA_DR3_RB15		GENMASK(31, 24)
    150#define NPCM_FIU_UMA_DR3_RB14		GENMASK(23, 16)
    151#define NPCM_FIU_UMA_DR3_RB13		GENMASK(15, 8)
    152#define NPCM_FIU_UMA_DR3_RB12		GENMASK(7, 0)
    153
    154/* FIU Read Mode */
    155enum {
    156	DRD_SINGLE_WIRE_MODE	= 0,
    157	DRD_DUAL_IO_MODE	= 1,
    158	DRD_QUAD_IO_MODE	= 2,
    159	DRD_SPI_X_MODE		= 3,
    160};
    161
    162enum {
    163	DWR_ABPCK_BIT_PER_CLK	= 0,
    164	DWR_ABPCK_2_BIT_PER_CLK	= 1,
    165	DWR_ABPCK_4_BIT_PER_CLK	= 2,
    166};
    167
    168enum {
    169	DWR_DBPCK_BIT_PER_CLK	= 0,
    170	DWR_DBPCK_2_BIT_PER_CLK	= 1,
    171	DWR_DBPCK_4_BIT_PER_CLK	= 2,
    172};
    173
    174#define NPCM_FIU_DRD_16_BYTE_BURST	0x3000000
    175#define NPCM_FIU_DWR_16_BYTE_BURST	0x3000000
    176
    177#define MAP_SIZE_128MB			0x8000000
    178#define MAP_SIZE_16MB			0x1000000
    179#define MAP_SIZE_8MB			0x800000
    180
    181#define FIU_DRD_MAX_DUMMY_NUMBER	3
    182#define NPCM_MAX_CHIP_NUM		4
    183#define CHUNK_SIZE			16
    184#define UMA_MICRO_SEC_TIMEOUT		150
    185
    186enum {
    187	FIU0 = 0,
    188	FIU3,
    189	FIUX,
    190};
    191
    192struct npcm_fiu_info {
    193	char *name;
    194	u32 fiu_id;
    195	u32 max_map_size;
    196	u32 max_cs;
    197};
    198
    199struct fiu_data {
    200	const struct npcm_fiu_info *npcm_fiu_data_info;
    201	int fiu_max;
    202};
    203
    204static const struct npcm_fiu_info npcm7xx_fiu_info[] = {
    205	{.name = "FIU0", .fiu_id = FIU0,
    206		.max_map_size = MAP_SIZE_128MB, .max_cs = 2},
    207	{.name = "FIU3", .fiu_id = FIU3,
    208		.max_map_size = MAP_SIZE_128MB, .max_cs = 4},
    209	{.name = "FIUX", .fiu_id = FIUX,
    210		.max_map_size = MAP_SIZE_16MB, .max_cs = 2} };
    211
    212static const struct fiu_data npcm7xx_fiu_data = {
    213	.npcm_fiu_data_info = npcm7xx_fiu_info,
    214	.fiu_max = 3,
    215};
    216
    217struct npcm_fiu_spi;
    218
    219struct npcm_fiu_chip {
    220	void __iomem *flash_region_mapped_ptr;
    221	struct npcm_fiu_spi *fiu;
    222	unsigned long clkrate;
    223	u32 chipselect;
    224};
    225
    226struct npcm_fiu_spi {
    227	struct npcm_fiu_chip chip[NPCM_MAX_CHIP_NUM];
    228	const struct npcm_fiu_info *info;
    229	struct spi_mem_op drd_op;
    230	struct resource *res_mem;
    231	struct regmap *regmap;
    232	unsigned long clkrate;
    233	struct device *dev;
    234	struct clk *clk;
    235	bool spix_mode;
    236};
    237
    238static const struct regmap_config npcm_mtd_regmap_config = {
    239	.reg_bits = 32,
    240	.val_bits = 32,
    241	.reg_stride = 4,
    242	.max_register = NPCM_FIU_MAX_REG_LIMIT,
    243};
    244
    245static void npcm_fiu_set_drd(struct npcm_fiu_spi *fiu,
    246			     const struct spi_mem_op *op)
    247{
    248	regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
    249			   NPCM_FIU_DRD_CFG_ACCTYPE,
    250			   ilog2(op->addr.buswidth) <<
    251			   NPCM_FIU_DRD_ACCTYPE_SHIFT);
    252	fiu->drd_op.addr.buswidth = op->addr.buswidth;
    253	regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
    254			   NPCM_FIU_DRD_CFG_DBW,
    255			   ((op->dummy.nbytes * ilog2(op->addr.buswidth)) / BITS_PER_BYTE)
    256			   << NPCM_FIU_DRD_DBW_SHIFT);
    257	fiu->drd_op.dummy.nbytes = op->dummy.nbytes;
    258	regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
    259			   NPCM_FIU_DRD_CFG_RDCMD, op->cmd.opcode);
    260	fiu->drd_op.cmd.opcode = op->cmd.opcode;
    261	regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
    262			   NPCM_FIU_DRD_CFG_ADDSIZ,
    263			   (op->addr.nbytes - 3) << NPCM_FIU_DRD_ADDSIZ_SHIFT);
    264	fiu->drd_op.addr.nbytes = op->addr.nbytes;
    265}
    266
    267static ssize_t npcm_fiu_direct_read(struct spi_mem_dirmap_desc *desc,
    268				    u64 offs, size_t len, void *buf)
    269{
    270	struct npcm_fiu_spi *fiu =
    271		spi_controller_get_devdata(desc->mem->spi->master);
    272	struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
    273	void __iomem *src = (void __iomem *)(chip->flash_region_mapped_ptr +
    274					     offs);
    275	u8 *buf_rx = buf;
    276	u32 i;
    277
    278	if (fiu->spix_mode) {
    279		for (i = 0 ; i < len ; i++)
    280			*(buf_rx + i) = ioread8(src + i);
    281	} else {
    282		if (desc->info.op_tmpl.addr.buswidth != fiu->drd_op.addr.buswidth ||
    283		    desc->info.op_tmpl.dummy.nbytes != fiu->drd_op.dummy.nbytes ||
    284		    desc->info.op_tmpl.cmd.opcode != fiu->drd_op.cmd.opcode ||
    285		    desc->info.op_tmpl.addr.nbytes != fiu->drd_op.addr.nbytes)
    286			npcm_fiu_set_drd(fiu, &desc->info.op_tmpl);
    287
    288		memcpy_fromio(buf_rx, src, len);
    289	}
    290
    291	return len;
    292}
    293
    294static ssize_t npcm_fiu_direct_write(struct spi_mem_dirmap_desc *desc,
    295				     u64 offs, size_t len, const void *buf)
    296{
    297	struct npcm_fiu_spi *fiu =
    298		spi_controller_get_devdata(desc->mem->spi->master);
    299	struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
    300	void __iomem *dst = (void __iomem *)(chip->flash_region_mapped_ptr +
    301					     offs);
    302	const u8 *buf_tx = buf;
    303	u32 i;
    304
    305	if (fiu->spix_mode)
    306		for (i = 0 ; i < len ; i++)
    307			iowrite8(*(buf_tx + i), dst + i);
    308	else
    309		memcpy_toio(dst, buf_tx, len);
    310
    311	return len;
    312}
    313
    314static int npcm_fiu_uma_read(struct spi_mem *mem,
    315			     const struct spi_mem_op *op, u32 addr,
    316			      bool is_address_size, u8 *data, u32 data_size)
    317{
    318	struct npcm_fiu_spi *fiu =
    319		spi_controller_get_devdata(mem->spi->master);
    320	u32 uma_cfg = BIT(10);
    321	u32 data_reg[4];
    322	int ret;
    323	u32 val;
    324	u32 i;
    325
    326	regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
    327			   NPCM_FIU_UMA_CTS_DEV_NUM,
    328			   (mem->spi->chip_select <<
    329			    NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
    330	regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CMD,
    331			   NPCM_FIU_UMA_CMD_CMD, op->cmd.opcode);
    332
    333	if (is_address_size) {
    334		uma_cfg |= ilog2(op->cmd.buswidth);
    335		uma_cfg |= ilog2(op->addr.buswidth)
    336			<< NPCM_FIU_UMA_CFG_ADBPCK_SHIFT;
    337		uma_cfg |= ilog2(op->dummy.buswidth)
    338			<< NPCM_FIU_UMA_CFG_DBPCK_SHIFT;
    339		uma_cfg |= ilog2(op->data.buswidth)
    340			<< NPCM_FIU_UMA_CFG_RDBPCK_SHIFT;
    341		uma_cfg |= op->dummy.nbytes << NPCM_FIU_UMA_CFG_DBSIZ_SHIFT;
    342		uma_cfg |= op->addr.nbytes << NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT;
    343		regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, addr);
    344	} else {
    345		regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, 0x0);
    346	}
    347
    348	uma_cfg |= data_size << NPCM_FIU_UMA_CFG_RDATSIZ_SHIFT;
    349	regmap_write(fiu->regmap, NPCM_FIU_UMA_CFG, uma_cfg);
    350	regmap_write_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
    351			  NPCM_FIU_UMA_CTS_EXEC_DONE,
    352			  NPCM_FIU_UMA_CTS_EXEC_DONE);
    353	ret = regmap_read_poll_timeout(fiu->regmap, NPCM_FIU_UMA_CTS, val,
    354				       (!(val & NPCM_FIU_UMA_CTS_EXEC_DONE)), 0,
    355				       UMA_MICRO_SEC_TIMEOUT);
    356	if (ret)
    357		return ret;
    358
    359	if (data_size) {
    360		for (i = 0; i < DIV_ROUND_UP(data_size, 4); i++)
    361			regmap_read(fiu->regmap, NPCM_FIU_UMA_DR0 + (i * 4),
    362				    &data_reg[i]);
    363		memcpy(data, data_reg, data_size);
    364	}
    365
    366	return 0;
    367}
    368
    369static int npcm_fiu_uma_write(struct spi_mem *mem,
    370			      const struct spi_mem_op *op, u8 cmd,
    371			      bool is_address_size, u8 *data, u32 data_size)
    372{
    373	struct npcm_fiu_spi *fiu =
    374		spi_controller_get_devdata(mem->spi->master);
    375	u32 uma_cfg = BIT(10);
    376	u32 data_reg[4] = {0};
    377	u32 val;
    378	u32 i;
    379
    380	regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
    381			   NPCM_FIU_UMA_CTS_DEV_NUM,
    382			   (mem->spi->chip_select <<
    383			    NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
    384
    385	regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CMD,
    386			   NPCM_FIU_UMA_CMD_CMD, cmd);
    387
    388	if (data_size) {
    389		memcpy(data_reg, data, data_size);
    390		for (i = 0; i < DIV_ROUND_UP(data_size, 4); i++)
    391			regmap_write(fiu->regmap, NPCM_FIU_UMA_DW0 + (i * 4),
    392				     data_reg[i]);
    393	}
    394
    395	if (is_address_size) {
    396		uma_cfg |= ilog2(op->cmd.buswidth);
    397		uma_cfg |= ilog2(op->addr.buswidth) <<
    398			NPCM_FIU_UMA_CFG_ADBPCK_SHIFT;
    399		uma_cfg |= ilog2(op->data.buswidth) <<
    400			NPCM_FIU_UMA_CFG_WDBPCK_SHIFT;
    401		uma_cfg |= op->addr.nbytes << NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT;
    402		regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, op->addr.val);
    403	} else {
    404		regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, 0x0);
    405	}
    406
    407	uma_cfg |= (data_size << NPCM_FIU_UMA_CFG_WDATSIZ_SHIFT);
    408	regmap_write(fiu->regmap, NPCM_FIU_UMA_CFG, uma_cfg);
    409
    410	regmap_write_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
    411			  NPCM_FIU_UMA_CTS_EXEC_DONE,
    412			  NPCM_FIU_UMA_CTS_EXEC_DONE);
    413
    414	return regmap_read_poll_timeout(fiu->regmap, NPCM_FIU_UMA_CTS, val,
    415				       (!(val & NPCM_FIU_UMA_CTS_EXEC_DONE)), 0,
    416					UMA_MICRO_SEC_TIMEOUT);
    417}
    418
    419static int npcm_fiu_manualwrite(struct spi_mem *mem,
    420				const struct spi_mem_op *op)
    421{
    422	struct npcm_fiu_spi *fiu =
    423		spi_controller_get_devdata(mem->spi->master);
    424	u8 *data = (u8 *)op->data.buf.out;
    425	u32 num_data_chunks;
    426	u32 remain_data;
    427	u32 idx = 0;
    428	int ret;
    429
    430	num_data_chunks  = op->data.nbytes / CHUNK_SIZE;
    431	remain_data  = op->data.nbytes % CHUNK_SIZE;
    432
    433	regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
    434			   NPCM_FIU_UMA_CTS_DEV_NUM,
    435			   (mem->spi->chip_select <<
    436			    NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
    437	regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
    438			   NPCM_FIU_UMA_CTS_SW_CS, 0);
    439
    440	ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, true, NULL, 0);
    441	if (ret)
    442		return ret;
    443
    444	/* Starting the data writing loop in multiples of 8 */
    445	for (idx = 0; idx < num_data_chunks; ++idx) {
    446		ret = npcm_fiu_uma_write(mem, op, data[0], false,
    447					 &data[1], CHUNK_SIZE - 1);
    448		if (ret)
    449			return ret;
    450
    451		data += CHUNK_SIZE;
    452	}
    453
    454	/* Handling chunk remains */
    455	if (remain_data > 0) {
    456		ret = npcm_fiu_uma_write(mem, op, data[0], false,
    457					 &data[1], remain_data - 1);
    458		if (ret)
    459			return ret;
    460	}
    461
    462	regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
    463			   NPCM_FIU_UMA_CTS_SW_CS, NPCM_FIU_UMA_CTS_SW_CS);
    464
    465	return 0;
    466}
    467
    468static int npcm_fiu_read(struct spi_mem *mem, const struct spi_mem_op *op)
    469{
    470	u8 *data = op->data.buf.in;
    471	int i, readlen, currlen;
    472	u8 *buf_ptr;
    473	u32 addr;
    474	int ret;
    475
    476	i = 0;
    477	currlen = op->data.nbytes;
    478
    479	do {
    480		addr = ((u32)op->addr.val + i);
    481		if (currlen < 16)
    482			readlen = currlen;
    483		else
    484			readlen = 16;
    485
    486		buf_ptr = data + i;
    487		ret = npcm_fiu_uma_read(mem, op, addr, true, buf_ptr,
    488					readlen);
    489		if (ret)
    490			return ret;
    491
    492		i += readlen;
    493		currlen -= 16;
    494	} while (currlen > 0);
    495
    496	return 0;
    497}
    498
    499static void npcm_fiux_set_direct_wr(struct npcm_fiu_spi *fiu)
    500{
    501	regmap_write(fiu->regmap, NPCM_FIU_DWR_CFG,
    502		     NPCM_FIU_DWR_16_BYTE_BURST);
    503	regmap_update_bits(fiu->regmap, NPCM_FIU_DWR_CFG,
    504			   NPCM_FIU_DWR_CFG_ABPCK,
    505			   DWR_ABPCK_4_BIT_PER_CLK << NPCM_FIU_DWR_ABPCK_SHIFT);
    506	regmap_update_bits(fiu->regmap, NPCM_FIU_DWR_CFG,
    507			   NPCM_FIU_DWR_CFG_DBPCK,
    508			   DWR_DBPCK_4_BIT_PER_CLK << NPCM_FIU_DWR_DBPCK_SHIFT);
    509}
    510
    511static void npcm_fiux_set_direct_rd(struct npcm_fiu_spi *fiu)
    512{
    513	u32 rx_dummy = 0;
    514
    515	regmap_write(fiu->regmap, NPCM_FIU_DRD_CFG,
    516		     NPCM_FIU_DRD_16_BYTE_BURST);
    517	regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
    518			   NPCM_FIU_DRD_CFG_ACCTYPE,
    519			   DRD_SPI_X_MODE << NPCM_FIU_DRD_ACCTYPE_SHIFT);
    520	regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
    521			   NPCM_FIU_DRD_CFG_DBW,
    522			   rx_dummy << NPCM_FIU_DRD_DBW_SHIFT);
    523}
    524
    525static int npcm_fiu_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
    526{
    527	struct npcm_fiu_spi *fiu =
    528		spi_controller_get_devdata(mem->spi->master);
    529	struct npcm_fiu_chip *chip = &fiu->chip[mem->spi->chip_select];
    530	int ret = 0;
    531	u8 *buf;
    532
    533	dev_dbg(fiu->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n",
    534		op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
    535		op->dummy.buswidth, op->data.buswidth, op->addr.val,
    536		op->data.nbytes);
    537
    538	if (fiu->spix_mode || op->addr.nbytes > 4)
    539		return -ENOTSUPP;
    540
    541	if (fiu->clkrate != chip->clkrate) {
    542		ret = clk_set_rate(fiu->clk, chip->clkrate);
    543		if (ret < 0)
    544			dev_warn(fiu->dev, "Failed setting %lu frequency, stay at %lu frequency\n",
    545				 chip->clkrate, fiu->clkrate);
    546		else
    547			fiu->clkrate = chip->clkrate;
    548	}
    549
    550	if (op->data.dir == SPI_MEM_DATA_IN) {
    551		if (!op->addr.nbytes) {
    552			buf = op->data.buf.in;
    553			ret = npcm_fiu_uma_read(mem, op, op->addr.val, false,
    554						buf, op->data.nbytes);
    555		} else {
    556			ret = npcm_fiu_read(mem, op);
    557		}
    558	} else  {
    559		if (!op->addr.nbytes && !op->data.nbytes)
    560			ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false,
    561						 NULL, 0);
    562		if (op->addr.nbytes && !op->data.nbytes) {
    563			int i;
    564			u8 buf_addr[4];
    565			u32 addr = op->addr.val;
    566
    567			for (i = op->addr.nbytes - 1; i >= 0; i--) {
    568				buf_addr[i] = addr & 0xff;
    569				addr >>= 8;
    570			}
    571			ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false,
    572						 buf_addr, op->addr.nbytes);
    573		}
    574		if (!op->addr.nbytes && op->data.nbytes)
    575			ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false,
    576						 (u8 *)op->data.buf.out,
    577						 op->data.nbytes);
    578		if (op->addr.nbytes && op->data.nbytes)
    579			ret = npcm_fiu_manualwrite(mem, op);
    580	}
    581
    582	return ret;
    583}
    584
    585static int npcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)
    586{
    587	struct npcm_fiu_spi *fiu =
    588		spi_controller_get_devdata(desc->mem->spi->master);
    589	struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
    590	struct regmap *gcr_regmap;
    591
    592	if (!fiu->res_mem) {
    593		dev_warn(fiu->dev, "Reserved memory not defined, direct read disabled\n");
    594		desc->nodirmap = true;
    595		return 0;
    596	}
    597
    598	if (!fiu->spix_mode &&
    599	    desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) {
    600		desc->nodirmap = true;
    601		return 0;
    602	}
    603
    604	if (!chip->flash_region_mapped_ptr) {
    605		chip->flash_region_mapped_ptr =
    606			devm_ioremap(fiu->dev, (fiu->res_mem->start +
    607							(fiu->info->max_map_size *
    608						    desc->mem->spi->chip_select)),
    609					     (u32)desc->info.length);
    610		if (!chip->flash_region_mapped_ptr) {
    611			dev_warn(fiu->dev, "Error mapping memory region, direct read disabled\n");
    612			desc->nodirmap = true;
    613			return 0;
    614		}
    615	}
    616
    617	if (of_device_is_compatible(fiu->dev->of_node, "nuvoton,npcm750-fiu")) {
    618		gcr_regmap =
    619			syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
    620		if (IS_ERR(gcr_regmap)) {
    621			dev_warn(fiu->dev, "Didn't find nuvoton,npcm750-gcr, direct read disabled\n");
    622			desc->nodirmap = true;
    623			return 0;
    624		}
    625		regmap_update_bits(gcr_regmap, NPCM7XX_INTCR3_OFFSET,
    626				   NPCM7XX_INTCR3_FIU_FIX,
    627				   NPCM7XX_INTCR3_FIU_FIX);
    628	}
    629
    630	if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN) {
    631		if (!fiu->spix_mode)
    632			npcm_fiu_set_drd(fiu, &desc->info.op_tmpl);
    633		else
    634			npcm_fiux_set_direct_rd(fiu);
    635
    636	} else {
    637		npcm_fiux_set_direct_wr(fiu);
    638	}
    639
    640	return 0;
    641}
    642
    643static int npcm_fiu_setup(struct spi_device *spi)
    644{
    645	struct spi_controller *ctrl = spi->master;
    646	struct npcm_fiu_spi *fiu = spi_controller_get_devdata(ctrl);
    647	struct npcm_fiu_chip *chip;
    648
    649	chip = &fiu->chip[spi->chip_select];
    650	chip->fiu = fiu;
    651	chip->chipselect = spi->chip_select;
    652	chip->clkrate = spi->max_speed_hz;
    653
    654	fiu->clkrate = clk_get_rate(fiu->clk);
    655
    656	return 0;
    657}
    658
    659static const struct spi_controller_mem_ops npcm_fiu_mem_ops = {
    660	.exec_op = npcm_fiu_exec_op,
    661	.dirmap_create = npcm_fiu_dirmap_create,
    662	.dirmap_read = npcm_fiu_direct_read,
    663	.dirmap_write = npcm_fiu_direct_write,
    664};
    665
    666static const struct of_device_id npcm_fiu_dt_ids[] = {
    667	{ .compatible = "nuvoton,npcm750-fiu", .data = &npcm7xx_fiu_data  },
    668	{ /* sentinel */ }
    669};
    670
    671static int npcm_fiu_probe(struct platform_device *pdev)
    672{
    673	const struct fiu_data *fiu_data_match;
    674	struct device *dev = &pdev->dev;
    675	struct spi_controller *ctrl;
    676	struct npcm_fiu_spi *fiu;
    677	void __iomem *regbase;
    678	struct resource *res;
    679	int id, ret;
    680
    681	ctrl = devm_spi_alloc_master(dev, sizeof(*fiu));
    682	if (!ctrl)
    683		return -ENOMEM;
    684
    685	fiu = spi_controller_get_devdata(ctrl);
    686
    687	fiu_data_match = of_device_get_match_data(dev);
    688	if (!fiu_data_match) {
    689		dev_err(dev, "No compatible OF match\n");
    690		return -ENODEV;
    691	}
    692
    693	id = of_alias_get_id(dev->of_node, "fiu");
    694	if (id < 0 || id >= fiu_data_match->fiu_max) {
    695		dev_err(dev, "Invalid platform device id: %d\n", id);
    696		return -EINVAL;
    697	}
    698
    699	fiu->info = &fiu_data_match->npcm_fiu_data_info[id];
    700
    701	platform_set_drvdata(pdev, fiu);
    702	fiu->dev = dev;
    703
    704	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control");
    705	regbase = devm_ioremap_resource(dev, res);
    706	if (IS_ERR(regbase))
    707		return PTR_ERR(regbase);
    708
    709	fiu->regmap = devm_regmap_init_mmio(dev, regbase,
    710					    &npcm_mtd_regmap_config);
    711	if (IS_ERR(fiu->regmap)) {
    712		dev_err(dev, "Failed to create regmap\n");
    713		return PTR_ERR(fiu->regmap);
    714	}
    715
    716	fiu->res_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
    717						    "memory");
    718	fiu->clk = devm_clk_get(dev, NULL);
    719	if (IS_ERR(fiu->clk))
    720		return PTR_ERR(fiu->clk);
    721
    722	fiu->spix_mode = of_property_read_bool(dev->of_node,
    723					       "nuvoton,spix-mode");
    724
    725	platform_set_drvdata(pdev, fiu);
    726	clk_prepare_enable(fiu->clk);
    727
    728	ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD
    729		| SPI_TX_DUAL | SPI_TX_QUAD;
    730	ctrl->setup = npcm_fiu_setup;
    731	ctrl->bus_num = -1;
    732	ctrl->mem_ops = &npcm_fiu_mem_ops;
    733	ctrl->num_chipselect = fiu->info->max_cs;
    734	ctrl->dev.of_node = dev->of_node;
    735
    736	ret = devm_spi_register_master(dev, ctrl);
    737	if (ret)
    738		clk_disable_unprepare(fiu->clk);
    739
    740	return ret;
    741}
    742
    743static int npcm_fiu_remove(struct platform_device *pdev)
    744{
    745	struct npcm_fiu_spi *fiu = platform_get_drvdata(pdev);
    746
    747	clk_disable_unprepare(fiu->clk);
    748	return 0;
    749}
    750
    751MODULE_DEVICE_TABLE(of, npcm_fiu_dt_ids);
    752
    753static struct platform_driver npcm_fiu_driver = {
    754	.driver = {
    755		.name	= "NPCM-FIU",
    756		.bus	= &platform_bus_type,
    757		.of_match_table = npcm_fiu_dt_ids,
    758	},
    759	.probe      = npcm_fiu_probe,
    760	.remove	    = npcm_fiu_remove,
    761};
    762module_platform_driver(npcm_fiu_driver);
    763
    764MODULE_DESCRIPTION("Nuvoton FLASH Interface Unit SPI Controller Driver");
    765MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
    766MODULE_LICENSE("GPL v2");