1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 Rob Purchase
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "ata-nand-target.h"
31 #define SECTOR_SIZE 512
33 /* ECC on read is implemented on the assumption that MLC-style 4-bit correction
34 is always used regardless of NAND chip type. This assumption is true for at
35 least D2 (MLC) and M200 (SLC). */
36 #define USE_ECC_CORRECTION
38 /* for compatibility */
39 int ata_spinup_time
= 0;
41 long last_disk_activity
= -1;
43 /** static, private data **/
44 static bool initialized
= false;
46 static long next_yield
= 0;
47 #define MIN_YIELD_PERIOD 1000
49 static struct mutex ata_mtx SHAREDBSS_ATTR
;
51 #if defined(COWON_D2) || defined(IAUDIO_7)
53 #define MAX_WRITE_CACHES 8
56 #define MAX_WRITE_CACHES 4
59 /* Sector type identifiers - main data area */
61 #define SECTYPE_MAIN_LPT 0x12
62 #define SECTYPE_MAIN_DATA 0x13
63 #define SECTYPE_MAIN_RANDOM_CACHE 0x15
64 #define SECTYPE_MAIN_INPLACE_CACHE 0x17
66 /* We don't touch the hidden area at all - these are for reference */
67 #define SECTYPE_HIDDEN_LPT 0x22
68 #define SECTYPE_HIDDEN_DATA 0x23
69 #define SECTYPE_HIDDEN_RANDOM_CACHE 0x25
70 #define SECTYPE_HIDDEN_INPLACE_CACHE 0x27
73 #define SECTYPE_FIRMWARE 0x40
75 #define SECTYPE_FIRMWARE 0xE0
78 /* Offsets to data within sector's spare area */
80 #define OFF_CACHE_PAGE_LOBYTE 2
81 #define OFF_CACHE_PAGE_HIBYTE 3
82 #define OFF_SECTOR_TYPE 4
85 #define OFF_LOG_SEG_LOBYTE 7
86 #define OFF_LOG_SEG_HIBYTE 6
88 #define OFF_LOG_SEG_LOBYTE 6
89 #define OFF_LOG_SEG_HIBYTE 7
92 /* Chip characteristics, initialised by nand_get_chip_info() */
94 static struct nand_info
* nand_data
= NULL
;
96 static int total_banks
= 0;
97 static int pages_per_bank
= 0;
98 static int sectors_per_page
= 0;
99 static int bytes_per_segment
= 0;
100 static int sectors_per_segment
= 0;
101 static int segments_per_bank
= 0;
102 static int pages_per_segment
= 0;
104 /* Maximum values for static buffers */
106 #define MAX_PAGE_SIZE 4096
107 #define MAX_SPARE_SIZE 128
108 #define MAX_BLOCKS_PER_BANK 8192
109 #define MAX_PAGES_PER_BLOCK 128
111 #define MAX_BLOCKS_PER_SEGMENT 4
113 #define MAX_SEGMENTS (MAX_BLOCKS_PER_BANK * MAX_BANKS / MAX_BLOCKS_PER_SEGMENT)
115 /* Logical/Physical translation table */
123 static struct lpt_entry lpt_lookup
[MAX_SEGMENTS
];
125 /* buffer_alloc'd in nand_init() when the correct size has been determined */
126 static struct lpt_entry
* lpt_lookup
= NULL
;
135 short inplace_phys_segment
;
136 short inplace_pages_used
;
138 short random_phys_segment
;
139 short page_map
[MAX_PAGES_PER_BLOCK
* MAX_BLOCKS_PER_SEGMENT
];
141 static struct write_cache write_caches
[MAX_WRITE_CACHES
];
143 static int write_caches_in_use
= 0;
146 /* Conversion functions */
148 static int phys_segment_to_page_addr(int phys_segment
, int page_in_seg
)
152 switch (nand_data
->planes
)
156 page_addr
= (phys_segment
* nand_data
->pages_per_block
);
163 page_addr
= phys_segment
* nand_data
->pages_per_block
* 2;
167 /* Data is located in block+1 */
168 page_addr
+= nand_data
->pages_per_block
;
171 if (nand_data
->planes
== 4 && page_in_seg
& 2)
173 /* Data is located in 2nd half of bank */
175 (nand_data
->blocks_per_bank
/2) * nand_data
->pages_per_block
;
182 page_addr
+= (page_in_seg
/ nand_data
->planes
);
188 /* NAND physical access functions */
190 static void nand_chip_select(int bank
)
194 /* Disable both chip selects */
195 NAND_GPIO_CLEAR(CS_GPIO_BIT
);
196 NFC_CTRL
|= NFC_CS0
| NFC_CS1
;
200 /* NFC chip select */
203 NFC_CTRL
&= ~NFC_CS0
;
209 NFC_CTRL
&= ~NFC_CS1
;
212 /* Secondary chip select */
214 NAND_GPIO_SET(CS_GPIO_BIT
);
216 NAND_GPIO_CLEAR(CS_GPIO_BIT
);
221 static void nand_read_id(int bank
, unsigned char* id_buf
)
225 /* Enable NFC bus clock */
228 /* Reset NAND controller */
231 /* Set slow cycle timings since the chip is as yet unidentified */
232 NFC_CTRL
= (NFC_CTRL
&~0xFFF) | 0x353;
234 nand_chip_select(bank
);
236 /* Set write protect */
237 NAND_GPIO_CLEAR(WE_GPIO_BIT
);
242 /* Set 8-bit data width */
243 NFC_CTRL
&= ~NFC_16BIT
;
245 /* Read ID command, single address cycle */
249 /* Read the 5 chip ID bytes */
250 for (i
= 0; i
< 5; i
++)
252 id_buf
[i
] = NFC_SDATA
& 0xFF;
255 nand_chip_select(-1);
257 /* Disable NFC bus clock */
258 BCLKCTR
&= ~DEV_NAND
;
262 static void nand_read_uid(int bank
, unsigned int* uid_buf
)
266 /* Enable NFC bus clock */
269 /* Set cycle timing (stp = 1, pw = 3, hold = 1) */
270 NFC_CTRL
= (NFC_CTRL
&~0xFFF) | 0x131;
272 nand_chip_select(bank
);
274 /* Set write protect */
275 NAND_GPIO_CLEAR(WE_GPIO_BIT
);
277 /* Set 8-bit data width */
278 NFC_CTRL
&= ~NFC_16BIT
;
280 /* Undocumented (SAMSUNG specific?) commands set the chip into a
281 special mode allowing a normally-hidden UID block to be read. */
288 /* Write row/column address */
289 for (i
= 0; i
< nand_data
->col_cycles
; i
++) NFC_SADDR
= 0;
290 for (i
= 0; i
< nand_data
->row_cycles
; i
++) NFC_SADDR
= 0;
295 /* Wait until complete */
296 while (!(NFC_CTRL
& NFC_READY
)) {};
298 /* Copy data to buffer (data repeats after 8 words) */
299 for (i
= 0; i
< 8; i
++)
301 uid_buf
[i
] = NFC_WDATA
;
304 /* Reset the chip back to normal mode */
307 nand_chip_select(-1);
309 /* Disable NFC bus clock */
310 BCLKCTR
&= ~DEV_NAND
;
314 static void nand_setup_read(int bank
, int row
, int column
)
318 /* Enable NFC bus clock */
321 /* Set cycle timing (stp = 1, pw = 3, hold = 1) */
322 NFC_CTRL
= (NFC_CTRL
&~0xFFF) | 0x131;
324 nand_chip_select(bank
);
326 /* Set write protect */
327 NAND_GPIO_CLEAR(WE_GPIO_BIT
);
329 /* Set 8-bit data width */
330 NFC_CTRL
&= ~NFC_16BIT
;
335 /* Write column address */
336 for (i
= 0; i
< nand_data
->col_cycles
; i
++)
338 NFC_SADDR
= column
& 0xFF;
339 column
= column
>> 8;
342 /* Write row address */
343 for (i
= 0; i
< nand_data
->row_cycles
; i
++)
345 NFC_SADDR
= row
& 0xFF;
349 /* End of read command */
352 /* Wait until complete */
353 while (!(NFC_CTRL
& NFC_READY
)) {};
357 static void nand_end_read(void)
359 nand_chip_select(-1);
361 /* Disable NFC bus clock */
362 BCLKCTR
&= ~DEV_NAND
;
366 static void nand_read_raw(int bank
, int row
, int column
, int size
, void* buf
)
370 nand_setup_read(bank
, row
, column
);
372 /* Read data into page buffer */
373 if (((unsigned int)buf
& 3) || (size
& 3))
375 /* Use byte copy since either the buffer or size are not word-aligned */
376 /* TODO: Byte copy only where necessary (use words for mid-section) */
377 for (i
= 0; i
< size
; i
++)
379 ((unsigned char*)buf
)[i
] = NFC_SDATA
;
384 /* Use 4-byte copy as buffer and size are both word-aligned */
385 for (i
= 0; i
< (size
/4); i
++)
387 ((unsigned int*)buf
)[i
] = NFC_WDATA
;
395 static void nand_get_chip_info(void)
397 unsigned char manuf_id
;
398 unsigned char id_buf
[8];
400 /* Read chip id from bank 0 */
401 nand_read_id(0, id_buf
);
403 manuf_id
= id_buf
[0];
405 /* Identify the chip geometry */
406 nand_data
= nand_identify(id_buf
);
408 if (nand_data
== NULL
)
410 panicf("Unknown NAND: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
411 id_buf
[0],id_buf
[1],id_buf
[2],id_buf
[3],id_buf
[4]);
414 pages_per_bank
= nand_data
->blocks_per_bank
* nand_data
->pages_per_block
;
416 segments_per_bank
= nand_data
->blocks_per_bank
/ nand_data
->planes
;
418 bytes_per_segment
= nand_data
->page_size
* nand_data
->pages_per_block
421 sectors_per_page
= nand_data
->page_size
/ SECTOR_SIZE
;
423 sectors_per_segment
= bytes_per_segment
/ SECTOR_SIZE
;
425 pages_per_segment
= sectors_per_segment
/ sectors_per_page
;
427 /* Establish how many banks are present */
428 nand_read_id(1, id_buf
);
430 if (id_buf
[0] == manuf_id
)
432 /* Bank 1 is populated, now check if banks 2/3 are valid */
433 nand_read_id(2, id_buf
);
435 if (id_buf
[0] == manuf_id
)
437 /* Bank 2 returned matching id - check if 2/3 are shadowing 0/1 */
438 unsigned int uid_buf0
[8];
439 unsigned int uid_buf2
[8];
441 nand_read_uid(0, uid_buf0
);
442 nand_read_uid(2, uid_buf2
);
444 if (memcmp(uid_buf0
, uid_buf2
, 32) == 0)
446 /* UIDs match, assume banks 2/3 are shadowing 0/1 */
451 /* UIDs differ, assume banks 2/3 are valid */
457 /* Bank 2 returned differing id - assume 2/3 are junk */
463 /* Bank 1 returned differing id - assume it is junk */
469 1. "BMP" tag at block 0, page 0, offset <page_size> [always present]
470 2. On most D2s, <page_size>+3 is 'M' and <page_size>+4 is no. of banks.
471 This is not present on some older players (formatted with early FW?)
474 nand_read_raw(0, 0, /* bank, page */
475 nand_data
->page_size
, /* offset */
476 8, id_buf
); /* length, dest */
478 if (strncmp(id_buf
, "BMP", 3)) panicf("BMP tag not present");
480 if (id_buf
[3] == 'M')
482 if (id_buf
[4] != total_banks
) panicf("BMPM total_banks mismatch");
487 static bool nand_read_sector_of_phys_page(int bank
, int page
,
488 int sector
, void* buf
)
492 int page_offset
= sector
* (SECTOR_SIZE
+ 16);
494 #ifdef USE_ECC_CORRECTION
495 unsigned long spare_buf
[4];
497 /* Set up the ECC controller to monitor reads from NFC_WDATA */
499 ECC_BASE
= (unsigned long)&NFC_WDATA
;
500 ECC_CTRL
|= ECC_M4EN
;
501 ECC_CTRL
&= ~ECC_ENC
;
502 ECC_CTRL
|= ECC_READY
;
506 /* Read the sector data */
507 nand_setup_read(bank
, page
, page_offset
);
509 /* Read data into page buffer */
510 if ((unsigned int)buf
& 3)
512 /* If unaligned, read into a temporary buffer and copy to destination.
513 This way, reads are always done through NFC_WDATA - otherwise they
514 would not be 'seen' by the ECC controller. */
515 static char temp_buf
[SECTOR_SIZE
];
517 unsigned int* ptr
= (unsigned int*) temp_buf
;
519 for (i
= 0; i
< (SECTOR_SIZE
/4); i
++)
524 memcpy(buf
, temp_buf
, SECTOR_SIZE
);
528 /* Use straight word copy as buffer and size are both word-aligned */
529 unsigned int* ptr
= (unsigned int*) buf
;
531 for (i
= 0; i
< (SECTOR_SIZE
/4); i
++)
537 #ifdef USE_ECC_CORRECTION
538 /* Stop monitoring before we read the OOB data */
539 ECC_CTRL
&= ~ECC_M4EN
;
542 /* Read a further 4 words (sector OOB data) */
543 spare_buf
[0] = NFC_WDATA
;
544 spare_buf
[1] = NFC_WDATA
;
545 spare_buf
[2] = NFC_WDATA
;
546 spare_buf
[3] = NFC_WDATA
;
548 /* Calculate MLC4 ECC using bytes 0,1,8-15 */
550 ECC_CTRL
|= ECC_M4EN
;
552 MLC_ECC0W
= *(unsigned short*)spare_buf
;
553 MLC_ECC1W
= spare_buf
[2];
554 MLC_ECC2W
= spare_buf
[3];
556 while (!(ECC_CTRL
& ECC_READY
)) {};
558 int errors
= ECC_ERR_NUM
& 7;
562 case 4: /* nothing to correct */
565 case 7: /* fail, can't correct */
569 default: /* between 1 and 4 errors */
572 unsigned char* char_buf
= (unsigned char*)buf
;
574 for (i
= 0; i
< errors
+ 1; i
++)
576 int offset
= 0x207 - ECC_ERRADDR(i
);
577 char_buf
[offset
] ^= ECC_ERRDATA(i
);
582 /* Disable ECC block */
583 ECC_CTRL
&= ~ECC_M4EN
;
593 static bool nand_read_sector_of_phys_segment(int bank
, int phys_segment
,
594 int page_in_seg
, int sector
,
597 int page_addr
= phys_segment_to_page_addr(phys_segment
,
600 return nand_read_sector_of_phys_page(bank
, page_addr
, sector
, buf
);
604 static bool nand_read_sector_of_logical_segment(int log_segment
, int sector
,
607 int page_in_segment
= sector
/ sectors_per_page
;
608 int sector_in_page
= sector
% sectors_per_page
;
610 int bank
= lpt_lookup
[log_segment
].bank
;
611 int phys_segment
= lpt_lookup
[log_segment
].phys_segment
;
613 /* Check if any of the write caches refer to this segment/page.
614 If present we need to read the cached page instead. */
619 while (!found
&& cache_num
< write_caches_in_use
)
621 if (write_caches
[cache_num
].log_segment
== log_segment
)
623 if (write_caches
[cache_num
].page_map
[page_in_segment
] != -1)
625 /* data is located in random pages cache */
628 bank
= write_caches
[cache_num
].random_bank
;
629 phys_segment
= write_caches
[cache_num
].random_phys_segment
;
632 write_caches
[cache_num
].page_map
[page_in_segment
];
634 else if (write_caches
[cache_num
].inplace_pages_used
!= -1 &&
635 write_caches
[cache_num
].inplace_pages_used
> page_in_segment
)
637 /* data is located in in-place pages cache */
640 bank
= write_caches
[cache_num
].inplace_bank
;
641 phys_segment
= write_caches
[cache_num
].inplace_phys_segment
;
647 return nand_read_sector_of_phys_segment(bank
, phys_segment
,
649 sector_in_page
, buf
);
653 /* Miscellaneous helper functions */
655 static inline unsigned char get_sector_type(char* spare_buf
)
657 return spare_buf
[OFF_SECTOR_TYPE
];
660 static inline unsigned short get_log_segment_id(int phys_seg
, char* spare_buf
)
664 return ((spare_buf
[OFF_LOG_SEG_HIBYTE
] << 8) |
665 spare_buf
[OFF_LOG_SEG_LOBYTE
])
667 + 984 * (phys_seg
/ 1024)
672 static inline unsigned short get_cached_page_id(char* spare_buf
)
674 return (spare_buf
[OFF_CACHE_PAGE_HIBYTE
] << 8) |
675 spare_buf
[OFF_CACHE_PAGE_LOBYTE
];
678 static int find_write_cache(int log_segment
)
682 for (i
= 0; i
< write_caches_in_use
; i
++)
683 if (write_caches
[i
].log_segment
== log_segment
)
690 static void read_random_writes_cache(int bank
, int phys_segment
)
694 unsigned char spare_buf
[16];
696 nand_read_raw(bank
, phys_segment_to_page_addr(phys_segment
, page
),
697 SECTOR_SIZE
, /* offset to first sector's spare */
700 log_segment
= get_log_segment_id(phys_segment
, spare_buf
);
702 if (log_segment
== -1)
705 /* Find which cache this is related to */
706 int cache_no
= find_write_cache(log_segment
);
710 if (write_caches_in_use
< MAX_WRITE_CACHES
)
712 cache_no
= write_caches_in_use
;
713 write_caches_in_use
++;
717 panicf("Max NAND write caches reached");
721 write_caches
[cache_no
].log_segment
= log_segment
;
722 write_caches
[cache_no
].random_bank
= bank
;
723 write_caches
[cache_no
].random_phys_segment
= phys_segment
;
726 /* Loop over each page in the phys segment (from page 1 onwards).
727 Read spare for 1st sector, store location of page in array. */
729 page
< (nand_data
->pages_per_block
* nand_data
->planes
);
732 unsigned short cached_page
;
734 nand_read_raw(bank
, phys_segment_to_page_addr(phys_segment
, page
),
735 SECTOR_SIZE
, /* offset to first sector's spare */
738 cached_page
= get_cached_page_id(spare_buf
);
740 if (cached_page
!= 0xFFFF)
741 write_caches
[cache_no
].page_map
[cached_page
] = page
;
747 static void read_inplace_writes_cache(int bank
, int phys_segment
)
751 unsigned char spare_buf
[16];
753 nand_read_raw(bank
, phys_segment_to_page_addr(phys_segment
, page
),
754 SECTOR_SIZE
, /* offset to first sector's spare */
757 log_segment
= get_log_segment_id(phys_segment
, spare_buf
);
759 if (log_segment
== -1)
762 /* Find which cache this is related to */
763 int cache_no
= find_write_cache(log_segment
);
767 if (write_caches_in_use
< MAX_WRITE_CACHES
)
769 cache_no
= write_caches_in_use
;
770 write_caches_in_use
++;
774 panicf("Max NAND write caches reached");
778 write_caches
[cache_no
].log_segment
= log_segment
;
780 /* Find how many pages have been written to the new segment */
781 while (log_segment
!= -1 &&
782 page
< (nand_data
->pages_per_block
* nand_data
->planes
) - 1)
785 nand_read_raw(bank
, phys_segment_to_page_addr(phys_segment
, page
),
786 SECTOR_SIZE
, 16, spare_buf
);
788 log_segment
= get_log_segment_id(phys_segment
, spare_buf
);
793 write_caches
[cache_no
].inplace_bank
= bank
;
794 write_caches
[cache_no
].inplace_phys_segment
= phys_segment
;
795 write_caches
[cache_no
].inplace_pages_used
= page
;
800 int nand_read_sectors(IF_MD2(int drive
,) unsigned long start
, int incount
,
803 #ifdef HAVE_MULTIDRIVE
804 (void)drive
; /* unused for now */
809 mutex_lock(&ata_mtx
);
816 int segment
= start
/ sectors_per_segment
;
817 int secmod
= start
% sectors_per_segment
;
819 while (incount
> 0 && secmod
< sectors_per_segment
)
821 if (!nand_read_sector_of_logical_segment(segment
, secmod
, inbuf
))
824 goto nand_read_error
;
827 if (TIME_AFTER(USEC_TIMER
, next_yield
))
829 next_yield
= USEC_TIMER
+ MIN_YIELD_PERIOD
;
833 inbuf
+= SECTOR_SIZE
;
842 goto nand_read_error
;
849 mutex_unlock(&ata_mtx
);
855 int nand_write_sectors(IF_MD2(int drive
,) unsigned long start
, int count
,
858 #ifdef HAVE_MULTIDRIVE
859 (void)drive
; /* unused for now */
862 /* TODO: Learn more about TNFTL and implement this one day... */
869 #ifdef HAVE_STORAGE_FLUSH
876 #ifdef STORAGE_GET_INFO
877 void nand_get_info(IF_MD2(int drive
,) struct storage_info
*info
)
879 #ifdef HAVE_MULTIDRIVE
880 (void)drive
; /* unused for now */
883 /* firmware version */
884 info
->revision
="0.00";
886 info
->vendor
="Rockbox";
887 info
->product
="Internal Storage";
890 info
->num_sectors
= sectors_per_segment
* segments_per_bank
* total_banks
;
891 info
->sector_size
= SECTOR_SIZE
;
898 int bank
, phys_segment
, lptbuf_size
;
899 unsigned char spare_buf
[16];
901 if (initialized
) return 0;
903 mutex_init(&ata_mtx
);
906 CSCFG2
= 0x018a8010 | tcc77x_cscfg_bw(TCC77X_CSCFG_BW8
);
908 GPIOC_FUNC
&= ~(CS_GPIO_BIT
| WE_GPIO_BIT
);
912 /* Set GPIO direction for chip select & write protect */
913 NAND_GPIO_OUT_EN(CS_GPIO_BIT
| WE_GPIO_BIT
);
915 /* Get chip characteristics and number of banks */
916 nand_get_chip_info();
919 /* Use chip info to allocate the correct size LPT buffer */
920 lptbuf_size
= sizeof(struct lpt_entry
) * segments_per_bank
* total_banks
;
921 lpt_lookup
= buffer_alloc(lptbuf_size
);
923 /* Use a static array in the bootloader */
924 lptbuf_size
= sizeof(lpt_lookup
);
927 memset(lpt_lookup
, 0xff, lptbuf_size
);
928 memset(write_caches
, 0xff, sizeof(write_caches
));
930 write_caches_in_use
= 0;
932 /* Scan banks to build up block translation table */
933 for (bank
= 0; bank
< total_banks
; bank
++)
935 for (phys_segment
= 0; phys_segment
< segments_per_bank
; phys_segment
++)
937 /* Read spare bytes from first sector of each segment */
938 nand_read_raw(bank
, phys_segment_to_page_addr(phys_segment
, 0),
939 SECTOR_SIZE
, /* offset */
942 int type
= get_sector_type(spare_buf
);
945 if (type
== SECTYPE_MAIN_INPLACE_CACHE
)
947 /* Since this type of segment is written to sequentially, its
948 job is complete if the final page has been written. In this
949 case we need to treat it as a normal data segment. */
950 nand_read_raw(bank
, phys_segment_to_page_addr
951 (phys_segment
, pages_per_segment
- 1),
952 SECTOR_SIZE
, 16, spare_buf
);
954 if (get_sector_type(spare_buf
) != 0xff)
956 type
= SECTYPE_MAIN_DATA
;
963 case SECTYPE_MAIN_DATA
:
965 /* Main data area segment */
966 unsigned short log_segment
=
967 get_log_segment_id(phys_segment
, spare_buf
);
969 if (log_segment
< segments_per_bank
* total_banks
)
971 if (lpt_lookup
[log_segment
].bank
== -1 ||
972 lpt_lookup
[log_segment
].phys_segment
== -1)
974 lpt_lookup
[log_segment
].bank
= bank
;
975 lpt_lookup
[log_segment
].phys_segment
= phys_segment
;
979 //panicf("duplicate data segment 0x%x!", log_segment);
985 case SECTYPE_MAIN_RANDOM_CACHE
:
987 /* Newly-written random page data (Main data area) */
988 read_random_writes_cache(bank
, phys_segment
);
992 case SECTYPE_MAIN_INPLACE_CACHE
:
994 /* Newly-written sequential page data (Main data area) */
995 read_inplace_writes_cache(bank
, phys_segment
);
1007 long nand_last_disk_activity(void)
1009 return last_disk_activity
;
1012 void nand_sleep(void)
1016 void nand_spin(void)
1020 void nand_spindown(int seconds
)
1025 #ifdef CONFIG_STORAGE_MULTI
1027 int nand_num_drives(int first_drive
)
1029 /* We don't care which logical drive number we have been assigned */
1035 void nand_sleepnow(void)
1039 bool nand_disk_is_active(void)
1044 int nand_soft_reset(void)
1049 int nand_spinup_time(void)
1054 void nand_enable(bool onoff
)
1059 #endif /* CONFIG_STORAGE_MULTI */