2022-12-19 14:44:56

by Witold Sadowski

[permalink] [raw]
Subject: [PATCH 5/7] spi: cadence: Add read access size switch

Allow to use different SDMA read size.
In Marvell implementation of that IP each SDMA
access will read 8 bytes at once, and is not
configurable.

Signed-off-by: Witold Sadowski <[email protected]>
Reviewed-by: Chandrakala Chavva <[email protected]>
Tested-by: Sunil Kovvuri Goutham <[email protected]>
---
drivers/spi/spi-cadence-xspi.c | 99 ++++++++++++++++++++++++++++++++--
1 file changed, 95 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index 25db0d55d5ef..719c2f3b4771 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -209,6 +209,11 @@ enum cdns_xspi_stig_cmd_dir {
CDNS_XSPI_STIG_CMD_DIR_WRITE,
};

+enum cdns_xspi_sdma_size {
+ CDNS_XSPI_SDMA_SIZE_8B = 0,
+ CDNS_XSPI_SDMA_SIZE_64B = 1,
+};
+
struct cdns_xspi_dev {
struct platform_device *pdev;
struct device *dev;
@@ -230,6 +235,7 @@ struct cdns_xspi_dev {
const void *out_buffer;

u8 hw_num_banks;
+ enum cdns_xspi_sdma_size read_size;
};

static int cdns_xspi_wait_for_controller_idle(struct cdns_xspi_dev *cdns_xspi)
@@ -329,6 +335,82 @@ static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi)
return 0;
}

+static void cdns_ioreadq(void __iomem *addr, void *buf, int len)
+{
+ int i = 0;
+ int rcount = len / 8;
+ int rcount_nf = len % 8;
+ uint64_t tmp;
+ uint64_t *buf64 = (uint64_t *)buf;
+
+ if (((uint64_t)buf % 8) == 0) {
+ for (i = 0; i < rcount; i++)
+ *buf64++ = readq(addr);
+ } else {
+ for (i = 0; i < rcount; i++) {
+ tmp = readq(addr);
+ memcpy(buf+(i*8), &tmp, 8);
+ }
+ }
+
+ if (rcount_nf != 0) {
+ tmp = readq(addr);
+ memcpy(buf+(i*8), &tmp, rcount_nf);
+ }
+}
+
+static void cdns_iowriteq(void __iomem *addr, const void *buf, int len)
+{
+ int i = 0;
+ int rcount = len / 8;
+ int rcount_nf = len % 8;
+ uint64_t tmp;
+ uint64_t *buf64 = (uint64_t *)buf;
+
+ if (((uint64_t)buf % 8) == 0) {
+ for (i = 0; i < rcount; i++)
+ writeq(*buf64++, addr);
+ } else {
+ for (i = 0; i < rcount; i++) {
+ memcpy(&tmp, buf+(i*8), 8);
+ writeq(tmp, addr);
+ }
+ }
+
+ if (rcount_nf != 0) {
+ memcpy(&tmp, buf+(i*8), rcount_nf);
+ writeq(tmp, addr);
+ }
+}
+
+static void cdns_xspi_sdma_memread(struct cdns_xspi_dev *cdns_xspi,
+ enum cdns_xspi_sdma_size size, int len)
+{
+ switch (size) {
+ case CDNS_XSPI_SDMA_SIZE_8B:
+ ioread8_rep(cdns_xspi->sdmabase,
+ cdns_xspi->in_buffer, len);
+ break;
+ case CDNS_XSPI_SDMA_SIZE_64B:
+ cdns_ioreadq(cdns_xspi->sdmabase, cdns_xspi->in_buffer, len);
+ break;
+ }
+}
+
+static void cdns_xspi_sdma_memwrite(struct cdns_xspi_dev *cdns_xspi,
+ enum cdns_xspi_sdma_size size, int len)
+{
+ switch (size) {
+ case CDNS_XSPI_SDMA_SIZE_8B:
+ iowrite8_rep(cdns_xspi->sdmabase,
+ cdns_xspi->out_buffer, len);
+ break;
+ case CDNS_XSPI_SDMA_SIZE_64B:
+ cdns_iowriteq(cdns_xspi->sdmabase, cdns_xspi->out_buffer, len);
+ break;
+ }
+}
+
static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
{
u32 sdma_size, sdma_trd_info;
@@ -340,13 +422,15 @@ static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)

switch (sdma_dir) {
case CDNS_XSPI_SDMA_DIR_READ:
- ioread8_rep(cdns_xspi->sdmabase,
- cdns_xspi->in_buffer, sdma_size);
+ cdns_xspi_sdma_memread(cdns_xspi,
+ cdns_xspi->read_size,
+ sdma_size);
break;

case CDNS_XSPI_SDMA_DIR_WRITE:
- iowrite8_rep(cdns_xspi->sdmabase,
- cdns_xspi->out_buffer, sdma_size);
+ cdns_xspi_sdma_memwrite(cdns_xspi,
+ cdns_xspi->read_size,
+ sdma_size);
break;
}
}
@@ -526,7 +610,14 @@ static int cdns_xspi_of_get_plat_data(struct platform_device *pdev)
{
struct device_node *node_prop = pdev->dev.of_node;
struct device_node *node_child;
+ struct spi_master *master = platform_get_drvdata(pdev);
+ struct cdns_xspi_dev *cdns_xspi = spi_master_get_devdata(master);
unsigned int cs;
+ unsigned int read_size = 0;
+
+ if (of_property_read_u32(node_prop, "cdns,read-size", &read_size))
+ dev_info(&pdev->dev, "Missing read size property, usining byte access\n");
+ cdns_xspi->read_size = read_size;

for_each_child_of_node(node_prop, node_child) {
if (!of_device_is_available(node_child))
--
2.17.1


2022-12-19 18:33:41

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH 5/7] spi: cadence: Add read access size switch

On Mon, Dec 19, 2022 at 06:42:52AM -0800, Witold Sadowski wrote:
> Allow to use different SDMA read size.
> In Marvell implementation of that IP each SDMA
> access will read 8 bytes at once, and is not
> configurable.

If this isn't configurable then shouldn't we just key off the compatible
rather than having a separate property?


Attachments:
(No filename) (340.00 B)
signature.asc (499.00 B)
Download all attachments

2022-12-19 20:38:49

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 5/7] spi: cadence: Add read access size switch

