From f29c0702d2e7a67327b67766f91793d8ae6d0f73 Mon Sep 17 00:00:00 2001
From: Lionel Debieve <lionel.debieve@foss.st.com>
Date: Tue, 13 Apr 2021 13:38:02 +0200
Subject: [PATCH] feat(mtd): add platform function to allow using external
 buffer

The scratch buffer could be large. The new function allows
platform to defined its own external buffer or use the default
one.

Signed-off-by: Lionel Debieve <lionel.debieve@foss.st.com>
Change-Id: Ib7ab8ff19fa0a9cb06e364f058b91af58c3c471a
---
 drivers/mtd/nand/core.c | 27 ++++++++++++++++++++++-----
 include/drivers/nand.h  |  4 +++-
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c
index 9f0331ad7..6ef2256ab 100644
--- a/drivers/mtd/nand/core.c
+++ b/drivers/mtd/nand/core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,18 +8,29 @@
 #include <errno.h>
 #include <stddef.h>
 
-#include <platform_def.h>
-
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
 #include <drivers/nand.h>
 #include <lib/utils.h>
 
+#include <platform_def.h>
+
 /*
  * Define a single nand_device used by specific NAND frameworks.
  */
 static struct nand_device nand_dev;
-static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE];
+
+#pragma weak plat_get_scratch_buffer
+void plat_get_scratch_buffer(void **buffer_addr, size_t *buf_size)
+{
+	static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE];
+
+	assert(buffer_addr != NULL);
+	assert(buf_size != NULL);
+
+	*buffer_addr = (void *)scratch_buff;
+	*buf_size = sizeof(scratch_buff);
+}
 
 int nand_read(unsigned int offset, uintptr_t buffer, size_t length,
 	      size_t *length_read)
@@ -34,6 +45,12 @@ int nand_read(unsigned int offset, uintptr_t buffer, size_t length,
 	unsigned int bytes_read;
 	int is_bad;
 	int ret;
+	uint8_t *scratch_buff;
+	size_t scratch_buff_size;
+
+	plat_get_scratch_buffer((void **)&scratch_buff, &scratch_buff_size);
+
+	assert(scratch_buff != NULL);
 
 	VERBOSE("Block %u - %u, page_start %u, nb %u, length %zu, offset %u\n",
 		block, end_block, page_start, nb_pages, length, offset);
@@ -41,7 +58,7 @@ int nand_read(unsigned int offset, uintptr_t buffer, size_t length,
 	*length_read = 0UL;
 
 	if (((start_offset != 0U) || (length % nand_dev.page_size) != 0U) &&
-	    (sizeof(scratch_buff) < nand_dev.page_size)) {
+	    (scratch_buff_size < nand_dev.page_size)) {
 		return -EINVAL;
 	}
 
diff --git a/include/drivers/nand.h b/include/drivers/nand.h
index 1b78ad41b..5e5607c64 100644
--- a/include/drivers/nand.h
+++ b/include/drivers/nand.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,6 +33,8 @@ struct nand_device {
 			     uintptr_t buffer);
 };
 
+void plat_get_scratch_buffer(void **buffer_addr, size_t *buf_size);
+
 /*
  * Read bytes from NAND device
  *