Commit 96ef831f713289afba19da0c8f905e99da2b23e0
Committed by
Stefan Roese
1 parent
950a392464
Exists in
master
and in
54 other branches
cfi_flash: Support buffered writes on non-standard Spansion NOR flash
Some NOR flash chip from Spansion, for example, the s29ws-n MirrorBit series require different addresses for buffered write commands. Define a configuration option to support buffered writes on those chips. A more elegant solution would be to automatically detect those chips by parsing their CFI records, but that would require introduction of a fixup table into the cfi_flash driver. Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Showing 2 changed files with 23 additions and 30 deletions Side-by-side Diff
README
... | ... | @@ -2040,6 +2040,13 @@ |
2040 | 2040 | This option also enables the building of the cfi_flash driver |
2041 | 2041 | in the drivers directory |
2042 | 2042 | |
2043 | +- CFG_FLASH_USE_BUFFER_WRITE | |
2044 | + Use buffered writes to flash. | |
2045 | + | |
2046 | +- CONFIG_FLASH_SPANSION_S29WS_N | |
2047 | + s29ws-n MirrorBit flash has non-standard addresses for buffered | |
2048 | + write commands. | |
2049 | + | |
2043 | 2050 | - CFG_FLASH_QUIET_TEST |
2044 | 2051 | If this option is defined, the common CFI flash doesn't |
2045 | 2052 | print it's warning upon not recognized FLASH banks. This |
drivers/mtd/cfi_flash.c
... | ... | @@ -844,25 +844,29 @@ |
844 | 844 | void *dst = map_physmem(dest, len, MAP_NOCACHE); |
845 | 845 | void *dst2 = dst; |
846 | 846 | int flag = 0; |
847 | + uint offset = 0; | |
848 | + unsigned int shift; | |
847 | 849 | |
848 | 850 | switch (info->portwidth) { |
849 | 851 | case FLASH_CFI_8BIT: |
850 | - cnt = len; | |
852 | + shift = 0; | |
851 | 853 | break; |
852 | 854 | case FLASH_CFI_16BIT: |
853 | - cnt = len >> 1; | |
855 | + shift = 1; | |
854 | 856 | break; |
855 | 857 | case FLASH_CFI_32BIT: |
856 | - cnt = len >> 2; | |
858 | + shift = 2; | |
857 | 859 | break; |
858 | 860 | case FLASH_CFI_64BIT: |
859 | - cnt = len >> 3; | |
861 | + shift = 3; | |
860 | 862 | break; |
861 | 863 | default: |
862 | 864 | retcode = ERR_INVAL; |
863 | 865 | goto out_unmap; |
864 | 866 | } |
865 | 867 | |
868 | + cnt = len >> shift; | |
869 | + | |
866 | 870 | while ((cnt-- > 0) && (flag == 0)) { |
867 | 871 | switch (info->portwidth) { |
868 | 872 | case FLASH_CFI_8BIT: |
... | ... | @@ -906,23 +910,7 @@ |
906 | 910 | if (retcode == ERR_OK) { |
907 | 911 | /* reduce the number of loops by the width of |
908 | 912 | * the port */ |
909 | - switch (info->portwidth) { | |
910 | - case FLASH_CFI_8BIT: | |
911 | - cnt = len; | |
912 | - break; | |
913 | - case FLASH_CFI_16BIT: | |
914 | - cnt = len >> 1; | |
915 | - break; | |
916 | - case FLASH_CFI_32BIT: | |
917 | - cnt = len >> 2; | |
918 | - break; | |
919 | - case FLASH_CFI_64BIT: | |
920 | - cnt = len >> 3; | |
921 | - break; | |
922 | - default: | |
923 | - retcode = ERR_INVAL; | |
924 | - goto out_unmap; | |
925 | - } | |
913 | + cnt = len >> shift; | |
926 | 914 | flash_write_cmd (info, sector, 0, (uchar) cnt - 1); |
927 | 915 | while (cnt-- > 0) { |
928 | 916 | switch (info->portwidth) { |
929 | 917 | |
930 | 918 | |
931 | 919 | |
932 | 920 | |
933 | 921 | |
... | ... | @@ -959,36 +947,34 @@ |
959 | 947 | case CFI_CMDSET_AMD_STANDARD: |
960 | 948 | case CFI_CMDSET_AMD_EXTENDED: |
961 | 949 | flash_unlock_seq(info,0); |
962 | - flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_TO_BUFFER); | |
963 | 950 | |
951 | +#ifdef CONFIG_FLASH_SPANSION_S29WS_N | |
952 | + offset = ((unsigned long)dst - info->start[sector]) >> shift; | |
953 | +#endif | |
954 | + flash_write_cmd(info, sector, offset, AMD_CMD_WRITE_TO_BUFFER); | |
955 | + cnt = len >> shift; | |
956 | + flash_write_cmd(info, sector, offset, (uchar)cnt - 1); | |
957 | + | |
964 | 958 | switch (info->portwidth) { |
965 | 959 | case FLASH_CFI_8BIT: |
966 | - cnt = len; | |
967 | - flash_write_cmd (info, sector, 0, (uchar) cnt - 1); | |
968 | 960 | while (cnt-- > 0) { |
969 | 961 | flash_write8(flash_read8(src), dst); |
970 | 962 | src += 1, dst += 1; |
971 | 963 | } |
972 | 964 | break; |
973 | 965 | case FLASH_CFI_16BIT: |
974 | - cnt = len >> 1; | |
975 | - flash_write_cmd (info, sector, 0, (uchar) cnt - 1); | |
976 | 966 | while (cnt-- > 0) { |
977 | 967 | flash_write16(flash_read16(src), dst); |
978 | 968 | src += 2, dst += 2; |
979 | 969 | } |
980 | 970 | break; |
981 | 971 | case FLASH_CFI_32BIT: |
982 | - cnt = len >> 2; | |
983 | - flash_write_cmd (info, sector, 0, (uchar) cnt - 1); | |
984 | 972 | while (cnt-- > 0) { |
985 | 973 | flash_write32(flash_read32(src), dst); |
986 | 974 | src += 4, dst += 4; |
987 | 975 | } |
988 | 976 | break; |
989 | 977 | case FLASH_CFI_64BIT: |
990 | - cnt = len >> 3; | |
991 | - flash_write_cmd (info, sector, 0, (uchar) cnt - 1); | |
992 | 978 | while (cnt-- > 0) { |
993 | 979 | flash_write64(flash_read64(src), dst); |
994 | 980 | src += 8, dst += 8; |