From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tolunay Orkun Date: Wed, 31 Jan 2007 23:26:08 -0600 Subject: [U-Boot-Users] [PATCH] Fixed cfi flash read uchar bug. In-Reply-To: <1170271527.3925.20.camel@udp097531uds.am.freescale.net> References: <45C05AF8.70709@orkun.us> <1170271527.3925.20.camel@udp097531uds.am.freescale.net> Message-ID: <45C179F0.6050206@orkun.us> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Haiying Wang wrote: > ------------ > U-Boot 1.2.0 (Jan 31 2007 - 13:12:04) > > Freescale PowerPC > CPU: > Core: E600, Version: 0.2, (0x80040202) > System: 8641D, Version: 2.0, (0x80900120) > Clocks: CPU:1000 MHz, MPX: 400 MHz, DDR: 200 MHz, LBC: 50 MHz > L2: Enabled Pretty fast CPU you've got here :) > Board: MPC8641HPCN > PCI-EXPRESS1: Disabled > I2C: ready > DRAM: DDR: 256 MB > FLASH: ## Unknown FLASH on Bank 1 - Size = 0x00000000 = 0 MB It looks like you inserted the debug prints in wrong place. The output below should have been after the debug stuff. Anyway... > chipwidth = 2 > portwidth = 2 > interface = 1 > vendor = 0 > cfi_offset= 85 > manufacturer_id = 1 > device_id = 126 > device_id2 = 4865 Except for "vendor" everything looks OK here. I should have asked you to print vendor right before flash_read_jedec_ids() call. It was not yet initialized when printed. It must be correctly set as well since flash_read_jedec_ids() uses it would not have returned correct data otherwise. You have a 16-bit flash accessible on 16-bit bus. The flash manufacturer is "AMD/Spansion" or compatible and device id is 7E1301 which is correct for your part: http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25538a1.pdf Please note that flash_read_jedec_ids() is used for manufacturer id and device_ids and this function in turn is using flash_read_uchar() which worked just fine for you. > 124 erase regions found, only 4 used This is not correct. This is why you are blaming the flash_read_uchar() function. But since it worked correctly before the failure to read the number of erase regions is probably not due to the function. >> Also try replacing following line in flash_detect_cfi() function: >> >> flash_write_cmd (info, 0, 0, info->cmd_reset); >> >> with the following two lines: >> >> flash_write_cmd(info, 0, 0, FLASH_CMD_RESET); >> flash_write_cmd(info, 0, 0, AMD_CMD_RESET); You demonstrated that this did not affect you because the output was the same. The problem with this line was that info->cmd_reset was not yet initialized when flash_detect_cfi() was called. This is a minor bug since the flash was not in query mode yet. I think we can safely remove this call as well or replace it both amd anf intel reset commands back to back. But anyway, back to your issue. >> If you are suspecting that the flash is not in array read mode after >> flash_read_jedec_ids() you can easily dump the first 256 bytes of flash >> right after [write a simple hexdump routine]. >> >>> this function, a flash_write_cmd() follows it, then the flash_read_uchar >> After this command, the flash should be in cfi_read mode. Hexdump the >> first 256 bytes again. You should be able to spot easily if you landed >> in cfi query mode or not. These are crucial before you put the blame on >> flash_read_uchar(). > Then I dump the first 256bytes of flash, first after > flash_read_jedec_ids(), then after flash_write_cmd(), see log: > > ------- > U-Boot 1.2.0 (Jan 31 2007 - 13:46:59) > > Freescale PowerPC > CPU: > Core: E600, Version: 0.2, (0x80040202) > System: 8641D, Version: 2.0, (0x80900120) > Clocks: CPU:1000 MHz, MPX: 400 MHz, DDR: 200 MHz, LBC: 50 MHz > L2: Enabled > Board: MPC8641HPCN > PCI-EXPRESS1: Disabled > I2C: ready > DRAM: DDR: 256 MB > FLASH: ## Unknown FLASH on Bank 1 - Size = 0x00000000 = 0 MB > chipwidth = 2 > portwidth = 2 > interface = 1 > vendor = 0 > cfi_offset= 85 > > Dump the first 256 byte of flash > 27 05 19 56 26 6c 3d b3 44 e4 ae 15 00 2b 05 33 > 00 00 00 00 00 00 00 00 35 b6 3f 82 05 07 03 01 > 75 62 6f 6f 74 20 65 78 74 32 20 72 61 6d 64 69 > 73 6b 20 72 6f 6f 74 66 73 00 00 00 00 00 00 00 > 1f 8b 08 08 14 ae e4 44 00 03 72 6f 6f 74 66 73 > 2e 65 78 74 32 00 ec 9d 09 7c 15 d5 bd c7 cf dc > dc dc 24 17 ac 97 a5 42 2b 68 dc 65 11 90 35 09 > 01 c2 22 6a 45 45 dc 00 17 92 90 00 d1 6c 26 81 > 62 ab 08 56 ad 5a 17 5a ad 5b 7d 16 7d f6 55 5b > b5 58 ab e0 52 1b 97 56 6c 51 41 01 51 2c 82 62 > b5 28 02 ae d4 2e be ef ff ce 19 e6 04 6e ca e4 > 35 e3 f4 d5 f3 e7 f3 e5 cc ff ce b9 f3 9b 73 ce > ff 2c 73 73 ef 8c 52 d6 ac 59 fb b2 5a 2a 4b a9 > 1e 87 29 f5 91 a3 d4 7d b9 4a fd 95 d7 1c 63 ff > c2 2e 2e 97 9b 2f aa ae ea e4 ad 8e b2 66 cd da > ff 6f a3 fb ab 38 64 a7 bd 79 6a df 5d f6 5f 47 > manufacturer_id = 1 > device_id = 126 > device_id2 = 4865 > > Dump the first 256 byte of flash > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 51 00 52 00 59 00 02 00 00 00 40 00 00 00 00 > 00 00 00 00 00 00 00 27 00 36 00 00 00 00 00 07 > 00 07 00 0a 00 00 00 01 00 05 00 04 00 00 00 17 > 00 01 00 00 00 05 00 00 00 01 00 7f 00 00 00 00 > 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 50 00 52 00 49 00 31 00 33 00 08 00 02 00 04 > 00 01 00 04 00 00 00 00 00 01 00 b5 00 c5 00 05 > 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 Guess what this looks like a valid CFI table now. I can definitely see Q = 0x51, R = 0x52, Y = 0x59 etc. in the correct places. > 8 MB It looks like the rest of the commands worked as well :) All without changing flash_read_uchar() functionality! > Using default environment > > In: serial > Out: serial > Err: serial > Net: eTSEC1, eTSEC2, eTSEC3, eTSEC4 > Hit any key to stop autoboot: 0 > => > ------- > This time, the flash got the correct size and can be accessed. I think > the second dump()function I added made it work, as it worked when I > inserted a udelay after flash_write_cmd(). At this point, all data indicates that flash_read_uchar() is just fine. I am suspecting two things: 1) Your CPU might be trying to re-order writes and reads to optimize performance. Since the command write and data read are from different addresses it could do this but the write command should really finish before we access the table data. So, we might need to add powerpc "sync" instructions in flash_write_cmd() function. Apparently CONFIG_BLACKFIN has a similar need as well. I would add a generic "sync" for the whole PowerPC family but there is not a conveninent CONFIG_POWERPC macro as far as I can see. Anyway, try adding: asm("sync;"); statements in that function. Use Blackfin as an example. 2) Because you have a rather fast CPU it is possible that we are not allowing enough time after reset command is executed before array is in read mode. According to the datasheet of your flash part if external reset signal was asserted you could need up to 20usec before flash returns to read mode. I am not sure if this delay is needed for issued reset commands as well. We might need to add some delay after flash reset commands. Try adding udelay(100); right after flash reset command is sent. You can locate flash reset commands by searching flash_write_cmd() statements that passes FLASH_CMD_RESET, AMD_CMD_RESET or cfi->cmd_reset as the last argument. > Please shed some lights. Thanks a lot! I hope this helps. Best regards, Tolunay