42 #ifndef _QSPI_WINBOND_V2_H_
43 #define _QSPI_WINBOND_V2_H_
47 #ifndef QSPI_WINBOND_UNLOCK_PROTECTION
48 #define QSPI_WINBOND_UNLOCK_PROTECTION (0)
51 #define QSPI_WINBOND_MANUFACTURER_ID (0xEF)
52 #define QSPI_WINBOND_W25QXXXJWIQ_TYPE (0x60)
53 #define QSPI_WINBOND_W25QXXXJWIM_TYPE (0x80)
55 #define QSPI_WINBOND_READ_STATUS_REG2_OPCODE (0x35)
56 #define QSPI_WINBOND_READ_STATUS_REG3_OPCODE (0x15)
57 #define QSPI_WINBOND_WRITE_STATUS_REG2_OPCODE (0x31)
58 #define QSPI_WINBOND_WRITE_STATUS_REG3_OPCODE (0x11)
60 #define QSPI_WINBOND_SUSPEND_OPCODE (0x75)
61 #define QSPI_WINBOND_RESUME_OPCODE (0x7A)
63 #define QSPI_WINBOND_STATUS_REG_BP0_POS (2) // Block Protection Bit 0
64 #define QSPI_WINBOND_STATUS_REG_BP1_POS (3) // Block Protection Bit 1
65 #define QSPI_WINBOND_STATUS_REG_BP2_POS (4) // Block Protection Bit 2
66 #define QSPI_WINBOND_STATUS_REG_TB_POS (5) // Top/Bottom Protection Bit
67 #define QSPI_WINBOND_STATUS_REG_SEC_POS (6) // Sector/Block Protection Bit
68 #define QSPI_WINBOND_STATUS_REG_SRP_POS (7) // Status Register Protection Bit 0
70 #define QSPI_WINBOND_STATUS_REG_PROTECTION_MASK ((1 << QSPI_WINBOND_STATUS_REG_BP0_POS) | \
71 (1 << QSPI_WINBOND_STATUS_REG_BP1_POS) | \
72 (1 << QSPI_WINBOND_STATUS_REG_BP2_POS) | \
73 (1 << QSPI_WINBOND_STATUS_REG_TB_POS) | \
74 (1 << QSPI_WINBOND_STATUS_REG_SEC_POS) | \
75 (1 << QSPI_WINBOND_STATUS_REG_SRP_POS))
77 #define QSPI_WINBOND_STATUS_REG2_SRL_POS (0) // Status Register2 Protection Bit 1
78 #define QSPI_WINBOND_STATUS_REG2_CMP_POS (6) // Complement Protect Bit 1
80 #define QSPI_WINBOND_STATUS_REG2_PROTECTION_MASK ((1 << QSPI_WINBOND_STATUS_REG2_SRL_POS) | \
81 (1 << QSPI_WINBOND_STATUS_REG2_CMP_POS))
83 #define QSPI_WINBOND_STATUS_REG2_SUSPEND_POS (7)
84 #define QSPI_WINBOND_STATUS_REG2_SUSPEND_MASK (1 << QSPI_WINBOND_STATUS_REG2_SUSPEND_POS)
86 #define QSPI_WINBOND_STATUS_REG2_QUAD_ENABLE_POS (1)
87 #define QSPI_WINBOND_STATUS_REG2_QUAD_ENABLE_MASK (1 << QSPI_WINBOND_STATUS_REG2_QUAD_ENABLE_POS)
89 #define QSPI_WINBOND_STATUS_REG3_ADDR_MODE_POS (0)
90 #define QSPI_WINBOND_STATUS_REG3_ADDR_MODE_MASK (1 << QSPI_WINBOND_STATUS_REG3_ADDR_MODE_POS)
92 #define QSPI_WINBOND_STATUS_REG3_DRV_STRENGTH_POS (5)
93 #define QSPI_WINBOND_STATUS_REG3_DRV_STRENGTH_MASK (3 << QSPI_WINBOND_STATUS_REG3_DRV_STRENGTH_POS)
95 __RETAINED_CODE
static uint8_t qspi_winbond_read_register(
HW_QSPIC_ID id, uint8_t opcode, uint8_t mask)
97 __DBG_QSPI_VOLATILE__ uint8_t reg_val;
99 ASSERT_WARNING((opcode == QSPI_READ_STATUS_REG_OPCODE) ||
100 (opcode == QSPI_WINBOND_READ_STATUS_REG2_OPCODE) ||
101 (opcode == QSPI_WINBOND_READ_STATUS_REG3_OPCODE));
108 return (reg_val & mask);
111 __RETAINED_CODE
static void qspi_winbond_write_register(
HW_QSPIC_ID id, uint8_t opcode, uint8_t value)
113 ASSERT_WARNING((opcode == QSPI_WRITE_STATUS_REG_OPCODE) ||
114 (opcode == QSPI_WINBOND_WRITE_STATUS_REG2_OPCODE) ||
115 (opcode == QSPI_WINBOND_WRITE_STATUS_REG3_OPCODE));
123 __RETAINED_CODE
static uint8_t qspi_winbond_read_status_reg(
HW_QSPIC_ID id)
125 return qspi_winbond_read_register(
id, QSPI_READ_STATUS_REG_OPCODE, 0xFF);
128 __RETAINED_CODE
static void qspi_winbond_write_status_reg(
HW_QSPIC_ID id, uint8_t status_reg)
130 qspi_winbond_write_register(
id, QSPI_WRITE_STATUS_REG_OPCODE, status_reg);
143 __RETAINED_CODE
static bool qspi_winbond_is_suspended(
HW_QSPIC_ID id)
145 __DBG_QSPI_VOLATILE__ uint8_t is_suspended;
147 is_suspended = qspi_winbond_read_register(
id, QSPI_WINBOND_READ_STATUS_REG2_OPCODE,
148 QSPI_WINBOND_STATUS_REG2_SUSPEND_MASK);
149 return (
bool) is_suspended;
156 is_busy = (
HW_QSPI_BUSY_LEVEL ) (qspi_winbond_read_status_reg(
id) & QSPI_STATUS_REG_BUSY_MASK);
158 return (
bool) is_busy;
161 __RETAINED_CODE
static void qspi_winbond_enable_quad_mode(
HW_QSPIC_ID id)
163 __DBG_QSPI_VOLATILE__ uint8_t status_reg2;
164 __DBG_QSPI_VOLATILE__ uint8_t verify;
166 status_reg2 = qspi_winbond_read_register(
id, QSPI_WINBOND_READ_STATUS_REG2_OPCODE, 0xFF);
168 if (!(status_reg2 & QSPI_WINBOND_STATUS_REG2_QUAD_ENABLE_MASK)) {
169 status_reg2 |= QSPI_WINBOND_STATUS_REG2_QUAD_ENABLE_MASK;
170 qspi_flash_write_enable(
id);
171 qspi_winbond_write_register(
id, QSPI_WINBOND_WRITE_STATUS_REG2_OPCODE, status_reg2);
173 verify = qspi_winbond_read_register(
id, QSPI_WINBOND_READ_STATUS_REG2_OPCODE, 0xFF);
174 ASSERT_WARNING(status_reg2 == verify);
180 __DBG_QSPI_VOLATILE__ uint8_t status_reg3;
181 __DBG_QSPI_VOLATILE__ uint8_t verify;
183 status_reg3 = qspi_winbond_read_register(
id, QSPI_WINBOND_READ_STATUS_REG3_OPCODE, 0xFF);
185 if ((status_reg3 & QSPI_WINBOND_STATUS_REG3_DRV_STRENGTH_MASK) != 0) {
186 status_reg3 &= ~QSPI_WINBOND_STATUS_REG3_DRV_STRENGTH_MASK;
187 qspi_flash_write_enable(
id);
188 qspi_winbond_write_register(
id, QSPI_WINBOND_WRITE_STATUS_REG3_OPCODE, status_reg3);
190 verify = qspi_winbond_read_register(
id, QSPI_WINBOND_READ_STATUS_REG3_OPCODE, 0xFF);
191 ASSERT_WARNING(status_reg3 == verify);
197 __DBG_QSPI_VOLATILE__ uint8_t status_reg;
198 __DBG_QSPI_VOLATILE__ uint8_t status_reg2;
199 __DBG_QSPI_VOLATILE__ uint8_t verify;
201 status_reg = qspi_winbond_read_status_reg(
id);
202 status_reg2 = qspi_winbond_read_register(
id, QSPI_WINBOND_READ_STATUS_REG2_OPCODE, 0xFF);
205 if (status_reg & QSPI_WINBOND_STATUS_REG_PROTECTION_MASK) {
206 status_reg &= ~QSPI_WINBOND_STATUS_REG_PROTECTION_MASK;
207 qspi_flash_write_enable(
id);
208 qspi_winbond_write_status_reg(
id, status_reg);
210 verify = qspi_winbond_read_status_reg(
id);
211 ASSERT_WARNING(status_reg == verify);
214 if (status_reg2 & QSPI_WINBOND_STATUS_REG2_PROTECTION_MASK) {
215 status_reg2 &= ~QSPI_WINBOND_STATUS_REG2_PROTECTION_MASK;
216 qspi_flash_write_enable(
id);
217 qspi_winbond_write_register(
id, QSPI_WINBOND_WRITE_STATUS_REG2_OPCODE, status_reg2);
219 verify = qspi_winbond_read_register(
id, QSPI_WINBOND_READ_STATUS_REG2_OPCODE, 0xFF);
220 ASSERT_WARNING(status_reg2 == verify);