16
16
#include <zephyr/kernel.h>
17
17
#include <zephyr/device.h>
18
18
#include <zephyr/drivers/cache.h>
19
+ #include <zephyr/drivers/flash/andes_flash_xip_api_ex.h>
19
20
#include <zephyr/drivers/flash.h>
20
21
#include <zephyr/init.h>
21
22
#include <zephyr/logging/log.h>
@@ -100,10 +101,21 @@ struct flash_andes_qspi_xip_config {
100
101
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
101
102
};
102
103
104
+ struct flash_andes_qspi_xip_data {
105
+ #ifdef CONFIG_FLASH_EX_OP_ENABLED
106
+ /* Lock of the status registers. */
107
+ bool status_lock ;
108
+ #endif
109
+ };
110
+
103
111
#define flash_andes_qspi_xip_cmd_read (dev , opcode , dest , length ) \
104
112
flash_andes_qspi_xip_access(dev, opcode, 0, 0, dest, length)
113
+ #define flash_andes_qspi_xip_cmd_write_data (dev , opcode , src , length ) \
114
+ flash_andes_qspi_xip_access(dev, opcode, ANDES_ACCESS_WRITE, 0, src, length)
105
115
#define flash_andes_qspi_xip_cmd_write (dev , opcode ) \
106
116
flash_andes_qspi_xip_access(dev, opcode, ANDES_ACCESS_WRITE, 0, NULL, 0)
117
+ #define flash_andes_qspi_xip_cmd_addr_read (dev , opcode , addr , dest , length ) \
118
+ flash_andes_qspi_xip_access(dev, opcode, ANDES_ACCESS_ADDRESSED, addr, dest, length)
107
119
#define flash_andes_qspi_xip_cmd_addr_write (dev , opcode , addr , src , length ) \
108
120
flash_andes_qspi_xip_access(dev, opcode, ANDES_ACCESS_WRITE | ANDES_ACCESS_ADDRESSED, \
109
121
addr, (void *)src, length)
@@ -486,6 +498,236 @@ static void flash_andes_qspi_xip_pages_layout(const struct device *dev,
486
498
}
487
499
#endif
488
500
501
+ #ifdef CONFIG_FLASH_EX_OP_ENABLED
502
+ static __ramfunc int flash_andes_qspi_xip_get_status (const struct device * dev ,
503
+ struct andes_xip_ex_ops_get_out * op_out )
504
+ {
505
+ int ret = 0 ;
506
+
507
+ prepare_for_flashing (dev );
508
+
509
+ ret = flash_andes_qspi_xip_cmd_read (dev , SPI_NOR_CMD_RDSR , & op_out -> regs [0 ], 1 );
510
+ if (ret ) {
511
+ goto cleanup ;
512
+ }
513
+
514
+ ret = flash_andes_qspi_xip_cmd_read (dev , SPI_NOR_CMD_RDSR2 , & op_out -> regs [1 ], 1 );
515
+ if (ret ) {
516
+ goto cleanup ;
517
+ }
518
+
519
+ ret = flash_andes_qspi_xip_cmd_read (dev , SPI_NOR_CMD_RDSR3 , & op_out -> regs [2 ], 1 );
520
+
521
+ cleanup :
522
+ cleanup_after_flashing (dev , 0 , 0 );
523
+
524
+ return ret ;
525
+ }
526
+
527
+ static __ramfunc int write_status_register (const struct device * dev , uint8_t sr , uint8_t mask ,
528
+ uint8_t op_read , uint8_t op_write )
529
+ {
530
+ uint8_t sr_curr ;
531
+ uint8_t sr_new ;
532
+ int ret , ret2 = 0 ;
533
+
534
+ if (!mask ) {
535
+ return 0 ;
536
+ }
537
+
538
+ ret = flash_andes_qspi_xip_cmd_read (dev , op_read , & sr_curr , 1 );
539
+ if (ret ) {
540
+ return ret ;
541
+ }
542
+ sr_new = (sr_curr & ~mask ) | sr ;
543
+ if (sr_new != sr_curr ) {
544
+ ret = write_protection_set (dev , false);
545
+ if (ret != 0 ) {
546
+ return ret ;
547
+ }
548
+ ret = flash_andes_qspi_xip_cmd_write_data (dev , op_write , & sr_new , 1 );
549
+ ret2 = flash_andes_qspi_xip_wait_until_ready (dev );
550
+ }
551
+
552
+ if (!ret ) {
553
+ ret = ret2 ;
554
+ }
555
+
556
+ return ret ;
557
+ }
558
+
559
+ static __ramfunc int flash_andes_qspi_xip_set_status (const struct device * dev ,
560
+ struct andes_xip_ex_ops_set_in * op_out )
561
+ {
562
+ int ret ;
563
+ struct flash_andes_qspi_xip_data * data = dev -> data ;
564
+
565
+ if (data -> status_lock ) {
566
+ return - EPERM ;
567
+ }
568
+
569
+ prepare_for_flashing (dev );
570
+
571
+ ret = write_status_register (dev , op_out -> regs [0 ], op_out -> masks [0 ], SPI_NOR_CMD_RDSR ,
572
+ SPI_NOR_CMD_WRSR );
573
+ if (ret ) {
574
+ goto cleanup ;
575
+ }
576
+
577
+ ret = write_status_register (dev , op_out -> regs [1 ], op_out -> masks [1 ], SPI_NOR_CMD_RDSR2 ,
578
+ SPI_NOR_CMD_WRSR2 );
579
+ if (ret ) {
580
+ goto cleanup ;
581
+ }
582
+
583
+ ret = write_status_register (dev , op_out -> regs [2 ], op_out -> masks [2 ], SPI_NOR_CMD_RDSR3 ,
584
+ SPI_NOR_CMD_WRSR3 );
585
+
586
+ cleanup :
587
+ cleanup_after_flashing (dev , 0 , 0 );
588
+
589
+ return ret ;
590
+ }
591
+
592
+ static __ramfunc int flash_andes_qspi_xip_lock (const struct device * dev ,
593
+ struct andes_xip_ex_ops_lock_in * op_in )
594
+ {
595
+ struct flash_andes_qspi_xip_data * data = dev -> data ;
596
+
597
+ data -> status_lock = op_in -> enable ;
598
+
599
+ return 0 ;
600
+ }
601
+
602
+ static __ramfunc int flash_andes_qspi_xip_lock_state (const struct device * dev ,
603
+ struct andes_xip_ex_ops_lock_state_out * op_out )
604
+ {
605
+ struct flash_andes_qspi_xip_data * data = dev -> data ;
606
+
607
+ op_out -> state = data -> status_lock ;
608
+
609
+ return 0 ;
610
+ }
611
+
612
+ static __ramfunc int
613
+ flash_andes_qspi_xip_set_memrdcmd (const struct device * dev ,
614
+ struct andes_xip_ex_ops_mem_read_cmd_in * op_in )
615
+ {
616
+ const struct flash_andes_qspi_xip_config * config = dev -> config ;
617
+ struct atcspi200_regs * regs = config -> regs ;
618
+
619
+ prepare_for_flashing (dev );
620
+
621
+ regs -> MEMCTRL = (uint32_t )op_in -> cmd ;
622
+ while (regs -> MEMCTRL & MEMCTRL_CHG ) {
623
+ }
624
+
625
+ cleanup_after_flashing (dev , 0 , 0 );
626
+
627
+ return 0 ;
628
+ }
629
+
630
+ static int flash_andes_qspi_xip_ex_op (const struct device * dev , uint16_t code , const uintptr_t in ,
631
+ void * out )
632
+ {
633
+ #ifdef CONFIG_USERSPACE
634
+ bool syscall_trap = z_syscall_trap ();
635
+ #endif
636
+ int key , ret ;
637
+
638
+ switch (code ) {
639
+ case FLASH_ANDES_XIP_EX_OP_GET_STATUS_REGS : {
640
+ struct andes_xip_ex_ops_get_out * op_out = (struct andes_xip_ex_ops_get_out * )out ;
641
+ #ifdef CONFIG_USERSPACE
642
+ struct andes_xip_ex_ops_get_out copy_out ;
643
+
644
+ if (syscall_trap ) {
645
+ op_out = & copy_out ;
646
+ }
647
+ #endif
648
+ key = prepare_for_ramfunc ();
649
+ ret = flash_andes_qspi_xip_get_status (dev , op_out );
650
+ cleanup_after_ramfunc (key );
651
+ #ifdef CONFIG_USERSPACE
652
+ if (ret == 0 && syscall_trap ) {
653
+ K_OOPS (k_usermode_to_copy (out , op_out , sizeof (copy_out )));
654
+ }
655
+ #endif
656
+ break ;
657
+ }
658
+ case FLASH_ANDES_XIP_EX_OP_SET_STATUS_REGS : {
659
+ struct andes_xip_ex_ops_set_in * op_in = (struct andes_xip_ex_ops_set_in * )in ;
660
+ #ifdef CONFIG_USERSPACE
661
+ struct andes_xip_ex_ops_set_in copy_in ;
662
+
663
+ if (syscall_trap ) {
664
+ K_OOPS (k_usermode_from_copy (& copy_in , op_in , sizeof (copy_in )));
665
+ op_in = & copy_in ;
666
+ }
667
+ #endif
668
+ key = prepare_for_ramfunc ();
669
+ ret = flash_andes_qspi_xip_set_status (dev , op_in );
670
+ cleanup_after_ramfunc (key );
671
+ break ;
672
+ }
673
+ case FLASH_ANDES_XIP_EX_OP_LOCK : {
674
+ struct andes_xip_ex_ops_lock_in * op_in = (struct andes_xip_ex_ops_lock_in * )in ;
675
+ #ifdef CONFIG_USERSPACE
676
+ struct andes_xip_ex_ops_lock_in copy_in ;
677
+
678
+ if (syscall_trap ) {
679
+ K_OOPS (k_usermode_from_copy (& copy_in , op_in , sizeof (copy_in )));
680
+ op_in = & copy_in ;
681
+ }
682
+ #endif
683
+ ret = flash_andes_qspi_xip_lock (dev , op_in );
684
+ break ;
685
+ }
686
+ case FLASH_ANDES_XIP_EX_OP_LOCK_STATE : {
687
+ struct andes_xip_ex_ops_lock_state_out * op_out =
688
+ (struct andes_xip_ex_ops_lock_state_out * )out ;
689
+ #ifdef CONFIG_USERSPACE
690
+ struct andes_xip_ex_ops_lock_state_out copy_out ;
691
+
692
+ if (syscall_trap ) {
693
+ op_out = & copy_out ;
694
+ }
695
+ #endif
696
+ key = prepare_for_ramfunc ();
697
+ ret = flash_andes_qspi_xip_lock_state (dev , op_out );
698
+ cleanup_after_ramfunc (key );
699
+ #ifdef CONFIG_USERSPACE
700
+ if (ret == 0 && syscall_trap ) {
701
+ K_OOPS (k_usermode_to_copy (out , op_out , sizeof (copy_out )));
702
+ }
703
+ #endif
704
+ break ;
705
+ }
706
+ case FLASH_ANDES_XIP_EX_OP_MEM_READ_CMD : {
707
+ struct andes_xip_ex_ops_mem_read_cmd_in * op_in =
708
+ (struct andes_xip_ex_ops_mem_read_cmd_in * )in ;
709
+ #ifdef CONFIG_USERSPACE
710
+ struct andes_xip_ex_ops_mem_read_cmd_in copy_in ;
711
+
712
+ if (syscall_trap ) {
713
+ K_OOPS (k_usermode_from_copy (& copy_in , op_in , sizeof (copy_in )));
714
+ op_in = & copy_in ;
715
+ }
716
+ #endif
717
+ key = prepare_for_ramfunc ();
718
+ ret = flash_andes_qspi_xip_set_memrdcmd (dev , op_in );
719
+ cleanup_after_ramfunc (key );
720
+ break ;
721
+ }
722
+ default :
723
+ ret = - ENOTSUP ;
724
+ break ;
725
+ }
726
+
727
+ return ret ;
728
+ }
729
+ #endif
730
+
489
731
static DEVICE_API (flash , flash_andes_qspi_xip_api ) = {
490
732
.read = flash_andes_qspi_xip_read ,
491
733
.write = flash_andes_qspi_xip_write ,
@@ -494,6 +736,9 @@ static DEVICE_API(flash, flash_andes_qspi_xip_api) = {
494
736
#if defined(CONFIG_FLASH_PAGE_LAYOUT )
495
737
.page_layout = flash_andes_qspi_xip_pages_layout ,
496
738
#endif
739
+ #ifdef CONFIG_FLASH_EX_OP_ENABLED
740
+ .ex_op = flash_andes_qspi_xip_ex_op ,
741
+ #endif
497
742
};
498
743
499
744
#define IS_XIP (node_id ) DT_SAME_NODE(node_id, DT_CHOSEN(zephyr_flash))
@@ -517,7 +762,9 @@ static DEVICE_API(flash, flash_andes_qspi_xip_api) = {
517
762
.flash_size = DT_INST_PROP(n, size), \
518
763
LAYOUT_PAGES_PROP(n)}; \
519
764
\
520
- DEVICE_DT_INST_DEFINE(n, &flash_andes_qspi_xip_init, NULL, NULL, \
765
+ static struct flash_andes_qspi_xip_data flash_andes_qspi_xip_data_##n; \
766
+ \
767
+ DEVICE_DT_INST_DEFINE(n, &flash_andes_qspi_xip_init, NULL, &flash_andes_qspi_xip_data_##n, \
521
768
&flash_andes_qspi_xip_config_##n, POST_KERNEL, \
522
769
CONFIG_FLASH_ANDES_QSPI_INIT_PRIORITY, &flash_andes_qspi_xip_api);
523
770
0 commit comments