Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: spi-zynqmp-gqspi: Add two chip select support

ZynqMP GQSPI controller can support up to two chip selects but the current
GQSPI driver only support CS0. With this update and num-cs DT property set
to 2 GQSPI driver can now support two slave devices each connected to one
chip select.

GQSPI driver configures the Lower CS and Upper CS based on the reg DT
property.

Changes tested on ZynqMP board with two SPI-NOR flashes each connected
to a different CS.

Signed-off-by: Amit Kumar Mahapatra <amit.kumar-mahapatra@xilinx.com>
Link: https://lore.kernel.org/r/20220512145820.20425-1-amit.kumar-mahapatra@xilinx.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Amit Kumar Mahapatra and committed by
Mark Brown
dd9c232d 657f8bd8

+22 -3
+22 -3
drivers/spi/spi-zynqmp-gqspi.c
··· 134 134 #define GQSPI_DMA_UNALIGN 0x3 135 135 #define GQSPI_DEFAULT_NUM_CS 1 /* Default number of chip selects */ 136 136 137 + #define GQSPI_MAX_NUM_CS 2 /* Maximum number of chip selects */ 138 + 137 139 #define SPI_AUTOSUSPEND_TIMEOUT 3000 138 140 enum mode_type {GQSPI_MODE_IO, GQSPI_MODE_DMA}; 139 141 ··· 365 363 genfifoentry |= GQSPI_GENFIFO_MODE_SPI; 366 364 367 365 if (!is_high) { 368 - xqspi->genfifobus = GQSPI_GENFIFO_BUS_LOWER; 369 - xqspi->genfifocs = GQSPI_GENFIFO_CS_LOWER; 366 + if (!qspi->chip_select) { 367 + xqspi->genfifobus = GQSPI_GENFIFO_BUS_LOWER; 368 + xqspi->genfifocs = GQSPI_GENFIFO_CS_LOWER; 369 + } else { 370 + xqspi->genfifobus = GQSPI_GENFIFO_BUS_UPPER; 371 + xqspi->genfifocs = GQSPI_GENFIFO_CS_UPPER; 372 + } 370 373 genfifoentry |= xqspi->genfifobus; 371 374 genfifoentry |= xqspi->genfifocs; 372 375 genfifoentry |= GQSPI_GENFIFO_CS_SETUP; ··· 1106 1099 struct zynqmp_qspi *xqspi; 1107 1100 struct device *dev = &pdev->dev; 1108 1101 struct device_node *np = dev->of_node; 1102 + u32 num_cs; 1109 1103 1110 1104 ctlr = spi_alloc_master(&pdev->dev, sizeof(*xqspi)); 1111 1105 if (!ctlr) ··· 1184 1176 if (ret) 1185 1177 goto clk_dis_all; 1186 1178 1179 + ret = of_property_read_u32(np, "num-cs", &num_cs); 1180 + if (ret < 0) { 1181 + ctlr->num_chipselect = GQSPI_DEFAULT_NUM_CS; 1182 + } else if (num_cs > GQSPI_MAX_NUM_CS) { 1183 + ret = -EINVAL; 1184 + dev_err(&pdev->dev, "only %d chip selects are available\n", 1185 + GQSPI_MAX_NUM_CS); 1186 + goto clk_dis_all; 1187 + } else { 1188 + ctlr->num_chipselect = num_cs; 1189 + } 1190 + 1187 1191 ctlr->bits_per_word_mask = SPI_BPW_MASK(8); 1188 - ctlr->num_chipselect = GQSPI_DEFAULT_NUM_CS; 1189 1192 ctlr->mem_ops = &zynqmp_qspi_mem_ops; 1190 1193 ctlr->setup = zynqmp_qspi_setup_op; 1191 1194 ctlr->max_speed_hz = clk_get_rate(xqspi->refclk) / 2;