@@ -638,31 +638,138 @@ static int dev_pm_action_cb(const struct device *dev,
638638static int quad_enable_set (const struct device * dev , bool enable )
639639{
640640 struct flash_mspi_nor_data * dev_data = dev -> data ;
641+ uint8_t op_code ;
642+ uint8_t qe_bit ;
643+ uint8_t status_reg ;
644+ uint8_t payload_len ;
645+ uint8_t payload [2 ];
641646 int rc ;
642647
643- rc = cmd_wren (dev );
648+ switch (dev_data -> switch_info .quad_enable_req ) {
649+ case JESD216_DW15_QER_VAL_S1B6 :
650+ op_code = SPI_NOR_CMD_RDSR ;
651+ qe_bit = BIT (6 );
652+ break ;
653+ case JESD216_DW15_QER_VAL_S2B7 :
654+ /* Use special Read status register 2 instruction. */
655+ op_code = 0x3F ;
656+ qe_bit = BIT (7 );
657+ break ;
658+ case JESD216_DW15_QER_VAL_S2B1v1 :
659+ case JESD216_DW15_QER_VAL_S2B1v4 :
660+ case JESD216_DW15_QER_VAL_S2B1v5 :
661+ case JESD216_DW15_QER_VAL_S2B1v6 :
662+ op_code = SPI_NOR_CMD_RDSR2 ;
663+ qe_bit = BIT (1 );
664+ break ;
665+ default :
666+ LOG_ERR ("Unknown Quad Enable Requirement: %u" ,
667+ dev_data -> switch_info .quad_enable_req );
668+ return - ENOTSUP ;
669+ }
670+
671+ rc = cmd_rdsr (dev , op_code , & status_reg );
644672 if (rc < 0 ) {
645- LOG_ERR ("Failed to set write enable: %d" , rc );
646673 return rc ;
647674 }
648675
649- if (dev_data -> switch_info .quad_enable_req == JESD216_DW15_QER_VAL_S1B6 ) {
650- uint8_t mode_payload = enable ? BIT (6 ) : 0 ;
676+ if (((status_reg & qe_bit ) != 0 ) == enable ) {
677+ /* Nothing to do, the QE bit is already set properly. */
678+ return 0 ;
679+ }
680+
681+ status_reg ^= qe_bit ;
682+
683+ switch (dev_data -> switch_info .quad_enable_req ) {
684+ default :
685+ case JESD216_DW15_QER_VAL_S1B6 :
686+ payload_len = 1 ;
687+ op_code = SPI_NOR_CMD_WRSR ;
688+ break ;
689+ case JESD216_DW15_QER_VAL_S2B7 :
690+ payload_len = 1 ;
691+ /* Use special Write status register 2 instruction. */
692+ op_code = 0x3E ;
693+ break ;
694+ case JESD216_DW15_QER_VAL_S2B1v1 :
695+ case JESD216_DW15_QER_VAL_S2B1v4 :
696+ case JESD216_DW15_QER_VAL_S2B1v5 :
697+ payload_len = 2 ;
698+ op_code = SPI_NOR_CMD_WRSR ;
699+ break ;
700+ case JESD216_DW15_QER_VAL_S2B1v6 :
701+ payload_len = 1 ;
702+ op_code = SPI_NOR_CMD_WRSR2 ;
703+ break ;
704+ }
705+
706+ if (payload_len == 1 ) {
707+ payload [0 ] = status_reg ;
708+ } else {
709+ payload [1 ] = status_reg ;
651710
652- rc = cmd_wrsr (dev , SPI_NOR_CMD_WRSR , 1 , & mode_payload );
711+ /* When the Write Status command is to be sent with two data
712+ * bytes (this is the case for S2B1v1, S2B1v4, and S2B1v5 QER
713+ * values), the first status register needs to be read and
714+ * sent as the first byte, so that its value is not modified.
715+ */
716+ rc = cmd_rdsr (dev , SPI_NOR_CMD_RDSR , & payload [0 ]);
653717 if (rc < 0 ) {
654- LOG_ERR ("Failed to enable/disable quad mode: %d" , rc );
655718 return rc ;
656719 }
657- } else {
658- /* TODO: handle all DW15 QER values */
720+ }
721+
722+ rc = cmd_wrsr (dev , op_code , payload_len , payload );
723+ if (rc < 0 ) {
724+ return rc ;
725+ }
726+
727+ return 0 ;
728+ }
729+
730+ static int octal_enable_set (const struct device * dev , bool enable )
731+ {
732+ struct flash_mspi_nor_data * dev_data = dev -> data ;
733+ uint8_t op_code ;
734+ uint8_t oe_bit ;
735+ uint8_t status_reg ;
736+ int rc ;
737+
738+ if (dev_data -> switch_info .octal_enable_req != OCTAL_ENABLE_REQ_S2B3 ) {
739+ LOG_ERR ("Unknown Octal Enable Requirement: %u" ,
740+ dev_data -> switch_info .octal_enable_req );
659741 return - ENOTSUP ;
660742 }
661743
662- rc = wait_until_ready ( dev , K_USEC ( 1 ) );
744+ oe_bit = BIT ( 3 );
663745
746+ /* Use special Read status register 2 instruction 0x65 with one address
747+ * byte 0x02 and one dummy byte.
748+ */
749+ op_code = 0x65 ;
750+ set_up_xfer (dev , MSPI_RX );
751+ dev_data -> xfer .rx_dummy = 8 ;
752+ dev_data -> xfer .addr_length = 1 ;
753+ dev_data -> packet .address = 0x02 ;
754+ dev_data -> packet .num_bytes = sizeof (uint8_t );
755+ dev_data -> packet .data_buf = & status_reg ;
756+ rc = perform_xfer (dev , op_code , false);
757+ if (rc < 0 ) {
758+ LOG_ERR ("cmd_rdsr 0x%02x failed: %d" , op_code , rc );
759+ return rc ;
760+ }
761+
762+ if (((status_reg & oe_bit ) != 0 ) == enable ) {
763+ /* Nothing to do, the OE bit is already set properly. */
764+ return 0 ;
765+ }
766+
767+ status_reg ^= oe_bit ;
768+
769+ /* Use special Write status register 2 instruction to clear the bit. */
770+ op_code = (status_reg & oe_bit ) ? SPI_NOR_CMD_WRSR2 : 0x3E ;
771+ rc = cmd_wrsr (dev , op_code , 1 , & status_reg );
664772 if (rc < 0 ) {
665- LOG_ERR ("Failed waiting until device ready after enabling quad: %d" , rc );
666773 return rc ;
667774 }
668775
@@ -699,18 +806,24 @@ static int switch_to_target_io_mode(const struct device *dev)
699806 int rc = 0 ;
700807
701808 if (dev_data -> switch_info .quad_enable_req != JESD216_DW15_QER_VAL_NONE ) {
702- /* For Quad 1-1-4 and 1-4-4, entering or leaving mode is defined
703- * in JEDEC216 BFP DW15 QER
704- */
705- if (io_mode == MSPI_IO_MODE_SINGLE ) {
706- rc = quad_enable_set (dev , false);
707- } else if (io_mode == MSPI_IO_MODE_QUAD_1_1_4 ||
708- io_mode == MSPI_IO_MODE_QUAD_1_4_4 ) {
709- rc = quad_enable_set (dev , true);
710- }
809+ bool quad_needed = io_mode == MSPI_IO_MODE_QUAD_1_1_4 ||
810+ io_mode == MSPI_IO_MODE_QUAD_1_4_4 ;
711811
812+ rc = quad_enable_set (dev , quad_needed );
712813 if (rc < 0 ) {
713814 LOG_ERR ("Failed to modify Quad Enable bit: %d" , rc );
815+ return rc ;
816+ }
817+ }
818+
819+ if (dev_data -> switch_info .octal_enable_req != OCTAL_ENABLE_REQ_NONE ) {
820+ bool octal_needed = io_mode == MSPI_IO_MODE_OCTAL_1_1_8 ||
821+ io_mode == MSPI_IO_MODE_OCTAL_1_8_8 ;
822+
823+ rc = octal_enable_set (dev , octal_needed );
824+ if (rc < 0 ) {
825+ LOG_ERR ("Failed to modify Octal Enable bit: %d" , rc );
826+ return rc ;
714827 }
715828 }
716829
0 commit comments