xref: /openbmc/linux/drivers/mtd/nand/spi/ato.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1*fc602b4fSAidan MacDonald // SPDX-License-Identifier: GPL-2.0
2*fc602b4fSAidan MacDonald /*
3*fc602b4fSAidan MacDonald  * Copyright (C) 2022 Aidan MacDonald
4*fc602b4fSAidan MacDonald  *
5*fc602b4fSAidan MacDonald  * Author: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
6*fc602b4fSAidan MacDonald  */
7*fc602b4fSAidan MacDonald 
8*fc602b4fSAidan MacDonald #include <linux/device.h>
9*fc602b4fSAidan MacDonald #include <linux/kernel.h>
10*fc602b4fSAidan MacDonald #include <linux/mtd/spinand.h>
11*fc602b4fSAidan MacDonald 
12*fc602b4fSAidan MacDonald 
13*fc602b4fSAidan MacDonald #define SPINAND_MFR_ATO		0x9b
14*fc602b4fSAidan MacDonald 
15*fc602b4fSAidan MacDonald 
16*fc602b4fSAidan MacDonald static SPINAND_OP_VARIANTS(read_cache_variants,
17*fc602b4fSAidan MacDonald 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
18*fc602b4fSAidan MacDonald 		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
19*fc602b4fSAidan MacDonald 		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
20*fc602b4fSAidan MacDonald 
21*fc602b4fSAidan MacDonald static SPINAND_OP_VARIANTS(write_cache_variants,
22*fc602b4fSAidan MacDonald 		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
23*fc602b4fSAidan MacDonald 		SPINAND_PROG_LOAD(true, 0, NULL, 0));
24*fc602b4fSAidan MacDonald 
25*fc602b4fSAidan MacDonald static SPINAND_OP_VARIANTS(update_cache_variants,
26*fc602b4fSAidan MacDonald 		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
27*fc602b4fSAidan MacDonald 		SPINAND_PROG_LOAD(false, 0, NULL, 0));
28*fc602b4fSAidan MacDonald 
29*fc602b4fSAidan MacDonald 
ato25d1ga_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)30*fc602b4fSAidan MacDonald static int ato25d1ga_ooblayout_ecc(struct mtd_info *mtd, int section,
31*fc602b4fSAidan MacDonald 				   struct mtd_oob_region *region)
32*fc602b4fSAidan MacDonald {
33*fc602b4fSAidan MacDonald 	if (section > 3)
34*fc602b4fSAidan MacDonald 		return -ERANGE;
35*fc602b4fSAidan MacDonald 
36*fc602b4fSAidan MacDonald 	region->offset = (16 * section) + 8;
37*fc602b4fSAidan MacDonald 	region->length = 8;
38*fc602b4fSAidan MacDonald 	return 0;
39*fc602b4fSAidan MacDonald }
40*fc602b4fSAidan MacDonald 
ato25d1ga_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)41*fc602b4fSAidan MacDonald static int ato25d1ga_ooblayout_free(struct mtd_info *mtd, int section,
42*fc602b4fSAidan MacDonald 				   struct mtd_oob_region *region)
43*fc602b4fSAidan MacDonald {
44*fc602b4fSAidan MacDonald 	if (section > 3)
45*fc602b4fSAidan MacDonald 		return -ERANGE;
46*fc602b4fSAidan MacDonald 
47*fc602b4fSAidan MacDonald 	if (section) {
48*fc602b4fSAidan MacDonald 		region->offset = (16 * section);
49*fc602b4fSAidan MacDonald 		region->length = 8;
50*fc602b4fSAidan MacDonald 	} else {
51*fc602b4fSAidan MacDonald 		/* first byte of section 0 is reserved for the BBM */
52*fc602b4fSAidan MacDonald 		region->offset = 1;
53*fc602b4fSAidan MacDonald 		region->length = 7;
54*fc602b4fSAidan MacDonald 	}
55*fc602b4fSAidan MacDonald 
56*fc602b4fSAidan MacDonald 	return 0;
57*fc602b4fSAidan MacDonald }
58*fc602b4fSAidan MacDonald 
59*fc602b4fSAidan MacDonald static const struct mtd_ooblayout_ops ato25d1ga_ooblayout = {
60*fc602b4fSAidan MacDonald 	.ecc = ato25d1ga_ooblayout_ecc,
61*fc602b4fSAidan MacDonald 	.free = ato25d1ga_ooblayout_free,
62*fc602b4fSAidan MacDonald };
63*fc602b4fSAidan MacDonald 
64*fc602b4fSAidan MacDonald 
65*fc602b4fSAidan MacDonald static const struct spinand_info ato_spinand_table[] = {
66*fc602b4fSAidan MacDonald 	SPINAND_INFO("ATO25D1GA",
67*fc602b4fSAidan MacDonald 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x12),
68*fc602b4fSAidan MacDonald 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
69*fc602b4fSAidan MacDonald 		     NAND_ECCREQ(1, 512),
70*fc602b4fSAidan MacDonald 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
71*fc602b4fSAidan MacDonald 					      &write_cache_variants,
72*fc602b4fSAidan MacDonald 					      &update_cache_variants),
73*fc602b4fSAidan MacDonald 		     SPINAND_HAS_QE_BIT,
74*fc602b4fSAidan MacDonald 		     SPINAND_ECCINFO(&ato25d1ga_ooblayout, NULL)),
75*fc602b4fSAidan MacDonald };
76*fc602b4fSAidan MacDonald 
77*fc602b4fSAidan MacDonald static const struct spinand_manufacturer_ops ato_spinand_manuf_ops = {
78*fc602b4fSAidan MacDonald };
79*fc602b4fSAidan MacDonald 
80*fc602b4fSAidan MacDonald const struct spinand_manufacturer ato_spinand_manufacturer = {
81*fc602b4fSAidan MacDonald 	.id = SPINAND_MFR_ATO,
82*fc602b4fSAidan MacDonald 	.name = "ATO",
83*fc602b4fSAidan MacDonald 	.chips = ato_spinand_table,
84*fc602b4fSAidan MacDonald 	.nchips = ARRAY_SIZE(ato_spinand_table),
85*fc602b4fSAidan MacDonald 	.ops = &ato_spinand_manuf_ops,
86*fc602b4fSAidan MacDonald };
87