Skip to content

Commit 213ec26

Browse files
committed
drivers: flash: stm32: qspi: support DTS quad enable requirements
Adds support for DTS quad_enable_requirements property. Signed-off-by: Georgij Cernysiov <[email protected]>
1 parent 90769b3 commit 213ec26

File tree

1 file changed

+118
-25
lines changed

1 file changed

+118
-25
lines changed

drivers/flash/flash_stm32_qspi.c

Lines changed: 118 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct flash_stm32_qspi_data {
9292
struct jesd216_erase_type erase_types[JESD216_NUM_ERASE_TYPES];
9393
/* Number of bytes per page */
9494
uint16_t page_size;
95+
enum jesd216_dw15_qer_type qer_type;
9596
enum jesd216_mode_type mode;
9697
int cmd_status;
9798
struct stream dma;
@@ -756,26 +757,83 @@ static int qspi_program_addr_4b(const struct device *dev)
756757
return ret;
757758
}
758759

759-
static int qspi_read_status_register(const struct device *dev, uint8_t *reg)
760+
static int qspi_read_status_register(const struct device *dev, uint8_t reg_num, uint8_t *reg)
760761
{
761762
QSPI_CommandTypeDef cmd = {
762-
.Instruction = SPI_NOR_CMD_RDSR,
763763
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
764764
.DataMode = QSPI_DATA_1_LINE,
765765
};
766766

767+
switch (reg_num) {
768+
case 1U:
769+
cmd.Instruction = SPI_NOR_CMD_RDSR;
770+
break;
771+
case 2U:
772+
cmd.Instruction = SPI_NOR_CMD_RDSR2;
773+
break;
774+
case 3U:
775+
cmd.Instruction = SPI_NOR_CMD_RDSR3;
776+
break;
777+
default:
778+
return -EINVAL;
779+
}
780+
767781
return qspi_read_access(dev, &cmd, reg, sizeof(*reg));
768782
}
769783

770-
static int qspi_write_status_register(const struct device *dev, uint8_t reg)
784+
static int qspi_write_status_register(const struct device *dev, uint8_t reg_num, uint8_t reg)
771785
{
786+
struct flash_stm32_qspi_data *dev_data = dev->data;
787+
size_t size;
788+
uint8_t regs[4] = { 0 };
789+
uint8_t *regs_p;
790+
int ret;
791+
772792
QSPI_CommandTypeDef cmd = {
773793
.Instruction = SPI_NOR_CMD_WRSR,
774794
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
775795
.DataMode = QSPI_DATA_1_LINE,
776796
};
777797

778-
return qspi_write_access(dev, &cmd, &reg, sizeof(reg));
798+
if (reg_num == 1) {
799+
size = 1U;
800+
regs[0] = reg;
801+
regs_p = &regs[0];
802+
/* 1 byte write clears SR2, write SR2 as well */
803+
if (dev_data->qer_type == JESD216_DW15_QER_S2B1v1) {
804+
ret = qspi_read_status_register(dev, 2, &regs[1]);
805+
if (ret < 0) {
806+
return ret;
807+
}
808+
size = 2U;
809+
}
810+
} else if (reg_num == 2) {
811+
cmd.Instruction = SPI_NOR_CMD_WRSR2;
812+
size = 1U;
813+
regs[1] = reg;
814+
regs_p = &regs[1];
815+
/* if SR2 write needs SR1 */
816+
if ((dev_data->qer_type == JESD216_DW15_QER_VAL_S2B1v1) ||
817+
(dev_data->qer_type == JESD216_DW15_QER_VAL_S2B1v4) ||
818+
(dev_data->qer_type == JESD216_DW15_QER_VAL_S2B1v5)) {
819+
ret = qspi_read_status_register(dev, 1, &regs[0]);
820+
if (ret < 0) {
821+
return ret;
822+
}
823+
cmd.Instruction = SPI_NOR_CMD_WRSR;
824+
size = 2U;
825+
regs_p = &regs[0];
826+
}
827+
} else if (reg_num == 3) {
828+
cmd.Instruction = SPI_NOR_CMD_WRSR3;
829+
size = 1U;
830+
regs[2] = reg;
831+
regs_p = &regs[2];
832+
} else {
833+
return -EINVAL;
834+
}
835+
836+
return qspi_write_access(dev, &cmd, regs_p, size);
779837
}
780838

781839
static int qspi_write_enable(const struct device *dev)
@@ -794,7 +852,7 @@ static int qspi_write_enable(const struct device *dev)
794852
}
795853

796854
do {
797-
ret = qspi_read_status_register(dev, &reg);
855+
ret = qspi_read_status_register(dev, 1U, &reg);
798856
} while (!ret && !(reg & SPI_NOR_WEL_BIT));
799857

