2
0

100-03-mtd-mtk-snand-add-support-for-SPL.patch 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. From a347e374cb338213632c6dde88dd226d64bd8b27 Mon Sep 17 00:00:00 2001
  2. From: Weijie Gao <[email protected]>
  3. Date: Wed, 3 Mar 2021 08:57:29 +0800
  4. Subject: [PATCH 37/71] mtd: mtk-snand: add support for SPL
  5. Add support to initialize SPI-NAND in SPL.
  6. Add implementation for SPL NAND loader.
  7. Signed-off-by: Weijie Gao <[email protected]>
  8. ---
  9. drivers/mtd/mtk-snand/Kconfig | 6 ++
  10. drivers/mtd/mtk-snand/Makefile | 4 +
  11. drivers/mtd/mtk-snand/mtk-snand-spl.c | 133 ++++++++++++++++++++++++++
  12. 3 files changed, 143 insertions(+)
  13. create mode 100644 drivers/mtd/mtk-snand/mtk-snand-spl.c
  14. --- a/drivers/mtd/mtk-snand/Kconfig
  15. +++ b/drivers/mtd/mtk-snand/Kconfig
  16. @@ -19,3 +19,9 @@ config MTK_SPI_NAND_MTD
  17. help
  18. This option enables access to SPI-NAND flashes through the
  19. MTD interface of MediaTek SPI NAND Flash Controller
  20. +
  21. +config SPL_MTK_SPI_NAND
  22. + tristate "SPL support for MediaTek SPI NAND flash controller"
  23. + depends on MTK_SPI_NAND
  24. + help
  25. + This option enables access to SPI-NAND flashes in the SPL stage
  26. --- a/drivers/mtd/mtk-snand/Makefile
  27. +++ b/drivers/mtd/mtk-snand/Makefile
  28. @@ -8,4 +8,8 @@
  29. obj-y += mtk-snand.o mtk-snand-ecc.o mtk-snand-ids.o mtk-snand-os.o
  30. obj-$(CONFIG_MTK_SPI_NAND_MTD) += mtk-snand-mtd.o
  31. +ifdef CONFIG_SPL_BUILD
  32. +obj-$(CONFIG_SPL_MTK_SPI_NAND) += mtk-snand-spl.o
  33. +endif
  34. +
  35. ccflags-y += -DPRIVATE_MTK_SNAND_HEADER
  36. --- /dev/null
  37. +++ b/drivers/mtd/mtk-snand/mtk-snand-spl.c
  38. @@ -0,0 +1,133 @@
  39. +// SPDX-License-Identifier: GPL-2.0
  40. +/*
  41. + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
  42. + *
  43. + * Author: Weijie Gao <[email protected]>
  44. + */
  45. +
  46. +#include <common.h>
  47. +#include <dm.h>
  48. +#include <dm/uclass.h>
  49. +#include <malloc.h>
  50. +#include <mapmem.h>
  51. +#include <mtd.h>
  52. +#include <watchdog.h>
  53. +
  54. +#include "mtk-snand.h"
  55. +
  56. +static struct mtk_snand *snf;
  57. +static struct mtk_snand_chip_info cinfo;
  58. +static u32 oobavail;
  59. +
  60. +static u8 *page_cache;
  61. +
  62. +int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
  63. +{
  64. + u32 sizeremain = size, chunksize, leading;
  65. + uint32_t off = offs, writesize_mask = cinfo.pagesize - 1;
  66. + uint8_t *ptr = dst;
  67. + int ret;
  68. +
  69. + if (!snf)
  70. + return -ENODEV;
  71. +
  72. + while (sizeremain) {
  73. + schedule();
  74. +
  75. + leading = off & writesize_mask;
  76. + chunksize = cinfo.pagesize - leading;
  77. + if (chunksize > sizeremain)
  78. + chunksize = sizeremain;
  79. +
  80. + if (chunksize == cinfo.pagesize) {
  81. + ret = mtk_snand_read_page(snf, off - leading, ptr,
  82. + NULL, false);
  83. + if (ret)
  84. + break;
  85. + } else {
  86. + ret = mtk_snand_read_page(snf, off - leading,
  87. + page_cache, NULL, false);
  88. + if (ret)
  89. + break;
  90. +
  91. + memcpy(ptr, page_cache + leading, chunksize);
  92. + }
  93. +
  94. + off += chunksize;
  95. + ptr += chunksize;
  96. + sizeremain -= chunksize;
  97. + }
  98. +
  99. + return ret;
  100. +}
  101. +
  102. +void nand_init(void)
  103. +{
  104. + struct mtk_snand_platdata mtk_snand_pdata = {};
  105. + struct udevice *dev;
  106. + fdt_addr_t base;
  107. + int ret;
  108. +
  109. + ret = uclass_get_device_by_driver(UCLASS_MTD, DM_DRIVER_GET(mtk_snand),
  110. + &dev);
  111. + if (ret) {
  112. + printf("mtk-snand-spl: Device instance not found!\n");
  113. + return;
  114. + }
  115. +
  116. + base = dev_read_addr_name(dev, "nfi");
  117. + if (base == FDT_ADDR_T_NONE) {
  118. + printf("mtk-snand-spl: NFI base not set\n");
  119. + return;
  120. + }
  121. + mtk_snand_pdata.nfi_base = map_sysmem(base, 0);
  122. +
  123. + base = dev_read_addr_name(dev, "ecc");
  124. + if (base == FDT_ADDR_T_NONE) {
  125. + printf("mtk-snand-spl: ECC base not set\n");
  126. + return;
  127. + }
  128. + mtk_snand_pdata.ecc_base = map_sysmem(base, 0);
  129. +
  130. + mtk_snand_pdata.soc = dev_get_driver_data(dev);
  131. + mtk_snand_pdata.quad_spi = dev_read_bool(dev, "quad-spi");
  132. +
  133. + ret = mtk_snand_init(NULL, &mtk_snand_pdata, &snf);
  134. + if (ret) {
  135. + printf("mtk-snand-spl: failed to initialize SPI-NAND\n");
  136. + return;
  137. + }
  138. +
  139. + mtk_snand_get_chip_info(snf, &cinfo);
  140. +
  141. + oobavail = cinfo.num_sectors * (cinfo.fdm_size - 1);
  142. +
  143. + printf("SPI-NAND: %s (%uMB)\n", cinfo.model,
  144. + (u32)(cinfo.chipsize >> 20));
  145. +
  146. + page_cache = malloc(cinfo.pagesize + cinfo.sparesize);
  147. + if (!page_cache) {
  148. + mtk_snand_cleanup(snf);
  149. + printf("mtk-snand-spl: failed to allocate page cache\n");
  150. + }
  151. +}
  152. +
  153. +void nand_deselect(void)
  154. +{
  155. +
  156. +}
  157. +
  158. +static const struct udevice_id mtk_snand_ids[] = {
  159. + { .compatible = "mediatek,mt7622-snand", .data = SNAND_SOC_MT7622 },
  160. + { .compatible = "mediatek,mt7629-snand", .data = SNAND_SOC_MT7629 },
  161. + { .compatible = "mediatek,mt7981-snand", .data = SNAND_SOC_MT7981 },
  162. + { .compatible = "mediatek,mt7986-snand", .data = SNAND_SOC_MT7986 },
  163. + { /* sentinel */ },
  164. +};
  165. +
  166. +U_BOOT_DRIVER(mtk_snand) = {
  167. + .name = "mtk-snand",
  168. + .id = UCLASS_MTD,
  169. + .of_match = mtk_snand_ids,
  170. + .flags = DM_FLAG_PRE_RELOC,
  171. +};