vc_screen-reload-load-of-struct-vc_data-pointer-in-v.patch
s390-qdio-get-rid-of-register-asm.patch
s390-qdio-fix-do_sqbs-inline-assembly-constraint.patch
+spi-spi-fsl-spi-automatically-adapt-bits-per-word-in-cpu-mode.patch
+spi-fsl-spi-re-organise-transfer-bits_per_word-adaptation.patch
+spi-fsl-cpm-use-16-bit-mode-for-large-transfers-with-even-size.patch
--- /dev/null
+From christophe.leroy@csgroup.eu Mon May 15 15:07:58 2023
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+Date: Mon, 15 May 2023 16:07:15 +0200
+Subject:[For 4.19/4.14] spi: fsl-cpm: Use 16 bit mode for large transfers with even size
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, Mark Brown <broonie@kernel.org>
+Message-ID: <9363da33f54e9862b4b59c0ed97924ca7265f7a4.1684158520.git.christophe.leroy@csgroup.eu>
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+(cherry picked from upstream fc96ec826bced75cc6b9c07a4ac44bbf651337ab)
+
+On CPM, the RISC core is a lot more efficiant when doing transfers
+in 16-bits chunks than in 8-bits chunks, but unfortunately the
+words need to be byte swapped as seen in a previous commit.
+
+So, for large tranfers with an even size, allocate a temporary tx
+buffer and byte-swap data before and after transfer.
+
+This change allows setting higher speed for transfer. For instance
+on an MPC 8xx (CPM1 comms RISC processor), the documentation tells
+that transfer in byte mode at 1 kbit/s uses 0.200% of CPM load
+at 25 MHz while a word transfer at the same speed uses 0.032%
+of CPM load. This means the speed can be 6 times higher in
+word mode for the same CPM load.
+
+For the time being, only do it on CPM1 as there must be a
+trade-off between the CPM load reduction and the CPU load required
+to byte swap the data.
+
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Link: https://lore.kernel.org/r/f2e981f20f92dd28983c3949702a09248c23845c.1680371809.git.christophe.leroy@csgroup.eu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-fsl-cpm.c | 23 +++++++++++++++++++++++
+ drivers/spi/spi-fsl-spi.c | 3 +++
+ 2 files changed, 26 insertions(+)
+
+--- a/drivers/spi/spi-fsl-cpm.c
++++ b/drivers/spi/spi-fsl-cpm.c
+@@ -25,6 +25,7 @@
+ #include <linux/spi/spi.h>
+ #include <linux/types.h>
+ #include <linux/platform_device.h>
++#include <linux/byteorder/generic.h>
+
+ #include "spi-fsl-cpm.h"
+ #include "spi-fsl-lib.h"
+@@ -124,6 +125,21 @@ int fsl_spi_cpm_bufs(struct mpc8xxx_spi
+ mspi->rx_dma = mspi->dma_dummy_rx;
+ mspi->map_rx_dma = 0;
+ }
++ if (t->bits_per_word == 16 && t->tx_buf) {
++ const u16 *src = t->tx_buf;
++ u16 *dst;
++ int i;
++
++ dst = kmalloc(t->len, GFP_KERNEL);
++ if (!dst)
++ return -ENOMEM;
++
++ for (i = 0; i < t->len >> 1; i++)
++ dst[i] = cpu_to_le16p(src + i);
++
++ mspi->tx = dst;
++ mspi->map_tx_dma = 1;
++ }
+
+ if (mspi->map_tx_dma) {
+ void *nonconst_tx = (void *)mspi->tx; /* shut up gcc */
+@@ -177,6 +193,13 @@ void fsl_spi_cpm_bufs_complete(struct mp
+ if (mspi->map_rx_dma)
+ dma_unmap_single(dev, mspi->rx_dma, t->len, DMA_FROM_DEVICE);
+ mspi->xfer_in_progress = NULL;
++
++ if (t->bits_per_word == 16 && t->rx_buf) {
++ int i;
++
++ for (i = 0; i < t->len; i += 2)
++ le16_to_cpus(t->rx_buf + i);
++ }
+ }
+ EXPORT_SYMBOL_GPL(fsl_spi_cpm_bufs_complete);
+
+--- a/drivers/spi/spi-fsl-spi.c
++++ b/drivers/spi/spi-fsl-spi.c
+@@ -366,6 +366,9 @@ static int fsl_spi_do_one_msg(struct spi
+ return -EINVAL;
+ if (t->bits_per_word == 16 || t->bits_per_word == 32)
+ t->bits_per_word = 8; /* pretend its 8 bits */
++ if (t->bits_per_word == 8 && t->len >= 256 &&
++ (mpc8xxx_spi->flags & SPI_CPM1))
++ t->bits_per_word = 16;
+ }
+ }
+
--- /dev/null
+From christophe.leroy@csgroup.eu Mon May 15 15:08:01 2023
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+Date: Mon, 15 May 2023 16:07:14 +0200
+Subject:[For 4.19/4.14] spi: fsl-spi: Re-organise transfer bits_per_word adaptation
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, Mark Brown <broonie@kernel.org>
+Message-ID: <e105f49ce5da21b48dc0450f5fb3644571ee9c1a.1684158520.git.christophe.leroy@csgroup.eu>
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+(backported from upstream 8a5299a1278eadf1e08a598a5345c376206f171e)
+
+For different reasons, fsl-spi driver performs bits_per_word
+modifications for different reasons:
+- On CPU mode, to minimise amount of interrupts
+- On CPM/QE mode to work around controller byte order
+
+For CPU mode that's done in fsl_spi_prepare_message() while
+for CPM mode that's done in fsl_spi_setup_transfer().
+
+Reunify all of it in fsl_spi_prepare_message(), and catch
+impossible cases early through master's bits_per_word_mask
+instead of returning EINVAL later.
+
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Link: https://lore.kernel.org/r/0ce96fe96e8b07cba0613e4097cfd94d09b8919a.1680371809.git.christophe.leroy@csgroup.eu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-fsl-spi.c | 50 +++++++++++++++++++++-------------------------
+ 1 file changed, 23 insertions(+), 27 deletions(-)
+
+--- a/drivers/spi/spi-fsl-spi.c
++++ b/drivers/spi/spi-fsl-spi.c
+@@ -201,26 +201,6 @@ static int mspi_apply_cpu_mode_quirks(st
+ return bits_per_word;
+ }
+
+-static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs,
+- struct spi_device *spi,
+- int bits_per_word)
+-{
+- /* CPM/QE uses Little Endian for words > 8
+- * so transform 16 and 32 bits words into 8 bits
+- * Unfortnatly that doesn't work for LSB so
+- * reject these for now */
+- /* Note: 32 bits word, LSB works iff
+- * tfcr/rfcr is set to CPMFCR_GBL */
+- if (spi->mode & SPI_LSB_FIRST &&
+- bits_per_word > 8)
+- return -EINVAL;
+- if (bits_per_word <= 8)
+- return bits_per_word;
+- if (bits_per_word == 16 || bits_per_word == 32)
+- return 8; /* pretend its 8 bits */
+- return -EINVAL;
+-}
+-
+ static int fsl_spi_setup_transfer(struct spi_device *spi,
+ struct spi_transfer *t)
+ {
+@@ -248,9 +228,6 @@ static int fsl_spi_setup_transfer(struct
+ bits_per_word = mspi_apply_cpu_mode_quirks(cs, spi,
+ mpc8xxx_spi,
+ bits_per_word);
+- else
+- bits_per_word = mspi_apply_qe_mode_quirks(cs, spi,
+- bits_per_word);
+
+ if (bits_per_word < 0)
+ return bits_per_word;
+@@ -368,14 +345,27 @@ static int fsl_spi_do_one_msg(struct spi
+ * In CPU mode, optimize large byte transfers to use larger
+ * bits_per_word values to reduce number of interrupts taken.
+ */
+- if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) {
+- list_for_each_entry(t, &m->transfers, transfer_list) {
++ list_for_each_entry(t, &m->transfers, transfer_list) {
++ if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) {
+ if (t->len < 256 || t->bits_per_word != 8)
+ continue;
+ if ((t->len & 3) == 0)
+ t->bits_per_word = 32;
+ else if ((t->len & 1) == 0)
+ t->bits_per_word = 16;
++ } else {
++ /*
++ * CPM/QE uses Little Endian for words > 8
++ * so transform 16 and 32 bits words into 8 bits
++ * Unfortnatly that doesn't work for LSB so
++ * reject these for now
++ * Note: 32 bits word, LSB works iff
++ * tfcr/rfcr is set to CPMFCR_GBL
++ */
++ if (m->spi->mode & SPI_LSB_FIRST && t->bits_per_word > 8)
++ return -EINVAL;
++ if (t->bits_per_word == 16 || t->bits_per_word == 32)
++ t->bits_per_word = 8; /* pretend its 8 bits */
+ }
+ }
+
+@@ -658,8 +648,14 @@ static struct spi_master * fsl_spi_probe
+ if (mpc8xxx_spi->type == TYPE_GRLIB)
+ fsl_spi_grlib_probe(dev);
+
+- master->bits_per_word_mask =
+- (SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32)) &
++ if (mpc8xxx_spi->flags & SPI_CPM_MODE)
++ master->bits_per_word_mask =
++ (SPI_BPW_RANGE_MASK(4, 8) | SPI_BPW_MASK(16) | SPI_BPW_MASK(32));
++ else
++ master->bits_per_word_mask =
++ (SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32));
++
++ master->bits_per_word_mask &=
+ SPI_BPW_RANGE_MASK(1, mpc8xxx_spi->max_bits_per_word);
+
+ if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE)
--- /dev/null
+From christophe.leroy@csgroup.eu Mon May 15 15:08:06 2023
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+Date: Mon, 15 May 2023 16:07:13 +0200
+Subject:[For 4.19/4.14] spi: spi-fsl-spi: automatically adapt bits-per-word in cpu mode
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, Rasmus Villemoes <rasmus.villemoes@prevas.dk>, Mark Brown <broonie@kernel.org>
+Message-ID: <674d9af640acf4aa04abd642cc81de926d3271ed.1684158520.git.christophe.leroy@csgroup.eu>
+
+From: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
+
+(cherry picked from upstream af0e6242909c3c4297392ca3e94eff1b4db71a97)
+
+Taking one interrupt for every byte is rather slow. Since the
+controller is perfectly capable of transmitting 32 bits at a time,
+change t->bits_per-word to 32 when the length is divisible by 4 and
+large enough that the reduced number of interrupts easily compensates
+for the one or two extra fsl_spi_setup_transfer() calls this causes.
+
+Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-fsl-spi.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/spi/spi-fsl-spi.c
++++ b/drivers/spi/spi-fsl-spi.c
+@@ -357,12 +357,28 @@ static int fsl_spi_bufs(struct spi_devic
+ static int fsl_spi_do_one_msg(struct spi_master *master,
+ struct spi_message *m)
+ {
++ struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
+ struct spi_device *spi = m->spi;
+ struct spi_transfer *t, *first;
+ unsigned int cs_change;
+ const int nsecs = 50;
+ int status;
+
++ /*
++ * In CPU mode, optimize large byte transfers to use larger
++ * bits_per_word values to reduce number of interrupts taken.
++ */
++ if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) {
++ list_for_each_entry(t, &m->transfers, transfer_list) {
++ if (t->len < 256 || t->bits_per_word != 8)
++ continue;
++ if ((t->len & 3) == 0)
++ t->bits_per_word = 32;
++ else if ((t->len & 1) == 0)
++ t->bits_per_word = 16;
++ }
++ }
++
+ /* Don't allow changes if CS is active */
+ first = list_first_entry(&m->transfers, struct spi_transfer,
+ transfer_list);