mediatek: copy patches-6.1 to patches-6.6
[openwrt/staging/stintel.git] / target / linux / mediatek / patches-6.6 / 435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch
1 From 7670ec4a14891a1a182b98a9c403ffbf6b49e4b1 Mon Sep 17 00:00:00 2001
2 From: "SkyLake.Huang" <skylake.huang@mediatek.com>
3 Date: Thu, 23 Jun 2022 18:39:56 +0800
4 Subject: [PATCH 5/6] drivers: mtd: spinand: Add calibration support for
5 spinand
6
7 Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
8 ---
9 drivers/mtd/nand/spi/core.c | 54 +++++++++++++++++++++++++++++++++++++
10 1 file changed, 54 insertions(+)
11
12 --- a/drivers/mtd/nand/spi/core.c
13 +++ b/drivers/mtd/nand/spi/core.c
14 @@ -978,6 +978,56 @@ static int spinand_manufacturer_match(st
15 return -ENOTSUPP;
16 }
17
18 +int spinand_cal_read(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen) {
19 + struct spinand_device *spinand = (struct spinand_device *)priv;
20 + struct device *dev = &spinand->spimem->spi->dev;
21 + struct spi_mem_op op = SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, buf, readlen);
22 + struct nand_pos pos;
23 + struct nand_page_io_req req;
24 + u8 status;
25 + int ret;
26 +
27 + if(addrlen != sizeof(struct nand_addr)/sizeof(unsigned int)) {
28 + dev_err(dev, "Must provide correct addr(length) for spinand calibration\n");
29 + return -EINVAL;
30 + }
31 +
32 + ret = spinand_reset_op(spinand);
33 + if (ret)
34 + return ret;
35 +
36 + /* We should store our golden data in first target because
37 + * we can't switch target at this moment.
38 + */
39 + pos = (struct nand_pos){
40 + .target = 0,
41 + .lun = *addr,
42 + .plane = *(addr+1),
43 + .eraseblock = *(addr+2),
44 + .page = *(addr+3),
45 + };
46 +
47 + req = (struct nand_page_io_req){
48 + .pos = pos,
49 + .dataoffs = *(addr+4),
50 + .datalen = readlen,
51 + .databuf.in = buf,
52 + .mode = MTD_OPS_AUTO_OOB,
53 + };
54 +
55 + ret = spinand_load_page_op(spinand, &req);
56 + if (ret)
57 + return ret;
58 +
59 + ret = spinand_wait(spinand, &status);
60 + if (ret < 0)
61 + return ret;
62 +
63 + ret = spi_mem_exec_op(spinand->spimem, &op);
64 +
65 + return 0;
66 +}
67 +
68 static int spinand_id_detect(struct spinand_device *spinand)
69 {
70 u8 *id = spinand->id.data;
71 @@ -1228,6 +1278,10 @@ static int spinand_init(struct spinand_d
72 if (!spinand->scratchbuf)
73 return -ENOMEM;
74
75 + ret = spi_mem_do_calibration(spinand->spimem, spinand_cal_read, spinand);
76 + if (ret)
77 + dev_err(dev, "Failed to calibrate SPI-NAND (err = %d)\n", ret);
78 +
79 ret = spinand_detect(spinand);
80 if (ret)
81 goto err_free_bufs;