Hi Witold,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on broonie-spi/for-next]
[also build test ERROR on linus/master v6.1 next-20221219]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Witold-Sadowski/Support-for-Marvell-modifications-for-Cadence-XSPI/20221219-224547
base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
patch link: https://lore.kernel.org/r/20221219144254.20883-6-wsadowski%40marvell.com
patch subject: [PATCH 5/7] spi: cadence: Add read access size switch
config: m68k-allmodconfig
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/552a25a831f809921128f7431e7aaf71aea2778c
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Witold-Sadowski/Support-for-Marvell-modifications-for-Cadence-XSPI/20221219-224547
git checkout 552a25a831f809921128f7431e7aaf71aea2778c
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash drivers/spi/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All error/warnings (new ones prefixed by >>):

drivers/spi/spi-cadence-xspi.c: In function 'cdns_ioreadq':
>> drivers/spi/spi-cadence-xspi.c:346:14: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
346 | if (((uint64_t)buf % 8) == 0) {
| ^
>> drivers/spi/spi-cadence-xspi.c:348:36: error: implicit declaration of function 'readq'; did you mean 'readb'? [-Werror=implicit-function-declaration]
348 | *buf64++ = readq(addr);
| ^~~~~
| readb
drivers/spi/spi-cadence-xspi.c: In function 'cdns_iowriteq':
drivers/spi/spi-cadence-xspi.c:370:14: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
370 | if (((uint64_t)buf % 8) == 0) {
| ^
>> drivers/spi/spi-cadence-xspi.c:372:25: error: implicit declaration of function 'writeq'; did you mean 'writel'? [-Werror=implicit-function-declaration]
372 | writeq(*buf64++, addr);
| ^~~~~~
| writel
drivers/spi/spi-cadence-xspi.c: At top level:
drivers/spi/spi-cadence-xspi.c:438:6: warning: no previous prototype for 'cdns_xspi_stig_ready' [-Wmissing-prototypes]
438 | bool cdns_xspi_stig_ready(struct cdns_xspi_dev *cdns_xspi)
| ^~~~~~~~~~~~~~~~~~~~
drivers/spi/spi-cadence-xspi.c:449:6: warning: no previous prototype for 'cdns_xspi_sdma_ready' [-Wmissing-prototypes]
449 | bool cdns_xspi_sdma_ready(struct cdns_xspi_dev *cdns_xspi)
| ^~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors


vim +348 drivers/spi/spi-cadence-xspi.c

337
338 static void cdns_ioreadq(void __iomem *addr, void *buf, int len)
339 {
340 int i = 0;
341 int rcount = len / 8;
342 int rcount_nf = len % 8;
343 uint64_t tmp;
344 uint64_t *buf64 = (uint64_t *)buf;
345
> 346 if (((uint64_t)buf % 8) == 0) {
347 for (i = 0; i < rcount; i++)
> 348 *buf64++ = readq(addr);
349 } else {
350 for (i = 0; i < rcount; i++) {
351 tmp = readq(addr);
352 memcpy(buf+(i*8), &tmp, 8);
353 }
354 }
355
356 if (rcount_nf != 0) {
357 tmp = readq(addr);
358 memcpy(buf+(i*8), &tmp, rcount_nf);
359 }
360 }
361
362 static void cdns_iowriteq(void __iomem *addr, const void *buf, int len)
363 {
364 int i = 0;
365 int rcount = len / 8;
366 int rcount_nf = len % 8;
367 uint64_t tmp;
368 uint64_t *buf64 = (uint64_t *)buf;
369
370 if (((uint64_t)buf % 8) == 0) {
371 for (i = 0; i < rcount; i++)
> 372 writeq(*buf64++, addr);
373 } else {
374 for (i = 0; i < rcount; i++) {
375 memcpy(&tmp, buf+(i*8), 8);
376 writeq(tmp, addr);
377 }
378 }
379
380 if (rcount_nf != 0) {
381 memcpy(&tmp, buf+(i*8), rcount_nf);
382 writeq(tmp, addr);
383 }
384 }
385

--
0-DAY CI Kernel Test Service
https://01.org/lkp


Attachments:
(No filename) (4.90 kB)
config (282.02 kB)
Download all attachments

2024-04-29 15:40:44

by Witold Sadowski

[permalink] [raw]
Subject: RE: [EXT] Re: [PATCH 5/7] spi: cadence: Add read access size switch

> ----------------------------------------------------------------------
> On Mon, Dec 19, 2022 at 06:42:52AM -0800, Witold Sadowski wrote:
> > Allow to use different SDMA read size.
> > In Marvell implementation of that IP each SDMA access will read 8
> > bytes at once, and is not configurable.
>
> If this isn't configurable then shouldn't we just key off the compatible
> rather than having a separate property?

Done, will be selected based on compatible property.

Regards
Witek