brintos

brintos / linux-shallow public Read only

0
0
Text · 11.9 KiB · 89a7f0b Raw
497 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * HiSilicon FMC SPI NOR flash controller driver4 *5 * Copyright (c) 2015-2016 HiSilicon Technologies Co., Ltd.6 */7#include <linux/bitops.h>8#include <linux/clk.h>9#include <linux/dma-mapping.h>10#include <linux/iopoll.h>11#include <linux/module.h>12#include <linux/mtd/mtd.h>13#include <linux/mtd/spi-nor.h>14#include <linux/of.h>15#include <linux/platform_device.h>16#include <linux/slab.h>17 18/* Hardware register offsets and field definitions */19#define FMC_CFG				0x0020#define FMC_CFG_OP_MODE_MASK		BIT_MASK(0)21#define FMC_CFG_OP_MODE_BOOT		022#define FMC_CFG_OP_MODE_NORMAL		123#define FMC_CFG_FLASH_SEL(type)		(((type) & 0x3) << 1)24#define FMC_CFG_FLASH_SEL_MASK		0x625#define FMC_ECC_TYPE(type)		(((type) & 0x7) << 5)26#define FMC_ECC_TYPE_MASK		GENMASK(7, 5)27#define SPI_NOR_ADDR_MODE_MASK		BIT_MASK(10)28#define SPI_NOR_ADDR_MODE_3BYTES	(0x0 << 10)29#define SPI_NOR_ADDR_MODE_4BYTES	(0x1 << 10)30#define FMC_GLOBAL_CFG			0x0431#define FMC_GLOBAL_CFG_WP_ENABLE	BIT(6)32#define FMC_SPI_TIMING_CFG		0x0833#define TIMING_CFG_TCSH(nr)		(((nr) & 0xf) << 8)34#define TIMING_CFG_TCSS(nr)		(((nr) & 0xf) << 4)35#define TIMING_CFG_TSHSL(nr)		((nr) & 0xf)36#define CS_HOLD_TIME			0x637#define CS_SETUP_TIME			0x638#define CS_DESELECT_TIME		0xf39#define FMC_INT				0x1840#define FMC_INT_OP_DONE			BIT(0)41#define FMC_INT_CLR			0x2042#define FMC_CMD				0x2443#define FMC_CMD_CMD1(cmd)		((cmd) & 0xff)44#define FMC_ADDRL			0x2c45#define FMC_OP_CFG			0x3046#define OP_CFG_FM_CS(cs)		((cs) << 11)47#define OP_CFG_MEM_IF_TYPE(type)	(((type) & 0x7) << 7)48#define OP_CFG_ADDR_NUM(addr)		(((addr) & 0x7) << 4)49#define OP_CFG_DUMMY_NUM(dummy)		((dummy) & 0xf)50#define FMC_DATA_NUM			0x3851#define FMC_DATA_NUM_CNT(cnt)		((cnt) & GENMASK(13, 0))52#define FMC_OP				0x3c53#define FMC_OP_DUMMY_EN			BIT(8)54#define FMC_OP_CMD1_EN			BIT(7)55#define FMC_OP_ADDR_EN			BIT(6)56#define FMC_OP_WRITE_DATA_EN		BIT(5)57#define FMC_OP_READ_DATA_EN		BIT(2)58#define FMC_OP_READ_STATUS_EN		BIT(1)59#define FMC_OP_REG_OP_START		BIT(0)60#define FMC_DMA_LEN			0x4061#define FMC_DMA_LEN_SET(len)		((len) & GENMASK(27, 0))62#define FMC_DMA_SADDR_D0		0x4c63#define HIFMC_DMA_MAX_LEN		(4096)64#define HIFMC_DMA_MASK			(HIFMC_DMA_MAX_LEN - 1)65#define FMC_OP_DMA			0x6866#define OP_CTRL_RD_OPCODE(code)		(((code) & 0xff) << 16)67#define OP_CTRL_WR_OPCODE(code)		(((code) & 0xff) << 8)68#define OP_CTRL_RW_OP(op)		((op) << 1)69#define OP_CTRL_DMA_OP_READY		BIT(0)70#define FMC_OP_READ			0x071#define FMC_OP_WRITE			0x172#define FMC_WAIT_TIMEOUT		100000073 74enum hifmc_iftype {75	IF_TYPE_STD,76	IF_TYPE_DUAL,77	IF_TYPE_DIO,78	IF_TYPE_QUAD,79	IF_TYPE_QIO,80};81 82struct hifmc_priv {83	u32 chipselect;84	u32 clkrate;85	struct hifmc_host *host;86};87 88#define HIFMC_MAX_CHIP_NUM		289struct hifmc_host {90	struct device *dev;91	struct mutex lock;92 93	void __iomem *regbase;94	void __iomem *iobase;95	struct clk *clk;96	void *buffer;97	dma_addr_t dma_buffer;98 99	struct spi_nor	*nor[HIFMC_MAX_CHIP_NUM];100	u32 num_chip;101};102 103static inline int hisi_spi_nor_wait_op_finish(struct hifmc_host *host)104{105	u32 reg;106 107	return readl_poll_timeout(host->regbase + FMC_INT, reg,108		(reg & FMC_INT_OP_DONE), 0, FMC_WAIT_TIMEOUT);109}110 111static int hisi_spi_nor_get_if_type(enum spi_nor_protocol proto)112{113	enum hifmc_iftype if_type;114 115	switch (proto) {116	case SNOR_PROTO_1_1_2:117		if_type = IF_TYPE_DUAL;118		break;119	case SNOR_PROTO_1_2_2:120		if_type = IF_TYPE_DIO;121		break;122	case SNOR_PROTO_1_1_4:123		if_type = IF_TYPE_QUAD;124		break;125	case SNOR_PROTO_1_4_4:126		if_type = IF_TYPE_QIO;127		break;128	case SNOR_PROTO_1_1_1:129	default:130		if_type = IF_TYPE_STD;131		break;132	}133 134	return if_type;135}136 137static void hisi_spi_nor_init(struct hifmc_host *host)138{139	u32 reg;140 141	reg = TIMING_CFG_TCSH(CS_HOLD_TIME)142		| TIMING_CFG_TCSS(CS_SETUP_TIME)143		| TIMING_CFG_TSHSL(CS_DESELECT_TIME);144	writel(reg, host->regbase + FMC_SPI_TIMING_CFG);145}146 147static int hisi_spi_nor_prep(struct spi_nor *nor)148{149	struct hifmc_priv *priv = nor->priv;150	struct hifmc_host *host = priv->host;151	int ret;152 153	mutex_lock(&host->lock);154 155	ret = clk_set_rate(host->clk, priv->clkrate);156	if (ret)157		goto out;158 159	ret = clk_prepare_enable(host->clk);160	if (ret)161		goto out;162 163	return 0;164 165out:166	mutex_unlock(&host->lock);167	return ret;168}169 170static void hisi_spi_nor_unprep(struct spi_nor *nor)171{172	struct hifmc_priv *priv = nor->priv;173	struct hifmc_host *host = priv->host;174 175	clk_disable_unprepare(host->clk);176	mutex_unlock(&host->lock);177}178 179static int hisi_spi_nor_op_reg(struct spi_nor *nor,180				u8 opcode, size_t len, u8 optype)181{182	struct hifmc_priv *priv = nor->priv;183	struct hifmc_host *host = priv->host;184	u32 reg;185 186	reg = FMC_CMD_CMD1(opcode);187	writel(reg, host->regbase + FMC_CMD);188 189	reg = FMC_DATA_NUM_CNT(len);190	writel(reg, host->regbase + FMC_DATA_NUM);191 192	reg = OP_CFG_FM_CS(priv->chipselect);193	writel(reg, host->regbase + FMC_OP_CFG);194 195	writel(0xff, host->regbase + FMC_INT_CLR);196	reg = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START | optype;197	writel(reg, host->regbase + FMC_OP);198 199	return hisi_spi_nor_wait_op_finish(host);200}201 202static int hisi_spi_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,203				 size_t len)204{205	struct hifmc_priv *priv = nor->priv;206	struct hifmc_host *host = priv->host;207	int ret;208 209	ret = hisi_spi_nor_op_reg(nor, opcode, len, FMC_OP_READ_DATA_EN);210	if (ret)211		return ret;212 213	memcpy_fromio(buf, host->iobase, len);214	return 0;215}216 217static int hisi_spi_nor_write_reg(struct spi_nor *nor, u8 opcode,218				  const u8 *buf, size_t len)219{220	struct hifmc_priv *priv = nor->priv;221	struct hifmc_host *host = priv->host;222 223	if (len)224		memcpy_toio(host->iobase, buf, len);225 226	return hisi_spi_nor_op_reg(nor, opcode, len, FMC_OP_WRITE_DATA_EN);227}228 229static int hisi_spi_nor_dma_transfer(struct spi_nor *nor, loff_t start_off,230		dma_addr_t dma_buf, size_t len, u8 op_type)231{232	struct hifmc_priv *priv = nor->priv;233	struct hifmc_host *host = priv->host;234	u8 if_type = 0;235	u32 reg;236 237	reg = readl(host->regbase + FMC_CFG);238	reg &= ~(FMC_CFG_OP_MODE_MASK | SPI_NOR_ADDR_MODE_MASK);239	reg |= FMC_CFG_OP_MODE_NORMAL;240	reg |= (nor->addr_nbytes == 4) ? SPI_NOR_ADDR_MODE_4BYTES241		: SPI_NOR_ADDR_MODE_3BYTES;242	writel(reg, host->regbase + FMC_CFG);243 244	writel(start_off, host->regbase + FMC_ADDRL);245	writel(dma_buf, host->regbase + FMC_DMA_SADDR_D0);246	writel(FMC_DMA_LEN_SET(len), host->regbase + FMC_DMA_LEN);247 248	reg = OP_CFG_FM_CS(priv->chipselect);249	if (op_type == FMC_OP_READ)250		if_type = hisi_spi_nor_get_if_type(nor->read_proto);251	else252		if_type = hisi_spi_nor_get_if_type(nor->write_proto);253	reg |= OP_CFG_MEM_IF_TYPE(if_type);254	if (op_type == FMC_OP_READ)255		reg |= OP_CFG_DUMMY_NUM(nor->read_dummy >> 3);256	writel(reg, host->regbase + FMC_OP_CFG);257 258	writel(0xff, host->regbase + FMC_INT_CLR);259	reg = OP_CTRL_RW_OP(op_type) | OP_CTRL_DMA_OP_READY;260	reg |= (op_type == FMC_OP_READ)261		? OP_CTRL_RD_OPCODE(nor->read_opcode)262		: OP_CTRL_WR_OPCODE(nor->program_opcode);263	writel(reg, host->regbase + FMC_OP_DMA);264 265	return hisi_spi_nor_wait_op_finish(host);266}267 268static ssize_t hisi_spi_nor_read(struct spi_nor *nor, loff_t from, size_t len,269		u_char *read_buf)270{271	struct hifmc_priv *priv = nor->priv;272	struct hifmc_host *host = priv->host;273	size_t offset;274	int ret;275 276	for (offset = 0; offset < len; offset += HIFMC_DMA_MAX_LEN) {277		size_t trans = min_t(size_t, HIFMC_DMA_MAX_LEN, len - offset);278 279		ret = hisi_spi_nor_dma_transfer(nor,280			from + offset, host->dma_buffer, trans, FMC_OP_READ);281		if (ret) {282			dev_warn(nor->dev, "DMA read timeout\n");283			return ret;284		}285		memcpy(read_buf + offset, host->buffer, trans);286	}287 288	return len;289}290 291static ssize_t hisi_spi_nor_write(struct spi_nor *nor, loff_t to,292			size_t len, const u_char *write_buf)293{294	struct hifmc_priv *priv = nor->priv;295	struct hifmc_host *host = priv->host;296	size_t offset;297	int ret;298 299	for (offset = 0; offset < len; offset += HIFMC_DMA_MAX_LEN) {300		size_t trans = min_t(size_t, HIFMC_DMA_MAX_LEN, len - offset);301 302		memcpy(host->buffer, write_buf + offset, trans);303		ret = hisi_spi_nor_dma_transfer(nor,304			to + offset, host->dma_buffer, trans, FMC_OP_WRITE);305		if (ret) {306			dev_warn(nor->dev, "DMA write timeout\n");307			return ret;308		}309	}310 311	return len;312}313 314static const struct spi_nor_controller_ops hisi_controller_ops = {315	.prepare = hisi_spi_nor_prep,316	.unprepare = hisi_spi_nor_unprep,317	.read_reg = hisi_spi_nor_read_reg,318	.write_reg = hisi_spi_nor_write_reg,319	.read = hisi_spi_nor_read,320	.write = hisi_spi_nor_write,321};322 323/*324 * Get spi flash device information and register it as a mtd device.325 */326static int hisi_spi_nor_register(struct device_node *np,327				struct hifmc_host *host)328{329	const struct spi_nor_hwcaps hwcaps = {330		.mask = SNOR_HWCAPS_READ |331			SNOR_HWCAPS_READ_FAST |332			SNOR_HWCAPS_READ_1_1_2 |333			SNOR_HWCAPS_READ_1_1_4 |334			SNOR_HWCAPS_PP,335	};336	struct device *dev = host->dev;337	struct spi_nor *nor;338	struct hifmc_priv *priv;339	struct mtd_info *mtd;340	int ret;341 342	nor = devm_kzalloc(dev, sizeof(*nor), GFP_KERNEL);343	if (!nor)344		return -ENOMEM;345 346	nor->dev = dev;347	spi_nor_set_flash_node(nor, np);348 349	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);350	if (!priv)351		return -ENOMEM;352 353	ret = of_property_read_u32(np, "reg", &priv->chipselect);354	if (ret) {355		dev_err(dev, "There's no reg property for %pOF\n",356			np);357		return ret;358	}359 360	ret = of_property_read_u32(np, "spi-max-frequency",361			&priv->clkrate);362	if (ret) {363		dev_err(dev, "There's no spi-max-frequency property for %pOF\n",364			np);365		return ret;366	}367	priv->host = host;368	nor->priv = priv;369	nor->controller_ops = &hisi_controller_ops;370 371	ret = spi_nor_scan(nor, NULL, &hwcaps);372	if (ret)373		return ret;374 375	mtd = &nor->mtd;376	mtd->name = np->name;377	ret = mtd_device_register(mtd, NULL, 0);378	if (ret)379		return ret;380 381	host->nor[host->num_chip] = nor;382	host->num_chip++;383	return 0;384}385 386static void hisi_spi_nor_unregister_all(struct hifmc_host *host)387{388	int i;389 390	for (i = 0; i < host->num_chip; i++)391		mtd_device_unregister(&host->nor[i]->mtd);392}393 394static int hisi_spi_nor_register_all(struct hifmc_host *host)395{396	struct device *dev = host->dev;397	struct device_node *np;398	int ret;399 400	for_each_available_child_of_node(dev->of_node, np) {401		ret = hisi_spi_nor_register(np, host);402		if (ret) {403			of_node_put(np);404			goto fail;405		}406 407		if (host->num_chip == HIFMC_MAX_CHIP_NUM) {408			dev_warn(dev, "Flash device number exceeds the maximum chipselect number\n");409			of_node_put(np);410			break;411		}412	}413 414	return 0;415 416fail:417	hisi_spi_nor_unregister_all(host);418	return ret;419}420 421static int hisi_spi_nor_probe(struct platform_device *pdev)422{423	struct device *dev = &pdev->dev;424	struct hifmc_host *host;425	int ret;426 427	host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);428	if (!host)429		return -ENOMEM;430 431	platform_set_drvdata(pdev, host);432	host->dev = dev;433 434	host->regbase = devm_platform_ioremap_resource_byname(pdev, "control");435	if (IS_ERR(host->regbase))436		return PTR_ERR(host->regbase);437 438	host->iobase = devm_platform_ioremap_resource_byname(pdev, "memory");439	if (IS_ERR(host->iobase))440		return PTR_ERR(host->iobase);441 442	host->clk = devm_clk_get(dev, NULL);443	if (IS_ERR(host->clk))444		return PTR_ERR(host->clk);445 446	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));447	if (ret) {448		dev_warn(dev, "Unable to set dma mask\n");449		return ret;450	}451 452	host->buffer = dmam_alloc_coherent(dev, HIFMC_DMA_MAX_LEN,453			&host->dma_buffer, GFP_KERNEL);454	if (!host->buffer)455		return -ENOMEM;456 457	ret = clk_prepare_enable(host->clk);458	if (ret)459		return ret;460 461	mutex_init(&host->lock);462	hisi_spi_nor_init(host);463	ret = hisi_spi_nor_register_all(host);464	if (ret)465		mutex_destroy(&host->lock);466 467	clk_disable_unprepare(host->clk);468	return ret;469}470 471static void hisi_spi_nor_remove(struct platform_device *pdev)472{473	struct hifmc_host *host = platform_get_drvdata(pdev);474 475	hisi_spi_nor_unregister_all(host);476	mutex_destroy(&host->lock);477}478 479static const struct of_device_id hisi_spi_nor_dt_ids[] = {480	{ .compatible = "hisilicon,fmc-spi-nor"},481	{ /* sentinel */ }482};483MODULE_DEVICE_TABLE(of, hisi_spi_nor_dt_ids);484 485static struct platform_driver hisi_spi_nor_driver = {486	.driver = {487		.name	= "hisi-sfc",488		.of_match_table = hisi_spi_nor_dt_ids,489	},490	.probe	= hisi_spi_nor_probe,491	.remove_new = hisi_spi_nor_remove,492};493module_platform_driver(hisi_spi_nor_driver);494 495MODULE_LICENSE("GPL v2");496MODULE_DESCRIPTION("HiSilicon SPI Nor Flash Controller Driver");497