brintos

brintos / linux-shallow public Read only

0
0
Text · 13.5 KiB · fc9e33b Raw
594 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2// Copyright (C) IBM Corporation 20203 4#include <linux/bitfield.h>5#include <linux/bits.h>6#include <linux/fsi.h>7#include <linux/jiffies.h>8#include <linux/kernel.h>9#include <linux/module.h>10#include <linux/of.h>11#include <linux/spi/spi.h>12 13#define FSI_ENGID_SPI			0x2314#define FSI_MBOX_ROOT_CTRL_8		0x286015#define  FSI_MBOX_ROOT_CTRL_8_SPI_MUX	 0xf000000016 17#define FSI2SPI_DATA0			0x0018#define FSI2SPI_DATA1			0x0419#define FSI2SPI_CMD			0x0820#define  FSI2SPI_CMD_WRITE		 BIT(31)21#define FSI2SPI_RESET			0x1822#define FSI2SPI_STATUS			0x1c23#define  FSI2SPI_STATUS_ANY_ERROR	 BIT(31)24#define FSI2SPI_IRQ			0x2025 26#define SPI_FSI_BASE			0x7000027#define SPI_FSI_TIMEOUT_MS		100028#define SPI_FSI_MAX_RX_SIZE		829#define SPI_FSI_MAX_TX_SIZE		4030 31#define SPI_FSI_ERROR			0x032#define SPI_FSI_COUNTER_CFG		0x133#define SPI_FSI_CFG1			0x234#define SPI_FSI_CLOCK_CFG		0x335#define  SPI_FSI_CLOCK_CFG_MM_ENABLE	 BIT_ULL(32)36#define  SPI_FSI_CLOCK_CFG_ECC_DISABLE	 (BIT_ULL(35) | BIT_ULL(33))37#define  SPI_FSI_CLOCK_CFG_RESET1	 (BIT_ULL(36) | BIT_ULL(38))38#define  SPI_FSI_CLOCK_CFG_RESET2	 (BIT_ULL(37) | BIT_ULL(39))39#define  SPI_FSI_CLOCK_CFG_MODE		 (BIT_ULL(41) | BIT_ULL(42))40#define  SPI_FSI_CLOCK_CFG_SCK_RECV_DEL	 GENMASK_ULL(51, 44)41#define   SPI_FSI_CLOCK_CFG_SCK_NO_DEL	  BIT_ULL(51)42#define  SPI_FSI_CLOCK_CFG_SCK_DIV	 GENMASK_ULL(63, 52)43#define SPI_FSI_MMAP			0x444#define SPI_FSI_DATA_TX			0x545#define SPI_FSI_DATA_RX			0x646#define SPI_FSI_SEQUENCE		0x747#define  SPI_FSI_SEQUENCE_STOP		 0x0048#define  SPI_FSI_SEQUENCE_SEL_SLAVE(x)	 (0x10 | ((x) & 0xf))49#define  SPI_FSI_SEQUENCE_SHIFT_OUT(x)	 (0x30 | ((x) & 0xf))50#define  SPI_FSI_SEQUENCE_SHIFT_IN(x)	 (0x40 | ((x) & 0xf))51#define  SPI_FSI_SEQUENCE_COPY_DATA_TX	 0xc052#define  SPI_FSI_SEQUENCE_BRANCH(x)	 (0xe0 | ((x) & 0xf))53#define SPI_FSI_STATUS			0x854#define  SPI_FSI_STATUS_ERROR		 \55	(GENMASK_ULL(31, 21) | GENMASK_ULL(15, 12))56#define  SPI_FSI_STATUS_SEQ_STATE	 GENMASK_ULL(55, 48)57#define   SPI_FSI_STATUS_SEQ_STATE_IDLE	  BIT_ULL(48)58#define  SPI_FSI_STATUS_TDR_UNDERRUN	 BIT_ULL(57)59#define  SPI_FSI_STATUS_TDR_OVERRUN	 BIT_ULL(58)60#define  SPI_FSI_STATUS_TDR_FULL	 BIT_ULL(59)61#define  SPI_FSI_STATUS_RDR_UNDERRUN	 BIT_ULL(61)62#define  SPI_FSI_STATUS_RDR_OVERRUN	 BIT_ULL(62)63#define  SPI_FSI_STATUS_RDR_FULL	 BIT_ULL(63)64#define  SPI_FSI_STATUS_ANY_ERROR	 \65	(SPI_FSI_STATUS_ERROR | \66	 SPI_FSI_STATUS_TDR_OVERRUN | SPI_FSI_STATUS_RDR_UNDERRUN | \67	 SPI_FSI_STATUS_RDR_OVERRUN)68#define SPI_FSI_PORT_CTRL		0x969 70struct fsi2spi {71	struct fsi_device *fsi; /* FSI2SPI CFAM engine device */72	struct mutex lock; /* lock access to the device */73};74 75struct fsi_spi {76	struct device *dev;	/* SPI controller device */77	struct fsi2spi *bridge; /* FSI2SPI device */78	u32 base;79};80 81struct fsi_spi_sequence {82	int bit;83	u64 data;84};85 86static int fsi_spi_check_mux(struct fsi_device *fsi, struct device *dev)87{88	int rc;89	u32 root_ctrl_8;90	__be32 root_ctrl_8_be;91 92	rc = fsi_slave_read(fsi->slave, FSI_MBOX_ROOT_CTRL_8, &root_ctrl_8_be,93			    sizeof(root_ctrl_8_be));94	if (rc)95		return rc;96 97	root_ctrl_8 = be32_to_cpu(root_ctrl_8_be);98	dev_dbg(dev, "Root control register 8: %08x\n", root_ctrl_8);99	if ((root_ctrl_8 & FSI_MBOX_ROOT_CTRL_8_SPI_MUX) ==100	     FSI_MBOX_ROOT_CTRL_8_SPI_MUX)101		return 0;102 103	return -ENOLINK;104}105 106static int fsi_spi_check_status(struct fsi_spi *ctx)107{108	int rc;109	u32 sts;110	__be32 sts_be;111 112	rc = fsi_device_read(ctx->bridge->fsi, FSI2SPI_STATUS, &sts_be,113			     sizeof(sts_be));114	if (rc)115		return rc;116 117	sts = be32_to_cpu(sts_be);118	if (sts & FSI2SPI_STATUS_ANY_ERROR) {119		dev_err(ctx->dev, "Error with FSI2SPI interface: %08x.\n", sts);120		return -EIO;121	}122 123	return 0;124}125 126static int fsi_spi_read_reg(struct fsi_spi *ctx, u32 offset, u64 *value)127{128	int rc = 0;129	__be32 cmd_be;130	__be32 data_be;131	u32 cmd = offset + ctx->base;132	struct fsi2spi *bridge = ctx->bridge;133 134	*value = 0ULL;135 136	if (cmd & FSI2SPI_CMD_WRITE)137		return -EINVAL;138 139	rc = mutex_lock_interruptible(&bridge->lock);140	if (rc)141		return rc;142 143	cmd_be = cpu_to_be32(cmd);144	rc = fsi_device_write(bridge->fsi, FSI2SPI_CMD, &cmd_be,145			      sizeof(cmd_be));146	if (rc)147		goto unlock;148 149	rc = fsi_spi_check_status(ctx);150	if (rc)151		goto unlock;152 153	rc = fsi_device_read(bridge->fsi, FSI2SPI_DATA0, &data_be,154			     sizeof(data_be));155	if (rc)156		goto unlock;157 158	*value |= (u64)be32_to_cpu(data_be) << 32;159 160	rc = fsi_device_read(bridge->fsi, FSI2SPI_DATA1, &data_be,161			     sizeof(data_be));162	if (rc)163		goto unlock;164 165	*value |= (u64)be32_to_cpu(data_be);166	dev_dbg(ctx->dev, "Read %02x[%016llx].\n", offset, *value);167 168unlock:169	mutex_unlock(&bridge->lock);170	return rc;171}172 173static int fsi_spi_write_reg(struct fsi_spi *ctx, u32 offset, u64 value)174{175	int rc = 0;176	__be32 cmd_be;177	__be32 data_be;178	u32 cmd = offset + ctx->base;179	struct fsi2spi *bridge = ctx->bridge;180 181	if (cmd & FSI2SPI_CMD_WRITE)182		return -EINVAL;183 184	rc = mutex_lock_interruptible(&bridge->lock);185	if (rc)186		return rc;187 188	dev_dbg(ctx->dev, "Write %02x[%016llx].\n", offset, value);189 190	data_be = cpu_to_be32(upper_32_bits(value));191	rc = fsi_device_write(bridge->fsi, FSI2SPI_DATA0, &data_be,192			      sizeof(data_be));193	if (rc)194		goto unlock;195 196	data_be = cpu_to_be32(lower_32_bits(value));197	rc = fsi_device_write(bridge->fsi, FSI2SPI_DATA1, &data_be,198			      sizeof(data_be));199	if (rc)200		goto unlock;201 202	cmd_be = cpu_to_be32(cmd | FSI2SPI_CMD_WRITE);203	rc = fsi_device_write(bridge->fsi, FSI2SPI_CMD, &cmd_be,204			      sizeof(cmd_be));205	if (rc)206		goto unlock;207 208	rc = fsi_spi_check_status(ctx);209 210unlock:211	mutex_unlock(&bridge->lock);212	return rc;213}214 215static int fsi_spi_data_in(u64 in, u8 *rx, int len)216{217	int i;218	int num_bytes = min(len, 8);219 220	for (i = 0; i < num_bytes; ++i)221		rx[i] = (u8)(in >> (8 * ((num_bytes - 1) - i)));222 223	return num_bytes;224}225 226static int fsi_spi_data_out(u64 *out, const u8 *tx, int len)227{228	int i;229	int num_bytes = min(len, 8);230	u8 *out_bytes = (u8 *)out;231 232	/* Unused bytes of the tx data should be 0. */233	*out = 0ULL;234 235	for (i = 0; i < num_bytes; ++i)236		out_bytes[8 - (i + 1)] = tx[i];237 238	return num_bytes;239}240 241static int fsi_spi_reset(struct fsi_spi *ctx)242{243	int rc;244 245	dev_dbg(ctx->dev, "Resetting SPI controller.\n");246 247	rc = fsi_spi_write_reg(ctx, SPI_FSI_CLOCK_CFG,248			       SPI_FSI_CLOCK_CFG_RESET1);249	if (rc)250		return rc;251 252	rc = fsi_spi_write_reg(ctx, SPI_FSI_CLOCK_CFG,253			       SPI_FSI_CLOCK_CFG_RESET2);254	if (rc)255		return rc;256 257	return fsi_spi_write_reg(ctx, SPI_FSI_STATUS, 0ULL);258}259 260static int fsi_spi_status(struct fsi_spi *ctx, u64 *status, const char *dir)261{262	int rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS, status);263 264	if (rc)265		return rc;266 267	if (*status & SPI_FSI_STATUS_ANY_ERROR) {268		dev_err(ctx->dev, "%s error: %016llx\n", dir, *status);269 270		rc = fsi_spi_reset(ctx);271		if (rc)272			return rc;273 274		return -EREMOTEIO;275	}276 277	return 0;278}279 280static void fsi_spi_sequence_add(struct fsi_spi_sequence *seq, u8 val)281{282	/*283	 * Add the next byte of instruction to the 8-byte sequence register.284	 * Then decrement the counter so that the next instruction will go in285	 * the right place. Return the index of the slot we just filled in the286	 * sequence register.287	 */288	seq->data |= (u64)val << seq->bit;289	seq->bit -= 8;290}291 292static void fsi_spi_sequence_init(struct fsi_spi_sequence *seq)293{294	seq->bit = 56;295	seq->data = 0ULL;296}297 298static int fsi_spi_transfer_data(struct fsi_spi *ctx,299				 struct spi_transfer *transfer)300{301	int loops;302	int rc = 0;303	unsigned long end;304	u64 status = 0ULL;305 306	if (transfer->tx_buf) {307		int nb;308		int sent = 0;309		u64 out = 0ULL;310		const u8 *tx = transfer->tx_buf;311 312		while (transfer->len > sent) {313			nb = fsi_spi_data_out(&out, &tx[sent],314					      (int)transfer->len - sent);315 316			rc = fsi_spi_write_reg(ctx, SPI_FSI_DATA_TX, out);317			if (rc)318				return rc;319 320			loops = 0;321			end = jiffies + msecs_to_jiffies(SPI_FSI_TIMEOUT_MS);322			do {323				if (loops++ && time_after(jiffies, end))324					return -ETIMEDOUT;325 326				rc = fsi_spi_status(ctx, &status, "TX");327				if (rc)328					return rc;329			} while (status & SPI_FSI_STATUS_TDR_FULL);330 331			sent += nb;332		}333	} else if (transfer->rx_buf) {334		int recv = 0;335		u64 in = 0ULL;336		u8 *rx = transfer->rx_buf;337 338		while (transfer->len > recv) {339			loops = 0;340			end = jiffies + msecs_to_jiffies(SPI_FSI_TIMEOUT_MS);341			do {342				if (loops++ && time_after(jiffies, end))343					return -ETIMEDOUT;344 345				rc = fsi_spi_status(ctx, &status, "RX");346				if (rc)347					return rc;348			} while (!(status & SPI_FSI_STATUS_RDR_FULL));349 350			rc = fsi_spi_read_reg(ctx, SPI_FSI_DATA_RX, &in);351			if (rc)352				return rc;353 354			recv += fsi_spi_data_in(in, &rx[recv],355						(int)transfer->len - recv);356		}357	}358 359	return 0;360}361 362static int fsi_spi_transfer_init(struct fsi_spi *ctx)363{364	int loops = 0;365	int rc;366	bool reset = false;367	unsigned long end;368	u64 seq_state;369	u64 clock_cfg = 0ULL;370	u64 status = 0ULL;371	u64 wanted_clock_cfg = SPI_FSI_CLOCK_CFG_ECC_DISABLE |372		SPI_FSI_CLOCK_CFG_SCK_NO_DEL |373		FIELD_PREP(SPI_FSI_CLOCK_CFG_SCK_DIV, 19);374 375	end = jiffies + msecs_to_jiffies(SPI_FSI_TIMEOUT_MS);376	do {377		if (loops++ && time_after(jiffies, end))378			return -ETIMEDOUT;379 380		rc = fsi_spi_read_reg(ctx, SPI_FSI_STATUS, &status);381		if (rc)382			return rc;383 384		seq_state = status & SPI_FSI_STATUS_SEQ_STATE;385 386		if (status & (SPI_FSI_STATUS_ANY_ERROR |387			      SPI_FSI_STATUS_TDR_FULL |388			      SPI_FSI_STATUS_RDR_FULL)) {389			if (reset) {390				dev_err(ctx->dev,391					"Initialization error: %08llx\n",392					status);393				return -EIO;394			}395 396			rc = fsi_spi_reset(ctx);397			if (rc)398				return rc;399 400			reset = true;401			continue;402		}403	} while (seq_state && (seq_state != SPI_FSI_STATUS_SEQ_STATE_IDLE));404 405	rc = fsi_spi_write_reg(ctx, SPI_FSI_COUNTER_CFG, 0ULL);406	if (rc)407		return rc;408 409	rc = fsi_spi_read_reg(ctx, SPI_FSI_CLOCK_CFG, &clock_cfg);410	if (rc)411		return rc;412 413	if ((clock_cfg & (SPI_FSI_CLOCK_CFG_MM_ENABLE |414			  SPI_FSI_CLOCK_CFG_ECC_DISABLE |415			  SPI_FSI_CLOCK_CFG_MODE |416			  SPI_FSI_CLOCK_CFG_SCK_RECV_DEL |417			  SPI_FSI_CLOCK_CFG_SCK_DIV)) != wanted_clock_cfg)418		rc = fsi_spi_write_reg(ctx, SPI_FSI_CLOCK_CFG,419				       wanted_clock_cfg);420 421	return rc;422}423 424static int fsi_spi_transfer_one_message(struct spi_controller *ctlr,425					struct spi_message *mesg)426{427	int rc;428	u8 seq_slave = SPI_FSI_SEQUENCE_SEL_SLAVE(spi_get_chipselect(mesg->spi, 0) + 1);429	unsigned int len;430	struct spi_transfer *transfer;431	struct fsi_spi *ctx = spi_controller_get_devdata(ctlr);432 433	rc = fsi_spi_check_mux(ctx->bridge->fsi, ctx->dev);434	if (rc)435		goto error;436 437	list_for_each_entry(transfer, &mesg->transfers, transfer_list) {438		struct fsi_spi_sequence seq;439		struct spi_transfer *next = NULL;440 441		/* Sequencer must do shift out (tx) first. */442		if (!transfer->tx_buf || transfer->len > SPI_FSI_MAX_TX_SIZE) {443			rc = -EINVAL;444			goto error;445		}446 447		dev_dbg(ctx->dev, "Start tx of %d bytes.\n", transfer->len);448 449		rc = fsi_spi_transfer_init(ctx);450		if (rc < 0)451			goto error;452 453		fsi_spi_sequence_init(&seq);454		fsi_spi_sequence_add(&seq, seq_slave);455 456		len = transfer->len;457		while (len > 8) {458			fsi_spi_sequence_add(&seq,459					     SPI_FSI_SEQUENCE_SHIFT_OUT(8));460			len -= 8;461		}462		fsi_spi_sequence_add(&seq, SPI_FSI_SEQUENCE_SHIFT_OUT(len));463 464		if (!list_is_last(&transfer->transfer_list,465				  &mesg->transfers)) {466			next = list_next_entry(transfer, transfer_list);467 468			/* Sequencer can only do shift in (rx) after tx. */469			if (next->rx_buf) {470				u8 shift;471 472				if (next->len > SPI_FSI_MAX_RX_SIZE) {473					rc = -EINVAL;474					goto error;475				}476 477				dev_dbg(ctx->dev, "Sequence rx of %d bytes.\n",478					next->len);479 480				shift = SPI_FSI_SEQUENCE_SHIFT_IN(next->len);481				fsi_spi_sequence_add(&seq, shift);482			} else {483				next = NULL;484			}485		}486 487		fsi_spi_sequence_add(&seq, SPI_FSI_SEQUENCE_SEL_SLAVE(0));488 489		rc = fsi_spi_write_reg(ctx, SPI_FSI_SEQUENCE, seq.data);490		if (rc)491			goto error;492 493		rc = fsi_spi_transfer_data(ctx, transfer);494		if (rc)495			goto error;496 497		if (next) {498			rc = fsi_spi_transfer_data(ctx, next);499			if (rc)500				goto error;501 502			transfer = next;503		}504	}505 506error:507	mesg->status = rc;508	spi_finalize_current_message(ctlr);509 510	return rc;511}512 513static size_t fsi_spi_max_transfer_size(struct spi_device *spi)514{515	return SPI_FSI_MAX_RX_SIZE;516}517 518static int fsi_spi_probe(struct device *dev)519{520	int rc;521	struct device_node *np;522	int num_controllers_registered = 0;523	struct fsi2spi *bridge;524	struct fsi_device *fsi = to_fsi_dev(dev);525 526	rc = fsi_spi_check_mux(fsi, dev);527	if (rc)528		return -ENODEV;529 530	bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);531	if (!bridge)532		return -ENOMEM;533 534	bridge->fsi = fsi;535	mutex_init(&bridge->lock);536 537	for_each_available_child_of_node(dev->of_node, np) {538		u32 base;539		struct fsi_spi *ctx;540		struct spi_controller *ctlr;541 542		if (of_property_read_u32(np, "reg", &base))543			continue;544 545		ctlr = spi_alloc_host(dev, sizeof(*ctx));546		if (!ctlr) {547			of_node_put(np);548			break;549		}550 551		ctlr->dev.of_node = np;552		ctlr->num_chipselect = of_get_available_child_count(np) ?: 1;553		ctlr->flags = SPI_CONTROLLER_HALF_DUPLEX;554		ctlr->max_transfer_size = fsi_spi_max_transfer_size;555		ctlr->transfer_one_message = fsi_spi_transfer_one_message;556 557		ctx = spi_controller_get_devdata(ctlr);558		ctx->dev = &ctlr->dev;559		ctx->bridge = bridge;560		ctx->base = base + SPI_FSI_BASE;561 562		rc = devm_spi_register_controller(dev, ctlr);563		if (rc)564			spi_controller_put(ctlr);565		else566			num_controllers_registered++;567	}568 569	if (!num_controllers_registered)570		return -ENODEV;571 572	return 0;573}574 575static const struct fsi_device_id fsi_spi_ids[] = {576	{ FSI_ENGID_SPI, FSI_VERSION_ANY },577	{ }578};579MODULE_DEVICE_TABLE(fsi, fsi_spi_ids);580 581static struct fsi_driver fsi_spi_driver = {582	.id_table = fsi_spi_ids,583	.drv = {584		.name = "spi-fsi",585		.bus = &fsi_bus_type,586		.probe = fsi_spi_probe,587	},588};589module_fsi_driver(fsi_spi_driver);590 591MODULE_AUTHOR("Eddie James <eajames@linux.ibm.com>");592MODULE_DESCRIPTION("FSI attached SPI controller");593MODULE_LICENSE("GPL");594