800858
return ret;
@@ -803,51 +861,75 @@ static int qspi_write_enable(const struct device *dev)
803861
static int qspi_program_quad_io(const struct device *dev)
804862
{
805863
struct flash_stm32_qspi_data *data = dev->data;
864+
uint8_t qe_reg_num;
865+
uint8_t qe_bit;
806866
uint8_t reg;
807867
int ret;
808868

809-
/* Check if QE bit setting is required */
810-
ret = qspi_read_status_register(dev, &reg);
811-
if (ret) {
869+
switch (data->qer_type) {
870+
case JESD216_DW15_QER_NONE:
871+
/* no QE bit, device detects reads based on opcode */
872+
return 0;
873+
case JESD216_DW15_QER_S1B6:
874+
qe_reg_num = 1U;
875+
qe_bit = BIT(6U);
876+
break;
877+
case JESD216_DW15_QER_S2B7:
878+
qe_reg_num = 2U;
879+
qe_bit = BIT(7U);
880+
break;
881+
case JESD216_DW15_QER_S2B1v1:
882+
__fallthrough;
883+
case JESD216_DW15_QER_S2B1v4:
884+
__fallthrough;
885+
case JESD216_DW15_QER_S2B1v5:
886+
__fallthrough;
887+
case JESD216_DW15_QER_S2B1v6:
888+
qe_reg_num = 2U;
889+
qe_bit = BIT(1U);
890+
break;
891+
default:
892+
return -ENOTSUP;
893+
}
894+
895+
ret = qspi_read_status_register(dev, qe_reg_num, &reg);
896+
if (ret < 0) {
812897
return ret;
813898
}
814899

815-
/* Quit early when QE bit is already set */
816-
if (reg & SPI_NOR_QE_BIT) {
817-
goto out;
900+
/* exit early if QE bit is already set */
901+
if ((reg & qe_bit) != 0U) {
902+
return 0;
818903
}
819904

905+
reg |= qe_bit;
906+
820907
ret = qspi_write_enable(dev);
821-
if (ret) {
908+
if (ret < 0) {
822909
return ret;
823910
}
824911

825-
reg |= SPI_NOR_QE_BIT;
826-
ret = qspi_write_status_register(dev, reg);
827-
if (ret) {
912+
ret = qspi_write_status_register(dev, qe_reg_num, reg);
913+
if (ret < 0) {
828914
return ret;
829915
}
830916

831917
ret = qspi_wait_until_ready(dev);
832-
if (ret) {
918+
if (ret < 0) {
833919
return ret;
834920
}
835921

836-
ret = qspi_read_status_register(dev, &reg);
837-
if (ret) {
922+
/* validate that QE bit is set */
923+
ret = qspi_read_status_register(dev, qe_reg_num, &reg);
924+
if (ret < 0) {
838925
return ret;
839926
}
840927

841-
/* Check if QE bit programming is finished */
842-
if (!(reg & SPI_NOR_QE_BIT)) {
843-
LOG_ERR("Quad Enable [QE] bit in status reg not set");
928+
if ((reg & qe_bit) == 0U) {
929+
LOG_ERR("Status Register %u [0x%02x] not set", qe_reg_num, reg);
844930
return -EIO;
845931
}
846932

847-
out:
848-
LOG_INF("Flash - QUAD mode enabled [SR:0x%02x]", reg);
849-
data->flag_quad_io_en = true;
850-
851933
return ret;
852934
}
853935

@@ -947,13 +1029,17 @@ static int spi_nor_process_bfp(const struct device *dev,
9471029

9481030
LOG_INF("Quad read mode %d instr [0x%x] will be used", data->mode, res.instr);
9491031

1032+
LOG_INF("QE requirement mode: %x", data->qer_type);
1033+
9501034
/* enable QE */
9511035
rc = qspi_program_quad_io(dev);
9521036
if (rc < 0) {
9531037
LOG_ERR("Failed to enable Quad mode: %d", rc);
9541038
return rc;
9551039
}
9561040

1041+
data->flag_quad_io_en = true;
1042+
LOG_INF("Quad mode enabled");
9571043
}
9581044

9591045
return 0;
@@ -1198,6 +1284,12 @@ static void flash_stm32_qspi_irq_config_func(const struct device *dev);
11981284
(_CONCAT(SPI_NOR_CMD_, DT_STRING_TOKEN(DT_DRV_INST(inst), writeoc))), \
11991285
((default_value)))
12001286

1287+
#define DT_QER_PROP_OR(inst, default_value) \
1288+
COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, quad_enable_requirements), \
1289+
(_CONCAT(JESD216_DW15_QER_VAL_, \
1290+
DT_STRING_TOKEN(DT_DRV_INST(inst), quad_enable_requirements))), \
1291+
((default_value)))
1292+
12011293
#define STM32_QSPI_NODE DT_INST_PARENT(0)
12021294

12031295
PINCTRL_DT_DEFINE(STM32_QSPI_NODE);
@@ -1227,6 +1319,7 @@ static struct flash_stm32_qspi_data flash_stm32_qspi_dev_data = {
12271319
.ClockMode = QSPI_CLOCK_MODE_0,
12281320
},
12291321
},
1322+
.qer_type = DT_QER_PROP_OR(0, JESD216_DW15_QER_VAL_S1B6),
12301323
.qspi_write_cmd = DT_WRITEOC_PROP_OR(0, SPI_NOR_CMD_PP_1_4_4),
12311324
QSPI_DMA_CHANNEL(STM32_QSPI_NODE, tx_rx)
12321325
};

0 commit comments

Comments
 (0)