@@ -598,31 +598,138 @@ static int dev_pm_action_cb(const struct device *dev,
598
598
static int quad_enable_set (const struct device * dev , bool enable )
599
599
{
600
600
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 ];
601
606
int rc ;
602
607
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 );
604
632
if (rc < 0 ) {
605
- LOG_ERR ("Failed to set write enable: %d" , rc );
606
633
return rc ;
607
634
}
608
635
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 ;
611
670
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 ]);
613
677
if (rc < 0 ) {
614
- LOG_ERR ("Failed to enable/disable quad mode: %d" , rc );
615
678
return rc ;
616
679
}
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 );
619
701
return - ENOTSUP ;
620
702
}
621
703
622
- rc = wait_until_ready ( dev , K_USEC ( 1 ) );
704
+ oe_bit = BIT ( 3 );
623
705
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 );
624
732
if (rc < 0 ) {
625
- LOG_ERR ("Failed waiting until device ready after enabling quad: %d" , rc );
626
733
return rc ;
627
734
}
628
735
@@ -659,18 +766,26 @@ static int switch_to_target_io_mode(const struct device *dev)
659
766
int rc = 0 ;
660
767
661
768
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 ;
671
772
773
+ rc = quad_enable_set (dev , quad_needed );
672
774
if (rc < 0 ) {
673
775
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 ;
674
789
}
675
790
}
676
791
0 commit comments