@@ -598,31 +598,138 @@ static int dev_pm_action_cb(const struct device *dev,
598598static int quad_enable_set (const struct device * dev , bool enable )
599599{
600600 struct flash_mspi_nor_data * dev_data = dev -> data ;
601+ uint8_t op_code ;
602+ uint8_t qe_bit ;
603+ uint8_t status_reg ;
604+ uint8_t payload_len ;
605+ uint8_t payload [2 ];
601606 int rc ;
602607
603- rc = cmd_wren (dev );
608+ switch (dev_data -> switch_info .quad_enable_req ) {
609+ case JESD216_DW15_QER_VAL_S1B6 :
610+ op_code = SPI_NOR_CMD_RDSR ;
611+ qe_bit = BIT (6 );
612+ break ;
613+ case JESD216_DW15_QER_VAL_S2B7 :
614+ /* Use special Read status register 2 instruction. */
615+ op_code = 0x3F ;
616+ qe_bit = BIT (7 );
617+ break ;
618+ case JESD216_DW15_QER_VAL_S2B1v1 :
619+ case JESD216_DW15_QER_VAL_S2B1v4 :
620+ case JESD216_DW15_QER_VAL_S2B1v5 :
621+ case JESD216_DW15_QER_VAL_S2B1v6 :
622+ op_code = SPI_NOR_CMD_RDSR2 ;
623+ qe_bit = BIT (1 );
624+ break ;
625+ default :
626+ LOG_ERR ("Unknown Quad Enable Requirement: %u" ,
627+ dev_data -> switch_info .quad_enable_req );
628+ return - ENOTSUP ;
629+ }
630+
631+ rc = cmd_rdsr (dev , op_code , & status_reg );
604632 if (rc < 0 ) {
605- LOG_ERR ("Failed to set write enable: %d" , rc );
606633 return rc ;
607634 }
608635
609- if (dev_data -> switch_info .quad_enable_req == JESD216_DW15_QER_VAL_S1B6 ) {
610- uint8_t mode_payload = enable ? BIT (6 ) : 0 ;
636+ if (((status_reg & qe_bit ) != 0 ) == enable ) {
637+ /* Nothing to do, the QE bit is already set properly. */
638+ return 0 ;
639+ }
640+
641+ status_reg ^= qe_bit ;
642+
643+ switch (dev_data -> switch_info .quad_enable_req ) {
644+ default :
645+ case JESD216_DW15_QER_VAL_S1B6 :
646+ payload_len = 1 ;
647+ op_code = SPI_NOR_CMD_WRSR ;
648+ break ;
649+ case JESD216_DW15_QER_VAL_S2B7 :
650+ payload_len = 1 ;
651+ /* Use special Write status register 2 instruction. */
652+ op_code = 0x3E ;
653+ break ;
654+ case JESD216_DW15_QER_VAL_S2B1v1 :
655+ case JESD216_DW15_QER_VAL_S2B1v4 :
656+ case JESD216_DW15_QER_VAL_S2B1v5 :
657+ payload_len = 2 ;
658+ op_code = SPI_NOR_CMD_WRSR ;
659+ break ;
660+ case JESD216_DW15_QER_VAL_S2B1v6 :
661+ payload_len = 1 ;
662+ op_code = SPI_NOR_CMD_WRSR2 ;
663+ break ;
664+ }
665+
666+ if (payload_len == 1 ) {
667+ payload [0 ] = status_reg ;
668+ } else {
669+ payload [1 ] = status_reg ;
611670
612- rc = cmd_wrsr (dev , SPI_NOR_CMD_WRSR , 1 , & mode_payload );
671+ /* When the Write Status command is to be sent with two data
672+ * bytes (this is the case for S2B1v1, S2B1v4, and S2B1v5 QER
673+ * values), the first status register needs to be read and
674+ * sent as the first byte, so that its value is not modified.
675+ */
676+ rc = cmd_rdsr (dev , SPI_NOR_CMD_RDSR , & payload [0 ]);
613677 if (rc < 0 ) {
614- LOG_ERR ("Failed to enable/disable quad mode: %d" , rc );
615678 return rc ;
616679 }
617- } else {
618- /* TODO: handle all DW15 QER values */
680+ }
681+
682+ rc = cmd_wrsr (dev , op_code , payload_len , payload );
683+ if (rc < 0 ) {
684+ return rc ;
685+ }
686+
687+ return 0 ;
688+ }
689+
690+ static int octal_enable_set (const struct device * dev , bool enable )
691+ {
692+ struct flash_mspi_nor_data * dev_data = dev -> data ;
693+ uint8_t op_code ;
694+ uint8_t oe_bit ;
695+ uint8_t status_reg ;
696+ int rc ;
697+
698+ if (dev_data -> switch_info .octal_enable_req != BFP_DW19_OER_VAL_S2B3 ) {
699+ LOG_ERR ("Unknown Octal Enable Requirement: %u" ,
700+ dev_data -> switch_info .octal_enable_req );
619701 return - ENOTSUP ;
620702 }
621703
622- rc = wait_until_ready ( dev , K_USEC ( 1 ) );
704+ oe_bit = BIT ( 3 );
623705
706+ /* Use special Read status register 2 instruction 0x65 with one address
707+ * byte 0x02 and one dummy byte.
708+ */
709+ op_code = 0x65 ;
710+ set_up_xfer (dev , MSPI_RX );
711+ dev_data -> xfer .rx_dummy = 8 ;
712+ dev_data -> xfer .addr_length = 1 ;
713+ dev_data -> packet .address = 0x02 ;
714+ dev_data -> packet .num_bytes = sizeof (uint8_t );
715+ dev_data -> packet .data_buf = & status_reg ;
716+ rc = perform_xfer (dev , op_code , false);
717+ if (rc < 0 ) {
718+ LOG_ERR ("cmd_rdsr 0x%02x failed: %d" , op_code , rc );
719+ return rc ;
720+ }
721+
722+ if (((status_reg & oe_bit ) != 0 ) == enable ) {
723+ /* Nothing to do, the OE bit is already set properly. */
724+ return 0 ;
725+ }
726+
727+ status_reg ^= oe_bit ;
728+
729+ /* Use special Write status register 2 instruction to clear the bit. */
730+ op_code = (status_reg & oe_bit ) ? SPI_NOR_CMD_WRSR2 : 0x3E ;
731+ rc = cmd_wrsr (dev , op_code , 1 , & status_reg );
624732 if (rc < 0 ) {
625- LOG_ERR ("Failed waiting until device ready after enabling quad: %d" , rc );
626733 return rc ;
627734 }
628735
@@ -659,18 +766,26 @@ static int switch_to_target_io_mode(const struct device *dev)
659766 int rc = 0 ;
660767
661768 if (dev_data -> switch_info .quad_enable_req != JESD216_DW15_QER_VAL_NONE ) {
662- /* For Quad 1-1-4 and 1-4-4, entering or leaving mode is defined
663- * in JEDEC216 BFP DW15 QER
664- */
665- if (io_mode == MSPI_IO_MODE_SINGLE ) {
666- rc = quad_enable_set (dev , false);
667- } else if (io_mode == MSPI_IO_MODE_QUAD_1_1_4 ||
668- io_mode == MSPI_IO_MODE_QUAD_1_4_4 ) {
669- rc = quad_enable_set (dev , true);
670- }
769+ bool quad_needed = io_mode == MSPI_IO_MODE_QUAD_1_1_4 ||
770+ io_mode == MSPI_IO_MODE_QUAD_1_4_4 ||
771+ io_mode == MSPI_IO_MODE_QUAD ;
671772
773+ rc = quad_enable_set (dev , quad_needed );
672774 if (rc < 0 ) {
673775 LOG_ERR ("Failed to modify Quad Enable bit: %d" , rc );
776+ return rc ;
777+ }
778+ }
779+
780+ if (dev_data -> switch_info .octal_enable_req != BFP_DW19_OER_VAL_NONE ) {
781+ bool octal_needed = io_mode == MSPI_IO_MODE_OCTAL_1_1_8 ||
782+ io_mode == MSPI_IO_MODE_OCTAL_1_8_8 ||
783+ io_mode == MSPI_IO_MODE_OCTAL ;
784+
785+ rc = octal_enable_set (dev , octal_needed );
786+ if (rc < 0 ) {
787+ LOG_ERR ("Failed to modify Octal Enable bit: %d" , rc );
788+ return rc ;
674789 }
675790 }
676791
0 commit comments