1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (C) 2005, Intec Automation Inc. |
4 | * Copyright (C) 2014, Freescale Semiconductor, Inc. |
5 | */ |
6 | |
7 | #include <linux/mtd/spi-nor.h> |
8 | |
9 | #include "core.h" |
10 | |
11 | static int |
12 | is25lp256_post_bfpt_fixups(struct spi_nor *nor, |
13 | const struct sfdp_parameter_header *, |
14 | const struct sfdp_bfpt *bfpt) |
15 | { |
16 | /* |
17 | * IS25LP256 supports 4B opcodes, but the BFPT advertises |
18 | * BFPT_DWORD1_ADDRESS_BYTES_3_ONLY. |
19 | * Overwrite the number of address bytes advertised by the BFPT. |
20 | */ |
21 | if ((bfpt->dwords[SFDP_DWORD(1)] & BFPT_DWORD1_ADDRESS_BYTES_MASK) == |
22 | BFPT_DWORD1_ADDRESS_BYTES_3_ONLY) |
23 | nor->params->addr_nbytes = 4; |
24 | |
25 | return 0; |
26 | } |
27 | |
28 | static const struct spi_nor_fixups is25lp256_fixups = { |
29 | .post_bfpt = is25lp256_post_bfpt_fixups, |
30 | }; |
31 | |
32 | static int pm25lv_nor_late_init(struct spi_nor *nor) |
33 | { |
34 | struct spi_nor_erase_map *map = &nor->params->erase_map; |
35 | int i; |
36 | |
37 | /* The PM25LV series has a different 4k sector erase opcode */ |
38 | for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) |
39 | if (map->erase_type[i].size == 4096) |
40 | map->erase_type[i].opcode = SPINOR_OP_BE_4K_PMC; |
41 | |
42 | return 0; |
43 | } |
44 | |
45 | static const struct spi_nor_fixups pm25lv_nor_fixups = { |
46 | .late_init = pm25lv_nor_late_init, |
47 | }; |
48 | |
49 | static const struct flash_info issi_nor_parts[] = { |
50 | { |
51 | .name = "pm25lv512" , |
52 | .sector_size = SZ_32K, |
53 | .size = SZ_64K, |
54 | .no_sfdp_flags = SECT_4K, |
55 | .fixups = &pm25lv_nor_fixups |
56 | }, { |
57 | .name = "pm25lv010" , |
58 | .sector_size = SZ_32K, |
59 | .size = SZ_128K, |
60 | .no_sfdp_flags = SECT_4K, |
61 | .fixups = &pm25lv_nor_fixups |
62 | }, { |
63 | .id = SNOR_ID(0x7f, 0x9d, 0x20), |
64 | .name = "is25cd512" , |
65 | .sector_size = SZ_32K, |
66 | .size = SZ_64K, |
67 | .no_sfdp_flags = SECT_4K, |
68 | }, { |
69 | .id = SNOR_ID(0x7f, 0x9d, 0x46), |
70 | .name = "pm25lq032" , |
71 | .size = SZ_4M, |
72 | .no_sfdp_flags = SECT_4K, |
73 | }, { |
74 | .id = SNOR_ID(0x9d, 0x40, 0x13), |
75 | .name = "is25lq040b" , |
76 | .size = SZ_512K, |
77 | .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, |
78 | }, { |
79 | .id = SNOR_ID(0x9d, 0x60, 0x14), |
80 | .name = "is25lp080d" , |
81 | .size = SZ_1M, |
82 | .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, |
83 | }, { |
84 | .id = SNOR_ID(0x9d, 0x60, 0x15), |
85 | .name = "is25lp016d" , |
86 | .size = SZ_2M, |
87 | .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, |
88 | }, { |
89 | .id = SNOR_ID(0x9d, 0x60, 0x16), |
90 | .name = "is25lp032" , |
91 | .size = SZ_4M, |
92 | .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ, |
93 | }, { |
94 | .id = SNOR_ID(0x9d, 0x60, 0x17), |
95 | .name = "is25lp064" , |
96 | .size = SZ_8M, |
97 | .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ, |
98 | }, { |
99 | .id = SNOR_ID(0x9d, 0x60, 0x18), |
100 | .name = "is25lp128" , |
101 | .size = SZ_16M, |
102 | .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ, |
103 | }, { |
104 | .id = SNOR_ID(0x9d, 0x60, 0x19), |
105 | .name = "is25lp256" , |
106 | .fixups = &is25lp256_fixups, |
107 | .fixup_flags = SPI_NOR_4B_OPCODES, |
108 | }, { |
109 | .id = SNOR_ID(0x9d, 0x70, 0x16), |
110 | .name = "is25wp032" , |
111 | .size = SZ_4M, |
112 | .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, |
113 | }, { |
114 | .id = SNOR_ID(0x9d, 0x70, 0x17), |
115 | .size = SZ_8M, |
116 | .name = "is25wp064" , |
117 | .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, |
118 | }, { |
119 | .id = SNOR_ID(0x9d, 0x70, 0x18), |
120 | .name = "is25wp128" , |
121 | .size = SZ_16M, |
122 | .no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ, |
123 | }, { |
124 | .id = SNOR_ID(0x9d, 0x70, 0x19), |
125 | .name = "is25wp256" , |
126 | .flags = SPI_NOR_QUAD_PP, |
127 | .fixups = &is25lp256_fixups, |
128 | .fixup_flags = SPI_NOR_4B_OPCODES, |
129 | } |
130 | }; |
131 | |
132 | static void issi_nor_default_init(struct spi_nor *nor) |
133 | { |
134 | nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; |
135 | } |
136 | |
137 | static const struct spi_nor_fixups issi_fixups = { |
138 | .default_init = issi_nor_default_init, |
139 | }; |
140 | |
141 | const struct spi_nor_manufacturer spi_nor_issi = { |
142 | .name = "issi" , |
143 | .parts = issi_nor_parts, |
144 | .nparts = ARRAY_SIZE(issi_nor_parts), |
145 | .fixups = &issi_fixups, |
146 | }; |
147 | |