David Jander wrote: > Hi Stefano, > Hi David,
> On Friday 20 August 2010 01:19:28 pm Stefano Babic wrote: >>> Will do. >>> Btw, do you have any idea why spi_xchg_single() hangs while transmitting >>> the second word without claiming the bus again? >> Can you see where does it hang ? Which device is connected to your SPI >> bus ? Does it work with the pmic (I think so, see later...). > > Just figured out one big mistake. I was debugging spi_flash.c, and had > CONFIG_ENV_IS_IN_SPI_FLASH set. That means, first SPI access is done before > malloc is available, and guess what? spi_setup_slave() uses malloc ;-) I have CONFIG_ENV_IS_IN_SPI_FLASH set, too. I try to figure out how the functions are called, but I do not get the same issue. I set with the debugger two breakpoints, one in mem_malloc_init and the second one in spi_setup_slave. I see that mem_alloc_init is hit first, and when spi_setup_slave is called, malloc is available. I get a valid pointer for the private structure. It seems there something in our config files that makes the things different. I do not yet know why. > The C++ comments show original code, the line below is new. Understood, if malloc is not called, we have to use static or (better) try to call mem_malloc_init() first > I see a one byte access followed by a 5 byte access, That is correct, you see the code in spi_flash.c. First the ID command is sent (0x97), without reading nothing (that is, din is NULL). Then the answer is read (dout is NULL), and the id buffer is 5 bytes long. > I assumed that u-boot spi drivers use only u8 buffers for simplicity. > So my fix looks as this: > > int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, > void *din, unsigned long flags) > { > int n_blks = (bitlen + 31) / 32; > u32 out, in; > u8 *in_b, *out_b; > int i; > > out_b = (u8 *)dout; > in_b = (u8 *)din; > > for(i = 0; i< n_blks; i++, bitlen -= 32) { > if(dout) { > out = out_b[0]; > if(bitlen > 8) > out = (out<<8) | out_b[1]; > if(bitlen > 16) > out = (out<<8) | out_b[2]; > if(bitlen > 24) > out = (out<<8) | out_b[3]; > out_b += 4; > } else { > out=0; > } > in = spi_xchg_single(slave, out, bitlen, flags); > if(din) { > if(bitlen > 24) { > in_b[3] = in & 0xff; > in >>= 8; > } > if(bitlen > 16) { > in_b[2] = in & 0xff; > in >>= 8; > } > if(bitlen > 8) { > in_b[1] = in & 0xff; > in >>= 8; > } > in_b[0] = in & 0xff; > in_b += 4; > } > } > return 0; > } > > Does this sound like it could work? I am trying another approach. As the MX51 has 32 bytes FIFO, it makes sense to use it and not send a single word, if we can. This must not change the behavior for the MX31, because this processor has no FIFO and a single word can be sent. So I replaced completely spi_xfer, and the logic you put in spi_xfer I have (more or less, I have not checked in details) moved inside the spi_xcgh:single, that now has the meaning for me as single transation: up to 1 word for i.MX31, up to 32 words (128 bytes) for i.MX51. Take into account that loading the kernel using a single word takes a lot of time.. >> However, I am currently working on several issues for MX51. It should be >> nice to know which are your plans to save both some time ;-) > > Well, I am in a bit of a hurry, and essentially what I need is to be able to > access SPI-nor flash (spansion type) for environment and booting linux. > MMC/SD access would be nice, but is not yet necessary. Ok, quite the same. I have a ST flash, but we get the same problems, I see. > I know. I thought to do it in two steps: Fix mxc_spi.c with a workaround for > the pmic driver (which amounts to '#define spi_xfer spi_xfer_fsl' at the > beginning of this driver basically) and fix the pmic driver later, since it > is > probably not trivial, and needs to be done carefully (you know, one can smoke > a board by mistake :-) I know, this makes funny setting voltages via software.... Best regards, Stefano -- ===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: off...@denx.de ===================================================================== _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot