File indexing completed on 2025-05-11 08:24:00
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 #include <stdint.h>
0060 #include <stddef.h>
0061 #include <string.h>
0062 #include <errno.h>
0063 #include <altera_avalon_epcq_regs.h>
0064 #include <altera_avalon_timer_regs.h>
0065
0066 #include <rtems/counter.h>
0067
0068 #ifndef ALT_MAX_NUMBER_OF_FLASH_REGIONS
0069 #define ALT_MAX_NUMBER_OF_FLASH_REGIONS 8
0070 #endif
0071
0072
0073 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
0074
0075
0076
0077
0078 typedef struct flash_region
0079 {
0080 int offset;
0081 int region_size;
0082 int number_of_blocks;
0083 int block_size;
0084 }flash_region;
0085
0086
0087
0088
0089 typedef struct alt_flash_dev alt_flash_dev;
0090
0091
0092
0093
0094 typedef int (*alt_flash_read)(
0095 alt_flash_dev* flash,
0096 int offset,
0097 void* dest_addr,
0098 int length
0099 );
0100
0101
0102
0103
0104 struct alt_flash_dev
0105 {
0106 const char* name;
0107 alt_flash_read read;
0108 void* base_addr;
0109 int length;
0110 int number_of_regions;
0111 flash_region region_info[ALT_MAX_NUMBER_OF_FLASH_REGIONS];
0112 };
0113
0114
0115
0116
0117
0118 typedef struct alt_epcq_controller2_dev
0119 {
0120 alt_flash_dev dev;
0121
0122 uint32_t data_base;
0123 uint32_t data_end;
0124 uint32_t csr_base;
0125 uint32_t size_in_bytes;
0126 uint32_t is_epcs;
0127 uint32_t number_of_sectors;
0128 uint32_t sector_size;
0129 uint32_t page_size;
0130 uint32_t silicon_id;
0131 } alt_epcq_controller2_dev;
0132
0133 static int altera_epcq_controller2_init(alt_epcq_controller2_dev *dev);
0134 static int alt_epcq_controller2_erase_block(
0135 alt_flash_dev *flash_info,
0136 int block_offset
0137 );
0138 static int alt_epcq_controller2_write_block(
0139 alt_flash_dev *flash_info,
0140 int block_offset,
0141 int data_offset,
0142 const void *data, int length
0143 );
0144 static int alt_epcq_controller2_write(
0145 alt_flash_dev *flash_info,
0146 int offset,
0147 const void *src_addr,
0148 int length,
0149 bool erase
0150 );
0151 static int alt_epcq_controller2_read(
0152 alt_flash_dev *flash_info,
0153 int offset,
0154 void *dest_addr,
0155 int length
0156 );
0157 static inline int alt_epcq_validate_read_write_arguments(
0158 alt_epcq_controller2_dev *flash_info,
0159 uint32_t offset,
0160 uint32_t length
0161 );
0162 static int alt_epcq_poll_for_write_in_progress(
0163 alt_epcq_controller2_dev* flash_info
0164 );
0165
0166
0167
0168
0169 #define ALTERA_EPCQ_CSR_INSTANCE(epcq_name, avl_mem, avl_csr, epcq_dev) \
0170 static alt_epcq_controller2_dev epcq_dev = { \
0171 .dev = { \
0172 .read = alt_epcq_controller2_read, \
0173 .base_addr = ((void*)(avl_mem##_BASE)), \
0174 .length = ((int)(avl_mem##_SPAN)), \
0175 }, \
0176 .data_base = ((uint32_t)(avl_mem##_BASE)), \
0177 .data_end = ((uint32_t)(avl_mem##_BASE) + (uint32_t)(avl_mem##_SPAN)), \
0178 .csr_base = ((uint32_t)(avl_csr##_BASE)), \
0179 .size_in_bytes = ((uint32_t)(avl_mem##_SPAN)), \
0180 .is_epcs = ((uint32_t)(avl_mem##_IS_EPCS)), \
0181 .number_of_sectors = ((uint32_t)(avl_mem##_NUMBER_OF_SECTORS)), \
0182 .sector_size = ((uint32_t)(avl_mem##_SECTOR_SIZE)), \
0183 .page_size = ((uint32_t)(avl_mem##_PAGE_SIZE)) , \
0184 }
0185
0186 #define ALTERA_EPCQ_CONTROLLER2_INIT(name, dev) \
0187 altera_epcq_controller2_init(&dev);
0188
0189
0190
0191
0192 ALTERA_EPCQ_CSR_INSTANCE(
0193 EPCQ_CONTROLLER,
0194 EPCQ_CONTROLLER_AVL_MEM,
0195 EPCQ_CONTROLLER_AVL_CSR,
0196 epcq_controller
0197 );
0198
0199
0200
0201
0202
0203
0204
0205 void epcq_initialize( void )
0206 {
0207 ALTERA_EPCQ_CONTROLLER2_INIT( EPCQ_CONTROLLER, epcq_controller);
0208 }
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224 int epcq_read_buffer( int offset, uint8_t *dest_addr, int length )
0225 {
0226 return alt_epcq_controller2_read(
0227 &epcq_controller.dev,
0228 offset,
0229 dest_addr,
0230 length
0231 );
0232 }
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248 int epcq_write_buffer (
0249 int offset,
0250 const uint8_t* src_addr,
0251 int length,
0252 bool erase
0253 )
0254 {
0255 return alt_epcq_controller2_write (
0256 &epcq_controller.dev,
0257 offset,
0258 src_addr,
0259 length,
0260 erase
0261 );
0262 }
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280 static int altera_epcq_controller2_init(alt_epcq_controller2_dev *flash)
0281 {
0282 uint32_t silicon_id = 0;
0283 uint32_t size_in_bytes = 0;
0284 uint32_t number_of_sectors = 0;
0285
0286
0287 if ( NULL == flash ) {
0288 return -EINVAL;
0289 }
0290
0291
0292 if ( NULL == ( void * )flash->csr_base ) {
0293 return -ENODEV;
0294 }
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308 if ( 0 == flash->is_epcs ) {
0309
0310 silicon_id = EPCQ_REGS->rd_rdid;
0311 silicon_id &= ALTERA_EPCQ_CONTROLLER2_RDID_MASK;
0312
0313
0314
0315 switch( silicon_id ) {
0316 case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ16:
0317 number_of_sectors = 32;
0318 break;
0319 case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ32:
0320 number_of_sectors = 64;
0321 break;
0322 case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ64:
0323 number_of_sectors = 128;
0324 break;
0325 case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ128:
0326 number_of_sectors = 256;
0327 break;
0328 case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ256:
0329 number_of_sectors = 512;
0330 break;
0331 case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ512:
0332 number_of_sectors = 1024;
0333 break;
0334 case ALTERA_EPCQ_CONTROLLER2_RDID_EPCQ1024:
0335 number_of_sectors = 2048;
0336 break;
0337 default:
0338 return -ENODEV;
0339 }
0340 } else {
0341
0342 silicon_id = EPCQ_REGS->rd_sid;
0343 silicon_id &= ALTERA_EPCQ_CONTROLLER2_SID_MASK;
0344
0345
0346 switch(silicon_id) {
0347 case ALTERA_EPCQ_CONTROLLER2_SID_EPCS16:
0348 number_of_sectors = 32;
0349 break;
0350 case ALTERA_EPCQ_CONTROLLER2_SID_EPCS64:
0351 number_of_sectors = 128;
0352 break;
0353 case ALTERA_EPCQ_CONTROLLER2_SID_EPCS128:
0354 number_of_sectors = 256;
0355 break;
0356 default:
0357 return -ENODEV;
0358 }
0359 }
0360
0361
0362 size_in_bytes = number_of_sectors * flash->sector_size;
0363
0364
0365
0366
0367
0368
0369 if (
0370 size_in_bytes != flash->size_in_bytes ||
0371 number_of_sectors != flash->number_of_sectors
0372 ) {
0373 flash->dev.number_of_regions = 0;
0374 return -ENODEV;
0375 } else {
0376 flash->silicon_id = silicon_id;
0377 flash->number_of_sectors = number_of_sectors;
0378
0379
0380
0381
0382
0383 flash->dev.number_of_regions = 1;
0384 flash->dev.region_info[0].offset = 0;
0385 flash->dev.region_info[0].region_size = size_in_bytes;
0386 flash->dev.region_info[0].number_of_blocks = number_of_sectors;
0387 flash->dev.region_info[0].block_size = flash->sector_size;
0388 }
0389
0390 return 0;
0391 }
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408 static int alt_epcq_controller2_erase_block(
0409 alt_flash_dev *flash_info,
0410 int block_offset
0411 )
0412 {
0413 int32_t ret_code = 0;
0414 uint32_t mem_op_value = 0;
0415 alt_epcq_controller2_dev* epcq_flash_info = NULL;
0416 uint32_t sector_number = 0;
0417
0418
0419 if ( NULL == flash_info ) {
0420 return -EINVAL;
0421 }
0422
0423 epcq_flash_info = (alt_epcq_controller2_dev*)flash_info;
0424
0425
0426
0427
0428
0429
0430 if (
0431 ( block_offset < 0 ) ||
0432 ( block_offset >= epcq_flash_info->size_in_bytes ) ||
0433 ( block_offset & ( epcq_flash_info->sector_size - 1 )) != 0
0434 ) {
0435 return -EINVAL;
0436 }
0437
0438 alt_epcq_poll_for_write_in_progress(epcq_flash_info);
0439
0440
0441 sector_number = (block_offset/(epcq_flash_info->sector_size));
0442
0443
0444 mem_op_value = (sector_number << 8) &
0445 ALTERA_EPCQ_CONTROLLER2_MEM_OP_SECTOR_VALUE_MASK;
0446
0447
0448 mem_op_value |= ALTERA_EPCQ_CONTROLLER2_MEM_OP_WRITE_ENABLE_CMD;
0449
0450
0451
0452
0453
0454 EPCQ_REGS->mem_op = mem_op_value;
0455
0456
0457 mem_op_value = (sector_number << 8) &
0458 ALTERA_EPCQ_CONTROLLER2_MEM_OP_SECTOR_VALUE_MASK;
0459
0460
0461 mem_op_value |= ALTERA_EPCQ_CONTROLLER2_MEM_OP_SECTOR_ERASE_CMD;
0462
0463
0464
0465
0466
0467 EPCQ_REGS->mem_op = mem_op_value;
0468
0469 alt_epcq_poll_for_write_in_progress(epcq_flash_info);
0470
0471
0472 if (
0473 ( EPCQ_REGS->isr & ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_ERASE_MASK ) ==
0474 ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_ERASE_ACTIVE
0475 ) {
0476
0477
0478 EPCQ_REGS->isr = ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_ERASE_MASK;
0479 return -EIO;
0480 }
0481
0482 return ret_code;
0483 }
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508 static int alt_epcq_controller2_write_block (
0509 alt_flash_dev *flash_info,
0510 int block_offset,
0511 int data_offset,
0512 const void *data,
0513 int length
0514 )
0515 {
0516 uint32_t buffer_offset = 0;
0517 uint32_t remaining_length = length;
0518 uint32_t write_offset = data_offset;
0519 uint32_t write_offset_32;
0520
0521 alt_epcq_controller2_dev *epcq_flash_info =
0522 (alt_epcq_controller2_dev*)flash_info;
0523
0524
0525
0526
0527
0528
0529 if (
0530 block_offset < 0 ||
0531 data_offset < 0 ||
0532 NULL == flash_info ||
0533 NULL == data ||
0534 data_offset >= epcq_flash_info->size_in_bytes ||
0535 block_offset >= epcq_flash_info->size_in_bytes ||
0536 length > (epcq_flash_info->sector_size - (data_offset - block_offset)) ||
0537 length < 0 ||
0538 (block_offset & (epcq_flash_info->sector_size - 1)) != 0
0539 ) {
0540 return -EINVAL;
0541 }
0542
0543
0544
0545
0546
0547
0548 while ( remaining_length > 0 ) {
0549 volatile uint32_t dummy_read;
0550
0551 uint32_t word_to_write = 0xFFFFFFFF;
0552
0553 uint32_t padding = 0;
0554
0555 uint32_t bytes_to_copy = sizeof(uint32_t);
0556
0557
0558
0559
0560
0561 if ( 0 != ( write_offset & ( sizeof( uint32_t ) - 1 ))) {
0562
0563
0564
0565
0566 padding = write_offset & (sizeof(uint32_t) - 1);
0567
0568
0569 bytes_to_copy -= padding;
0570
0571 if(bytes_to_copy > remaining_length) {
0572 bytes_to_copy = remaining_length;
0573 }
0574
0575 write_offset = write_offset - padding;
0576 if ( 0 != ( write_offset & ( sizeof( uint32_t ) - 1 ))) {
0577 return -EINVAL;
0578 }
0579 } else {
0580 if ( bytes_to_copy > remaining_length ) {
0581 bytes_to_copy = remaining_length;
0582 }
0583 }
0584
0585
0586 memcpy (
0587 ((( void * )&word_to_write)) + padding,
0588 (( void * )data) + buffer_offset,
0589 bytes_to_copy
0590 );
0591
0592
0593 buffer_offset += bytes_to_copy;
0594 remaining_length -= bytes_to_copy;
0595
0596
0597 write_offset_32 = write_offset >> 2;
0598 EPCQ_MEM_32[write_offset_32] = word_to_write;
0599 alt_epcq_poll_for_write_in_progress(epcq_flash_info);
0600 if ( EPCQ_MEM_32[write_offset_32] != word_to_write ) {
0601 EPCQ_MEM_32[write_offset_32] = word_to_write;
0602 alt_epcq_poll_for_write_in_progress(epcq_flash_info);
0603 dummy_read = EPCQ_MEM_32[write_offset_32];
0604 }
0605
0606
0607 if (
0608 ( EPCQ_REGS->isr & ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_WRITE_MASK ) ==
0609 ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_WRITE_ACTIVE
0610 ) {
0611
0612 EPCQ_REGS->isr = ALTERA_EPCQ_CONTROLLER2_ISR_ILLEGAL_WRITE_MASK;
0613 return -EIO;
0614 }
0615
0616
0617 write_offset = write_offset + sizeof(uint32_t);
0618 }
0619
0620 return 0;
0621 }
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645 static int alt_epcq_controller2_write (
0646 alt_flash_dev *flash_info,
0647 int offset,
0648 const void *src_addr,
0649 int length,
0650 bool erase
0651 )
0652 {
0653 int32_t ret_code = 0;
0654
0655 alt_epcq_controller2_dev *epcq_flash_info = NULL;
0656
0657
0658 uint32_t write_offset = offset;
0659
0660 uint32_t remaining_length = length;
0661
0662 uint32_t buffer_offset = 0;
0663 uint32_t i = 0;
0664
0665
0666 if( NULL == flash_info || NULL == src_addr ) {
0667 return -EINVAL;
0668 }
0669
0670 epcq_flash_info = (alt_epcq_controller2_dev*)flash_info;
0671
0672
0673 ret_code = alt_epcq_validate_read_write_arguments (
0674 epcq_flash_info,
0675 offset,
0676 length
0677 );
0678
0679 if ( 0 != ret_code ) {
0680 return ret_code;
0681 }
0682
0683
0684
0685
0686
0687 for (
0688 i = offset / epcq_flash_info->sector_size;
0689 i < epcq_flash_info->number_of_sectors;
0690 i++
0691 ) {
0692
0693 uint32_t block_offset = 0;
0694
0695 uint32_t offset_within_current_sector = 0;
0696
0697 uint32_t length_to_write = 0;
0698
0699 if( 0 >= remaining_length ) {
0700 break;
0701 }
0702
0703
0704 block_offset = write_offset & ~(epcq_flash_info->sector_size - 1);
0705
0706
0707 if ( block_offset != write_offset ) {
0708 offset_within_current_sector = write_offset - block_offset;
0709 }
0710
0711
0712 if( erase ) {
0713 ret_code = alt_epcq_controller2_erase_block(flash_info, block_offset);
0714
0715 if( 0 != ret_code ) {
0716 return ret_code;
0717 }
0718 }
0719
0720
0721 length_to_write = MIN (
0722 epcq_flash_info->sector_size - offset_within_current_sector,
0723 remaining_length
0724 );
0725
0726
0727 ret_code = alt_epcq_controller2_write_block (
0728 flash_info,
0729 block_offset,
0730 write_offset,
0731 src_addr + buffer_offset,
0732 length_to_write
0733 );
0734
0735 if( 0 != ret_code ) {
0736 return ret_code;
0737 }
0738
0739
0740 remaining_length -= length_to_write;
0741 buffer_offset += length_to_write;
0742 write_offset += length_to_write;
0743 }
0744
0745 return ret_code;
0746 }
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764 static int alt_epcq_controller2_read (
0765 alt_flash_dev *flash_info,
0766 int offset,
0767 void *dest_addr,
0768 int length
0769 )
0770 {
0771 int32_t ret_code = 0;
0772 alt_epcq_controller2_dev *epcq_flash_info = NULL;
0773
0774
0775 if ( NULL == flash_info || NULL == dest_addr ) {
0776 return -EINVAL;
0777 }
0778
0779 epcq_flash_info = (alt_epcq_controller2_dev*)flash_info;
0780
0781
0782 ret_code = alt_epcq_validate_read_write_arguments (
0783 epcq_flash_info,
0784 offset,
0785 length
0786 );
0787
0788
0789 if( 0 == ret_code ) {
0790 memcpy(dest_addr, (uint8_t*)epcq_flash_info->data_base + offset, length);
0791 }
0792
0793 return ret_code;
0794 }
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811 static inline int alt_epcq_validate_read_write_arguments (
0812 alt_epcq_controller2_dev *flash_info,
0813 uint32_t offset,
0814 uint32_t length
0815 )
0816 {
0817 alt_epcq_controller2_dev *epcq_flash_info = NULL;
0818 uint32_t start_address = 0;
0819 int32_t end_address = 0;
0820
0821
0822 if( NULL == flash_info ) {
0823 return -EINVAL;
0824 }
0825
0826 epcq_flash_info = (alt_epcq_controller2_dev*)flash_info;
0827
0828
0829 start_address = epcq_flash_info->data_base + offset;
0830
0831 end_address = start_address + length;
0832
0833
0834 if (
0835 start_address >= epcq_flash_info->data_end ||
0836 end_address > epcq_flash_info->data_end ||
0837 offset < 0 ||
0838 length < 0
0839 ) {
0840 return -EINVAL;
0841 }
0842
0843 return 0;
0844 }
0845
0846
0847
0848
0849
0850
0851
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868
0869 int static alt_epcq_poll_for_write_in_progress (
0870 alt_epcq_controller2_dev* epcq_flash_info
0871 )
0872 {
0873
0874 #if ALTERA_EPCQ_CONTROLLER2_1US_TIMEOUT_VALUE > 0
0875 uint32_t timeout = ALTERA_EPCQ_CONTROLLER2_1US_TIMEOUT_VALUE;
0876 uint16_t counter = 0;
0877 #endif
0878
0879
0880 if ( NULL == epcq_flash_info ) {
0881 return -EINVAL;
0882 }
0883
0884
0885 while (
0886 (EPCQ_REGS->rd_status & ALTERA_EPCQ_CONTROLLER2_STATUS_WIP_MASK) ==
0887 ALTERA_EPCQ_CONTROLLER2_STATUS_WIP_BUSY
0888 ) {
0889 if ( counter > (ALTERA_EPCQ_CONTROLLER2_1US_TIMEOUT_VALUE >> 1 )) {
0890 rtems_counter_delay_ticks(2);
0891 }
0892 #if ALTERA_EPCQ_CONTROLLER2_1US_TIMEOUT_VALUE > 0
0893 if ( timeout <= counter ) {
0894 return -ETIME;
0895 }
0896
0897 counter++;
0898 #endif
0899 }
0900
0901 return 0;
0902 }