xref: /aosp_15_r20/external/coreboot/src/drivers/spi/macronix.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <commonlib/helpers.h>
4 #include <spi_flash.h>
5 #include <spi-generic.h>
6 
7 #include "spi_flash_internal.h"
8 
9 /* MX25xx-specific commands */
10 #define CMD_MX25XX_WREN		0x06	/* Write Enable */
11 #define CMD_MX25XX_WRDI		0x04	/* Write Disable */
12 #define CMD_MX25XX_RDSR		0x05	/* Read Status Register */
13 #define CMD_MX25XX_WRSR		0x01	/* Write Status Register */
14 #define CMD_MX25XX_READ		0x03	/* Read Data Bytes */
15 #define CMD_MX25XX_FAST_READ	0x0b	/* Read Data Bytes at Higher Speed */
16 #define CMD_MX25XX_PP		0x02	/* Page Program */
17 #define CMD_MX25XX_SE		0x20	/* Sector Erase */
18 #define CMD_MX25XX_BE		0xD8	/* Block Erase */
19 #define CMD_MX25XX_CE		0xc7	/* Chip Erase */
20 #define CMD_MX25XX_DP		0xb9	/* Deep Power-down */
21 #define CMD_MX25XX_RES		0xab	/* Release from DP, and Read Signature */
22 
23 #define MACRONIX_SR_WIP		(1 << 0)	/* Write-in-Progress */
24 
25 static const struct spi_flash_part_id flash_table[] = {
26 	{
27 		/* MX25L8005 */
28 		.id[0] = 0x2014,
29 		.nr_sectors_shift = 8,
30 	},
31 	{
32 		/* MX25L1605D */
33 		.id[0] = 0x2015,
34 		.nr_sectors_shift = 9,
35 	},
36 	{
37 		/* MX25L3205D */
38 		.id[0] = 0x2016,
39 		.nr_sectors_shift = 10,
40 	},
41 	{
42 		/* MX25L6405D */
43 		.id[0] = 0x2017,
44 		.nr_sectors_shift = 11,
45 	},
46 	{
47 		/* MX25L12805D */
48 		.id[0] = 0x2018,
49 		.nr_sectors_shift = 12,
50 	},
51 	{
52 		/* MX25L25635F */
53 		.id[0] = 0x2019,
54 		.nr_sectors_shift = 13,
55 	},
56 	{
57 		/* MX66L51235F */
58 		.id[0] = 0x201a,
59 		.nr_sectors_shift = 14,
60 	},
61 	{
62 		/* MX25L1635D */
63 		.id[0] = 0x2415,
64 		.nr_sectors_shift = 9,
65 	},
66 	/*
67 	 * NOTE: C225xx JEDEC IDs are basically useless because Macronix keeps
68 	 * reusing the same IDs for vastly different chips. 35E versions always
69 	 * seem to support Dual I/O but not Dual Output, while 35F versions seem
70 	 * to support both, so we only set Dual I/O here to improve our chances
71 	 * of compatibility. Since Macronix makes it impossible to search all
72 	 * different parts that it recklessly assigned the same IDs to, it's
73 	 * hard to know if there may be parts that don't even support Dual I/O
74 	 * with these IDs, though (or what we should do if there are).
75 	 */
76 	{
77 		/* MX25L1635E */
78 		.id[0] = 0x2515,
79 		.nr_sectors_shift = 9,
80 		.fast_read_dual_io_support = 1,
81 	},
82 	{
83 		/* MX25U8032E */
84 		.id[0] = 0x2534,
85 		.nr_sectors_shift = 8,
86 		.fast_read_dual_io_support = 1,
87 	},
88 	{
89 		/* MX25U1635E/MX25U1635F */
90 		.id[0] = 0x2535,
91 		.nr_sectors_shift = 9,
92 		.fast_read_dual_io_support = 1,
93 	},
94 	{
95 		/* MX25U3235E/MX25U3235F */
96 		.id[0] = 0x2536,
97 		.nr_sectors_shift = 10,
98 		.fast_read_dual_io_support = 1,
99 	},
100 	{
101 		/* MX25U6435E/MX25U6435F */
102 		.id[0] = 0x2537,
103 		.nr_sectors_shift = 11,
104 		.fast_read_dual_io_support = 1,
105 	},
106 	{
107 		/* MX25U12835F */
108 		.id[0] = 0x2538,
109 		.nr_sectors_shift = 12,
110 		.fast_read_dual_io_support = 1,
111 	},
112 	{
113 		/* MX25U25635F */
114 		.id[0] = 0x2539,
115 		.nr_sectors_shift = 13,
116 		.fast_read_dual_io_support = 1,
117 	},
118 	{
119 		/* MX25U51235F */
120 		.id[0] = 0x253a,
121 		.nr_sectors_shift = 14,
122 		.fast_read_dual_io_support = 1,
123 	},
124 	{
125 		/* MX25L12855E */
126 		.id[0] = 0x2618,
127 		.nr_sectors_shift = 12,
128 		.fast_read_dual_io_support = 1,
129 	},
130 	{
131 		/* MX25L3235D/MX25L3225D/MX25L3236D/MX25L3237D */
132 		.id[0] = 0x5e16,
133 		.nr_sectors_shift = 10,
134 		.fast_read_dual_io_support = 1,
135 	},
136 	{
137 		/* MX25L6495F */
138 		.id[0] = 0x9517,
139 		.nr_sectors_shift = 11,
140 	},
141 	{
142 		/* MX77U25650F */
143 		.id[0] = 0x7539,
144 		.nr_sectors_shift = 13,
145 	},
146 };
147 
148 const struct spi_flash_vendor_info spi_flash_macronix_vi = {
149 	.id = VENDOR_ID_MACRONIX,
150 	.page_size_shift = 8,
151 	.sector_size_kib_shift = 2,
152 	.match_id_mask[0] = 0xffff,
153 	.ids = flash_table,
154 	.nr_part_ids = ARRAY_SIZE(flash_table),
155 	.desc = &spi_flash_pp_0x20_sector_desc,
156 };
157