2010-09-22 09:44:31

by Alex A. Mihaylov

[permalink] [raw]
Subject: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

Hello!

I have Toradex Colibri module ( PXA270 and PXA320 based -
http://www.toradex.com/Products/Colibri_Modules ) and want connect
them to Sagrad SG901-1028 module (
http://www.sagrad.com/index.php?option=com_content&view=article&id=55&Itemid=66
) based on STLC450 chip.

Now I add next code to plaform file (kernel 2.6.35.4):

static mfp_cfg_t colibri_pxa320_ssp_pin_config[] __initdata = {
GPIO83_SSP1_SCLK,
GPIO85_SSP1_TXD,
GPIO86_SSP1_RXD,
GPIO84_GPIO,
GPIO94_GPIO | MFP_LPM_EDGE_RISE, // IRQ
GPIO95_GPIO, // SLEEP
};

static struct pxa2xx_spi_master colibri_pxa320_spi_master = {
.clock_enable = CKEN_SSP1,
.num_chipselect = 1,
.enable_dma = 0,
};

static struct pxa2xx_spi_chip sagrad_spi_tuning = {
.gpio_cs = 84,
};

static struct spi_board_info colibri_pxa320_spi_chips[] = {
{ // Sagrad SG901-1028 or SG901-1039 - module p54spi, but... Joke
from Nokia =)
.modalias = "cx3110x",
.max_speed_hz = 13000000,
.mode = SPI_MODE_0,
.bus_num = 1,
.chip_select = 0,
.controller_data = &sagrad_spi_tuning,
},
};

static inline void colibri_pxa320_init_spi ( void ) {
pxa3xx_mfp_config( ARRAY_AND_SIZE( colibri_pxa320_ssp_pin_config ) );
pxa2xx_set_spi_info(1,&colibri_pxa320_spi_master);
spi_register_board_info( ARRAY_AND_SIZE( colibri_pxa320_spi_chips ) );
}

and pach p54spi.c for proper SPI speed (XScale have maximum SPI rate
13Mhz) with addition module parameter:

static long p54spi_max_rate = 24000000;
module_param(p54spi_max_rate, long, 0444);
MODULE_PARM_DESC(p54spi_max_rate, "maximum spi bus frequency");

and replace string with
spi->max_speed_hz = 24000000;
to
spi->max_speed_hz = p54spi_max_rate;

Also i got firmware 2.13.0.0.a.13.14.arm from linux-wireles. After
loading module with proper command line, I see message

cx3110x spi1.0: firmware boot failed

and no other error/warning message presents. SPI signals like good.


phy0: p54 detected a LM20 firmware
p54: rx_mtu reduced from 3240 to 2376
phy0: FW rev 2.13.0.0.a.13.14 - Softmac protocol 5.6
phy0: cryptographic accelerator WEP:YES, TKIP:YES, CCMP:YES
cx3110x spi1.0: loading user eeprom...
phy0: hwaddr 00:02:ee:c0:ff:ee, MAC:isl3820 RF:Longbc
x3110x spi1.0: firmware boot failed

What's trouble? Incorrect firmware? Unsupported (so slow) SPI rate?

I try load another firmware from 2.13... series - result: firmware
boot failed. I also try load firmware cutted from Sagrad source
(version 2.19....) result is same: firmware boot failed.

What is my next step for this idea?

--
Sincerely,
Alex A. Mihaylov
AKA MinimumLaw


2010-09-22 12:33:55

by Alex A. Mihaylov

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

2010/9/22 Christian Lamparter <[email protected]>:
> why polling? They even say "14. Wait for the READY interrupt".

This code from Sagrad:

SPI_IRQ(DISABLE);

// Turn the device Off and then On again.
SPIDRV_Pwr(FALSE);
SPIDRV_Pwr(TRUE);

// 1. Power up
// 2. Wait 240 ms.
Delay(480);

[skiped]

// 14. Wait for the READY interrupt (100 ms timeout).
// Loop while waiting for SPI device to respond with
interrupt, max timeout is WIFI_BOOT_TIMEOUT
for ( i = 0 ; i < WIFI_BOOT_TIMEOUT ; i++)
{
TempReg = SPIDRVReadReg32(SPI_ADRS_HOST_INTERRUPTS);
if( TempReg && SPI_HOST_INT_READY)
{
// 15. Acknowledge the READY interrupt.
SPIDRVWriteReg32(SPI_ADRS_HOST_INT_ACK,
SPI_HOST_INT_READY);
// 16. Issue the SLEEP interrupt.
SPIDRVWriteReg32(SPI_ADRS_ARM_INTERRUPTS,
SPI_ARM_INT_SLEEP);
break;
}

Delay(1);
}

SPI_IRQ(ENABLE);

if (i == WIFI_BOOT_TIMEOUT)
{
ret = FALSE;
}
else
{
ret = TRUE;
SET_WIFI_ACTIVE();
}

SPIDRVReadReg32(SPI_ADRS_HOST_INTERRUPTS) - poll SPI register. IRQ
from STLC chip disabled.

> Have you checked if the module parameters for power + irq are correct?

Yes. I check this in code and on osciloscope.

> Also, on power_on the driver currently waits just 10 and not 240 ms,
> maybe this could just be the problem...

OK. I try change this.

--
Sincerely,
Alex A. Mihaylov
AKA MinimumLaw

2010-09-22 12:24:44

by Christian Lamparter

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

On Wednesday 22 September 2010 14:01:46 Alex Mihaylov wrote:
> 2010/9/22 Christian Lamparter <[email protected]>:
> > their GPL driver looks funny. (Max, it's really worth a look)
> > anyway found this:
> > /*
> > Sequence taken from STLC4560 DataSheet
> > This sequence can be run with the maximum SPI clock frequency (that is, 48 MHz).
> > 1. Power up.
> > 2. Wait 240 ms.
> > 3. Halt processor (EHostDeviceCntrl2 = KSetHostOverride | KSetHostCPUEn=0).
> > 4. Wait 1 us.
> > 5. Enable DMA TX (EHostDmaTxCntrl, KDmaTxCntrlEnable).
> > 6. Write DMA TX length (EHostDmaTxLength).
> > 7. Write DMA TX base (EHostDmaTxBase1).
> > 8. Wait 1 ?s.
> > 9. Write firmware image (EHostDmaData).
> > 10. RAM reset (EHostDeviceCntrl2 = KSetHostOverride | KSetHostReset | KSetRamBoot).
> > 11. Wait 40 ms.
> > 12. RAM boot (EHostDeviceCntrl2 = KSetHostOverride | KSetRamBoot),
> > 13. Enable host interrupts (EHostIntEnable1 = KIrqReady | KIrqWrReady | KHwUpdate | KSwUpdate).
> > 14. Wait for the READY interrupt (100 ms timeout).
> > 15. Acknowledge the READY interrupt.
> > 16. Issue the SLEEP interrupt.
> > */
> >
> > maybe it helps
>
> Yes. I see this code. But in p54spi.c I found sequence from 1 to 13.
> Sagrad make this steps with disabler interrupt from card (poll chip
> register). But p54spi wait hardware READY IRQ from chip in 14 (and in
> IRQ routine send acknowledge from 15).

why polling? They even say "14. Wait for the READY interrupt".

Have you checked if the module parameters for power + irq are correct?

static int p54spi_gpio_power = 97;
MODULE_PARM_DESC(p54spi_gpio_power, "gpio number for power line");

static int p54spi_gpio_irq = 87;
MODULE_PARM_DESC(p54spi_gpio_irq, "gpio number for irq line");

Also, on power_on the driver currently waits just 10 and not 240 ms,
maybe this could just be the problem...

2010-09-22 11:25:56

by Alex A. Mihaylov

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

2010/9/22 Max Filippov <[email protected]>:

>> loading module with proper command line, I see message
>> cx3110x spi1.0: firmware boot failed
>> phy0: p54 detected a LM20 firmware
>> p54: rx_mtu reduced from 3240 to 2376
>> phy0: FW rev 2.13.0.0.a.13.14 - Softmac protocol 5.6
>> phy0: cryptographic accelerator WEP:YES, TKIP:YES, CCMP:YES
>> cx3110x spi1.0: loading user eeprom...

> Looks like you have custom eeprom image...
> ...and this eeprom image has wrong format.

>> What is my next step for this idea?
> I'd suggest removing file 3826.eeprom and trying to boot without it.

eeprom image was created from p54spi_eeprom.h file. I try to delete
this file and load different fimware - result some:


cx3110x spi1.0: 13000000 Hz actual, PIO
cx3110x spi1.0: setup mode 0, 16 bits/w, 13000000 Hz max --> 0
phy0: p54 detected a LM20 firmware
p54: rx_mtu reduced from 3240 to 2376
phy0: FW rev 2.13.0.0.a.13.14 - Softmac protocol 5.6
phy0: cryptographic accelerator WEP:YES, TKIP:YES, CCMP:YES
cx3110x spi1.0: loading default eeprom...
phy0: hwaddr 00:02:ee:c0:ff:ee, MAC:isl3820 RF:Longbow
phy0: Selected rate control algorithm 'minstrel'
cx3110x spi1.0: is registered as 'phy0'
cx3110x spi1.0: firmware boot failed

and with Sagrad firmware:

cx3110x spi1.0: 13000000 Hz actual, PIO
cx3110x spi1.0: setup mode 0, 16 bits/w, 13000000 Hz max --> 0
phy0: p54 detected a LM20 firmware
p54: rx_mtu reduced from 3240 to 2376
phy0: FW rev 2.19.0.0.A.14 Private - Softmac protocol 5.6
phy0: cryptographic accelerator WEP:YES, TKIP:YES, CCMP:YES
cx3110x spi1.0: loading default eeprom...
phy0: hwaddr 00:02:ee:c0:ff:ee, MAC:isl3820 RF:Longbow
phy0: Selected rate control algorithm 'minstrel'
cx3110x spi1.0: is registered as 'phy0'
cx3110x spi1.0: firmware boot failed

IRQ line not change state after firmware loaded into chip (stay low).
Is this normal?
SPI_CS line switch to low, and stay low all time. May be I need SPI_CS
pulse after firmware loaded into chip? I try use SPI_CS as controller
specific pin (not gpio_cs in platform file) - in this case I have next
error:

cx3110x: spi_write_dma not allowed to dma write.

and no firmware load into chip. SPI_CS in this case, make pulse on
each SPI transaction. After switch to gpio_cs firmware try to load,
but:

timeout = msecs_to_jiffies(2000);
timeout =
wait_for_completion_interruptible_timeout(&priv->fw_comp, timeout);
if (!timeout) {
dev_err(&priv->spi->dev, "firmware boot failed");
p54spi_power_off(priv);
ret = -1;
goto out;
}


Not starting?

---
Sincerely,
Alex A. Mihaylov
AKA MinimumLaw

2010-09-22 17:33:58

by Alex A. Mihaylov

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

2010/9/22 Max Filippov <[email protected]>:
>
> Look at the code of SPI_IRQ routine:
>
> void SPI_IRQ(FunctionalState state)
> {
> ? ?NVIC_InitTypeDef NVIC_InitStructure;
> ? ?static FunctionalState CurrState = DISABLE;
> ? ?// Check if we're changing states, otherwise just leave it.
> ? ?if(state != CurrState)
> ? ?{
> ? ? ? ?// 5. Configure the interrupt controller for the External
> Interrupt x SPI
> ? ? ? ?// Enable the interrupt controller for the External Interrupt
> ? ? ? ?NVIC_InitStructure.NVIC_IRQChannel = WIFI_INT_IRQ_CHAN;
> ? ? ? ?NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
> ? ? ? ?NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
> ? ? ? ?NVIC_InitStructure.NVIC_IRQChannelCmd = state;
> ? ? ? ?NVIC_Init(&NVIC_InitStructure);
>
> ? ? ? ?if( state == ENABLE )
> ? ? ? ?{
> ? ? ? ? ? ?SPIDRVWriteReg32(SPI_ADRS_HOST_INT_EN, SPI_HOST_INTS_DEFAULT);
> ? ? ? ?}
> ? ? ? ?else
> ? ? ? ?{
> ? ? ? ? ? ?SPIDRVWriteReg32(SPI_ADRS_HOST_INT_EN, 0);
> ? ? ? ?}
> ? ? ? ?CurrState = state;
> ? ?}
>
> }
>
> There's some activity with something unknown to me: // 5. Configure
> the interrupt controller for the External Interrupt x SPI
> And then programming of the stlc's HOST_INT_EN.
>
> It's not quite clear to me, what is that NVIC and what additional
> external interrupt configuration is going on. What's clear is that
> it's not related to the stlc chip. Looks like there's additional
> hardware on your board that conveys interrupt signal and that has to
> be configured.
>
> In nokia's N810 stlc's IRQ line seems to be connected directly to gpio
> pin. That gpio line is configured in p54spi_probe and that's enough
> for interrupts to get to us.

On my board lines IRQ and POWER (realy -SLEEPEN) also connected
directly to GPIO. (In real word they connected via interface chip.
CPUs use 3.3V voltage, STLC on this line use 1.8V - and I, and Nokia
use level-shift chip for connection). In code all simple - first off
all connect STM32 GPIO to interrupt controller and enable/disable this
IRQ source, next check requested action. If command==enable then allow
default STLC IRQ source (all source, but not CTS)
#define SPI_HOST_INT_READY 0x00000001
#define SPI_HOST_INT_UPDATE 0x10000000
#define SPI_HOST_INT_SW_UPDATE 0x00000004
#define SPI_HOST_INT_WR_READY 0x00000002

#define SPI_HOST_INT_CTS 0x00004000<>// clear to send
#define SPI_HOST_INT_DR> 0x00008000<>// data ready

#define SPI_HOST_INTS_DEFAULT SPI_HOST_INT_UPDATE |
SPI_HOST_INT_DR | SPI_HOST_INT_SW_UPDATE | SPI_HOST_INT_WR_READY

I.e. STLC can generate IRQ request on any events. Else, disable not
only host irq handler, but disable also STLC IRQ generation for ALL
events.

Unfortunately, I not see impulse on IRQ line with my
kernel/firmware/module. I think about corruted chip, but them set bit
in chip-side DMA-enabled transfer in p54spi.c function
p54spi_write_dma():

if (!p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL,
HOST_ALLOWED)) {
dev_err(&priv->spi->dev, "spi_write_dma not allowed "
"to DMA write.\n");
return -EAGAIN;
}

I realy got HOST_ALLOWED bit in contents of SPI_ADRS_DMA_WRITE_CTRL
register from STLC chip.

In Sagrad code, write data with chip-side DMA not use wait_bit mechanism:

void SPIDRVWriteDataDMA(const u8* pBuffer, u32 WriteAddr, u16
NumByteToWrite)
{
u32 reg1 = 0;
u32 i = 0;
u16 address = SPI_ADRS_DMA_DATA;
u16 *pBuf16 = (u16*)pBuffer;
SPI_REGSET_WRITE(address); //Clear read bit (redundant because it
shouldn't be set)

//Read DMA WRITE Control Register
reg1 = SPIDRVReadReg32(SPI_ADRS_DMA_WRITE_CTRL);
reg1 |= 0x1; //Set enable
SPIDRVWriteReg32(SPI_ADRS_DMA_WRITE_CTRL, reg1); //write it back

SPIDRVWriteReg32(SPI_ADRS_DMA_WRITE_LEN, NumByteToWrite);
reg1 = SPIDRVReadReg32(SPI_ADRS_DMA_WRITE_LEN);

SPIDRVWriteReg32(SPI_ADRS_DMA_WRITE_BASE, WriteAddr);
reg1 = SPIDRVReadReg32(SPI_ADRS_DMA_WRITE_BASE);

SPIDRV_ChipSelect(HIGH);
SPIDRV_ChipSelect(LOW); // Start transactions to Data register
SPI_I2S_SendHalfWord(address); // Write

for (i = 0; i < NumByteToWrite/2; i++)
{
SPI_I2S_SendHalfWord(pBuf16[i]);
}

// Wait for busy flag to clear before indicating the end of a
transaction
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);

SPIDRV_ChipSelect(HIGH);

return;
}

WOW! Bingo! Unfortunately, I'm home now! Tomorroy I try make this tips:

SPIDRV_ChipSelect(HIGH);
SPIDRV_ChipSelect(LOW); // Start transactions to Data register

This job NOT maked by XScale SPI driver.
Hm... Is Omap SPI driver do this? How?

--
Sincerely,
Alex A. Mihaylov
AKA MinimumLaw

2010-09-22 11:36:19

by Christian Lamparter

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

On Wednesday 22 September 2010 13:25:55 Alex Mihaylov wrote:
> 2010/9/22 Max Filippov <[email protected]>:
>
> >> loading module with proper command line, I see message
> >> cx3110x spi1.0: firmware boot failed
> >> phy0: p54 detected a LM20 firmware
> >> p54: rx_mtu reduced from 3240 to 2376
> >> phy0: FW rev 2.13.0.0.a.13.14 - Softmac protocol 5.6
> >> phy0: cryptographic accelerator WEP:YES, TKIP:YES, CCMP:YES
> >> cx3110x spi1.0: loading user eeprom...
>
> > Looks like you have custom eeprom image...
> > ...and this eeprom image has wrong format.
>
> >> What is my next step for this idea?
> > I'd suggest removing file 3826.eeprom and trying to boot without it.
>
> eeprom image was created from p54spi_eeprom.h file. I try to delete
> this file and load different fimware - result some:
>
>
> cx3110x spi1.0: 13000000 Hz actual, PIO
> cx3110x spi1.0: setup mode 0, 16 bits/w, 13000000 Hz max --> 0
> phy0: p54 detected a LM20 firmware
> p54: rx_mtu reduced from 3240 to 2376
> phy0: FW rev 2.13.0.0.a.13.14 - Softmac protocol 5.6
> phy0: cryptographic accelerator WEP:YES, TKIP:YES, CCMP:YES
> cx3110x spi1.0: loading default eeprom...
> phy0: hwaddr 00:02:ee:c0:ff:ee, MAC:isl3820 RF:Longbow
> phy0: Selected rate control algorithm 'minstrel'
> cx3110x spi1.0: is registered as 'phy0'
> cx3110x spi1.0: firmware boot failed
>
> and with Sagrad firmware:
>
> cx3110x spi1.0: 13000000 Hz actual, PIO
> cx3110x spi1.0: setup mode 0, 16 bits/w, 13000000 Hz max --> 0
> phy0: p54 detected a LM20 firmware
> p54: rx_mtu reduced from 3240 to 2376
> phy0: FW rev 2.19.0.0.A.14 Private - Softmac protocol 5.6
> phy0: cryptographic accelerator WEP:YES, TKIP:YES, CCMP:YES
> cx3110x spi1.0: loading default eeprom...
> phy0: hwaddr 00:02:ee:c0:ff:ee, MAC:isl3820 RF:Longbow
> phy0: Selected rate control algorithm 'minstrel'
> cx3110x spi1.0: is registered as 'phy0'
> cx3110x spi1.0: firmware boot failed
>
> IRQ line not change state after firmware loaded into chip (stay low).
> Is this normal?
> SPI_CS line switch to low, and stay low all time. May be I need SPI_CS
> pulse after firmware loaded into chip? I try use SPI_CS as controller
> specific pin (not gpio_cs in platform file) - in this case I have next
> error:
>
> cx3110x: spi_write_dma not allowed to dma write.
>
> and no firmware load into chip. SPI_CS in this case, make pulse on
> each SPI transaction. After switch to gpio_cs firmware try to load,
> but:
>
> timeout = msecs_to_jiffies(2000);
> timeout =
> wait_for_completion_interruptible_timeout(&priv->fw_comp, timeout);
> if (!timeout) {
> dev_err(&priv->spi->dev, "firmware boot failed");
> p54spi_power_off(priv);
> ret = -1;
> goto out;
> }
>
>
> Not starting?

their GPL driver looks funny. (Max, it's really worth a look)


anyway found this:
/*
Sequence taken from STLC4560 DataSheet
This sequence can be run with the maximum SPI clock frequency (that is, 48 MHz).
1. Power up.
2. Wait 240 ms.
3. Halt processor (EHostDeviceCntrl2 = KSetHostOverride | KSetHostCPUEn=0).
4. Wait 1 us.
5. Enable DMA TX (EHostDmaTxCntrl, KDmaTxCntrlEnable).
6. Write DMA TX length (EHostDmaTxLength).
7. Write DMA TX base (EHostDmaTxBase1).
8. Wait 1 ?s.
9. Write firmware image (EHostDmaData).
10. RAM reset (EHostDeviceCntrl2 = KSetHostOverride | KSetHostReset | KSetRamBoot).
11. Wait 40 ms.
12. RAM boot (EHostDeviceCntrl2 = KSetHostOverride | KSetRamBoot),
13. Enable host interrupts (EHostIntEnable1 = KIrqReady | KIrqWrReady | KHwUpdate | KSwUpdate).
14. Wait for the READY interrupt (100 ms timeout).
15. Acknowledge the READY interrupt.
16. Issue the SLEEP interrupt.
*/

maybe it helps

2010-09-22 16:10:25

by Alex A. Mihaylov

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

2010/9/22 Max Filippov <[email protected]>:
>> This code from Sagrad:
>>
>> ? ? ? ?SPI_IRQ(DISABLE);
>>
>> [skiped]
>
> If you look closer into the skipped part you'll see
>
> ? ? ? ?// 13. Enable host interrupts (EHostIntEnable1 = KIrqReady |
> KIrqWrReady | KHwUpdate | KSwUpdate)
> ? ? ? ?TempReg = (SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE |
> SPI_HOST_INT_SW_UPDATE| SPI_HOST_INT_WR_READY);
> ? ? ? ?SPIDRVWriteReg32(SPI_ADRS_HOST_INT_EN, TempReg);
>
> which actually enables interrupts, exactly as SPI_IRQ(ENABLE); does.
>
>>
>> ? ? ? // 14. Wait for the READY interrupt (100 ms timeout).
>> ? ? ? ?// Loop while waiting for SPI device to respond with
>> interrupt, max timeout is WIFI_BOOT_TIMEOUT
>> ? ? ? ?for ( i = 0 ; i < WIFI_BOOT_TIMEOUT ; i++)
>> ? ? ? ?{
>> ? ? ? ? ? ? ? ?TempReg = SPIDRVReadReg32(SPI_ADRS_HOST_INTERRUPTS);
>> ? ? ? ? ? ? ? ?if( TempReg && SPI_HOST_INT_READY)
>> ? ? ? ? ? ? ? ?{
>> ? ? ? ? ? ? ? ? ? ? ? ?// 15. Acknowledge the READY interrupt.
>> ? ? ? ? ? ? ? ? ? ? ? ?SPIDRVWriteReg32(SPI_ADRS_HOST_INT_ACK,
>> SPI_HOST_INT_READY);
>> ? ? ? ? ? ? ? ? ? ? ? ?// 16. Issue the SLEEP interrupt.
>> ? ? ? ? ? ? ? ? ? ? ? ?SPIDRVWriteReg32(SPI_ADRS_ARM_INTERRUPTS,
>> SPI_ARM_INT_SLEEP);
>> ? ? ? ? ? ? ? ? ? ? ? ?break;
>> ? ? ? ? ? ? ? ?}
>>
>> ? ? ? ? ? ? ? ?Delay(1);
>> ? ? ? ?}
>>
>> ? ? ? ?SPI_IRQ(ENABLE);

OK. Chip (STLC4560) have some reasons to make IRQ reqest to host
(XScale or Omap). In code:

SPIDRVWriteReg32(SPI_ADRS_HOST_INT_EN, TempReg);

we set IRQ mask for chip. So, chip CAN generate IRQ request to host
(make pulse on host IRQ GPIO line). But host NOT serve this interrupt
request ( SPI_IRQ(DISABLE) ). Host wait for event by pool interrupt
reason register. In linux kernel (p54spi.c) host serve this IRQ.
SPI_IRQ(ENABLE/DISABLE) used for enable/disable host handler, but
SPIDRVWriteReg32(SPI_ADRS_HOST_INT_EN, TempReg) used for device IRQ
reason control. I think so.

And some words about license. On Sagrad web site this file described:

URL: http://sagrad.com/index.php?option=com_docman&task=doc_details&gid=26&Itemid=101
(download possible after registration on web site).
Name: Sagrad_MAC GPL Source Code + IP Stack
Description: FreeRTOS with: - WiFi SPI driver - Custom Sagrad MAC with
ability to scan and associate to an Open AP - uIP stack to provide
TCP/IP
Filename: ? ? ? ?STM32Wifi_V.1.0.0.1.zip

FreeRTOS distributed under GPL. Sagrad say - GPL code. But, in head of
file wrote:
/*
?* IMPORTANT--READ CAREFULLY:
?*
?* Right, including without limitation, use, reproduction,
modification, and
?* creation of derivative works, pertaining to this Source Code
("Document")
?* are governed by a legal Agreement ("Agreement") between you (either
an
?* individual or a single entity) and Sagrad Inc("Sagrad")
?* and/or its licensee (both hereinafter called Licensor).
?*
?* By reproducing, modifying, creating derivative works, accepting,
?* installing, viewing, accessing, transforming or otherwise using
this
?* Document, you agree to be bound by the terms of the Agreement. If
you
?* do not agree to the terms of the Agreement, Licensor is unwilling
to
?* license rights to this Document to you. ?In such event, you may not
?* use, reproduce, modify, create derivative works, install, view,
access,
?* transport, transform or circulate this Document, and you should
promptly
?* contact Licensor from which you acquired this Document for
instructions
?* on returning or destroying this Document.
?*
?*
?* CONFIDENTIAL, PROPRIETARY AND TRADE SECRET INFORMATION: This
Document
?* contains confidential, proprietary and trade secret information of
?* Intersil Americas Inc. and should be treated in a confidential
manner.
?* Furthermore, this Document is protected by national copyright laws
and
?* international treaties.
?*
?* Unauthorized use, reproduction, modification, creation of
derivative
?* works or circulation is strictly prohibited.
?*
?* Copyright (c) 2008 Sagrad Inc. All Rights Reserved.
?*
?* The intent of Sagrad is to release this source to the public under
GPL
?* upon the successful agreement with STMicro for the exclusive
?* distribution rights for the STLC4560
?*/

This code cant be directly placed into kernel source (FreeRTOS is NOT
Linux). This code contents NOT a code, but initialization and working
methods.

--
Sincerelly,
Alex A. Mihaylov
AKA MinimumLaw

2010-09-22 12:58:47

by Christian Lamparter

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

On Wednesday 22 September 2010 14:33:54 Alex Mihaylov wrote:
> 2010/9/22 Christian Lamparter <[email protected]>:
> > why polling? They even say "14. Wait for the READY interrupt".
>
> This code from Sagrad:

be careful with code... Haven't you read the comical license?!
I'm not sure how ST react once they figured out that Sagrad
leaked parts of the secret code, which might even cost them
the FCC badge?!

> SPIDRVReadReg32(SPI_ADRS_HOST_INTERRUPTS) - poll SPI register. IRQ
> from STLC chip disabled.

so what you are trying to say is that they have knowingly ignored
their own specification? But who cares, as long as they do provide
a "complete" driver+stack solution for their paying customers.

> > Also, on power_on the driver currently waits just 10 and not 240 ms,
> > maybe this could just be the problem...
>
> OK. I try change this.
>

note:

2.6.25.4 is very old and the spi subsystem (which isn't backported in cw)
has changed quite a bit since then.

2010-09-22 13:41:49

by Max Filippov

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

> I have Toradex Colibri module ( PXA270 and PXA320 based -
> http://www.toradex.com/Products/Colibri_Modules ) and want connect
> them to Sagrad SG901-1028 module (
> http://www.sagrad.com/index.php?option=com_content&view=article&id=55&Itemid=66
> ) based on STLC450 chip.
>
> Now I add next code to plaform file (kernel 2.6.35.4):
...
> their GPL driver looks funny. (Max, it's really worth a look)
...
> note:
> 2.6.25.4 is very old and the spi subsystem (which isn't backported in cw)
> has changed quite a bit since then.

Alex, what driver is discussed? Christian, what GPL driver?

--
Max

2010-09-22 13:48:36

by Christian Lamparter

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

On Wednesday 22 September 2010 15:41:49 Max Filippov wrote:
> > I have Toradex Colibri module ( PXA270 and PXA320 based -
> > http://www.toradex.com/Products/Colibri_Modules ) and want connect
> > them to Sagrad SG901-1028 module (
> > http://www.sagrad.com/index.php?option=com_content&view=article&id=55&Itemid=66
> > ) based on STLC450 chip.
> >
> > Now I add next code to plaform file (kernel 2.6.35.4):
> ...
> > their GPL driver looks funny. (Max, it's really worth a look)
> ...
> > note:
> > 2.6.25.4 is very old and the spi subsystem (which isn't backported in cw)
> > has changed quite a bit since then.
>
> Alex, what driver is discussed? Christian, what GPL driver?
Oh I'm sorry, I forgot to add the "irony" GPL tags.

Anyway, take a look at the product page, there you can download
the their driver "demo".

2010-09-22 19:59:11

by Max Filippov

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

> WOW! Bingo! Unfortunately, I'm home now! Tomorroy I try make this tips:
>
> SPIDRV_ChipSelect(HIGH);
> SPIDRV_ChipSelect(LOW); // Start transactions to Data register
>
> This job NOT maked by XScale SPI driver.
> Hm... Is Omap SPI driver do this? How?

Seems to me that omap2_mcspi_work in drivers/spi/omap2_mcspi.c does it by the calls to omap2_mcspi_force_cs.

Thanks.
-- Max

2010-09-22 10:39:00

by Max Filippov

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

> Also i got firmware ?2.13.0.0.a.13.14.arm from linux-wireles. After
> loading module with proper command line, I see message
>
> cx3110x spi1.0: firmware boot failed
>
> and no other error/warning message presents. SPI signals like good.
>
>
> phy0: p54 detected a LM20 firmware
> p54: rx_mtu reduced from 3240 to 2376
> phy0: FW rev 2.13.0.0.a.13.14 - Softmac protocol 5.6
> phy0: cryptographic accelerator WEP:YES, TKIP:YES, CCMP:YES
> cx3110x spi1.0: loading user eeprom...

Looks like you have custom eeprom image...

> phy0: hwaddr 00:02:ee:c0:ff:ee, MAC:isl3820 RF:Longbc
> x3110x spi1.0: firmware boot failed

...and this eeprom image has wrong format.

> What's trouble? Incorrect firmware? Unsupported (so slow) SPI rate?
>
> I try load another firmware from 2.13... series - result: firmware
> boot failed. I also try load firmware cutted from Sagrad source
> (version 2.19....) result is same: firmware boot failed.
>
> What is my next step for this idea?

I'd suggest removing file 3826.eeprom and trying to boot without it.

--
Max

2010-09-22 16:43:15

by Max Filippov

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

>>> This code from Sagrad:
>>>
>>> ? ? ? ?SPI_IRQ(DISABLE);
>>>
>>> [skiped]
>>
>> If you look closer into the skipped part you'll see
>>
>> ? ? ? ?// 13. Enable host interrupts (EHostIntEnable1 = KIrqReady |
>> KIrqWrReady | KHwUpdate | KSwUpdate)
>> ? ? ? ?TempReg = (SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE |
>> SPI_HOST_INT_SW_UPDATE| SPI_HOST_INT_WR_READY);
>> ? ? ? ?SPIDRVWriteReg32(SPI_ADRS_HOST_INT_EN, TempReg);
>>
>> which actually enables interrupts, exactly as SPI_IRQ(ENABLE); does.
>>
>>>
>>> ? ? ? // 14. Wait for the READY interrupt (100 ms timeout).
>>> ? ? ? ?// Loop while waiting for SPI device to respond with
>>> interrupt, max timeout is WIFI_BOOT_TIMEOUT
>>> ? ? ? ?for ( i = 0 ; i < WIFI_BOOT_TIMEOUT ; i++)
>>> ? ? ? ?{
>>> ? ? ? ? ? ? ? ?TempReg = SPIDRVReadReg32(SPI_ADRS_HOST_INTERRUPTS);
>>> ? ? ? ? ? ? ? ?if( TempReg && SPI_HOST_INT_READY)
>>> ? ? ? ? ? ? ? ?{
>>> ? ? ? ? ? ? ? ? ? ? ? ?// 15. Acknowledge the READY interrupt.
>>> ? ? ? ? ? ? ? ? ? ? ? ?SPIDRVWriteReg32(SPI_ADRS_HOST_INT_ACK,
>>> SPI_HOST_INT_READY);
>>> ? ? ? ? ? ? ? ? ? ? ? ?// 16. Issue the SLEEP interrupt.
>>> ? ? ? ? ? ? ? ? ? ? ? ?SPIDRVWriteReg32(SPI_ADRS_ARM_INTERRUPTS,
>>> SPI_ARM_INT_SLEEP);
>>> ? ? ? ? ? ? ? ? ? ? ? ?break;
>>> ? ? ? ? ? ? ? ?}
>>>
>>> ? ? ? ? ? ? ? ?Delay(1);
>>> ? ? ? ?}
>>>
>>> ? ? ? ?SPI_IRQ(ENABLE);
>
> OK. Chip (STLC4560) have some reasons to make IRQ reqest to host
> (XScale or Omap). In code:
>
> SPIDRVWriteReg32(SPI_ADRS_HOST_INT_EN, TempReg);
>
> we set IRQ mask for chip. So, chip CAN generate IRQ request to host
> (make pulse on host IRQ GPIO line). But host NOT serve this interrupt
> request ( SPI_IRQ(DISABLE) ). Host wait for event by pool interrupt
> reason register. In linux kernel (p54spi.c) host serve this IRQ.
> SPI_IRQ(ENABLE/DISABLE) used for enable/disable host handler, but
> SPIDRVWriteReg32(SPI_ADRS_HOST_INT_EN, TempReg) used for device IRQ
> reason control. I think so.

Look at the code of SPI_IRQ routine:

void SPI_IRQ(FunctionalState state)
{
NVIC_InitTypeDef NVIC_InitStructure;
static FunctionalState CurrState = DISABLE;
// Check if we're changing states, otherwise just leave it.
if(state != CurrState)
{
// 5. Configure the interrupt controller for the External
Interrupt x SPI
// Enable the interrupt controller for the External Interrupt
NVIC_InitStructure.NVIC_IRQChannel = WIFI_INT_IRQ_CHAN;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = state;
NVIC_Init(&NVIC_InitStructure);

if( state == ENABLE )
{
SPIDRVWriteReg32(SPI_ADRS_HOST_INT_EN, SPI_HOST_INTS_DEFAULT);
}
else
{
SPIDRVWriteReg32(SPI_ADRS_HOST_INT_EN, 0);
}
CurrState = state;
}

}

There's some activity with something unknown to me: // 5. Configure
the interrupt controller for the External Interrupt x SPI
And then programming of the stlc's HOST_INT_EN.

It's not quite clear to me, what is that NVIC and what additional
external interrupt configuration is going on. What's clear is that
it's not related to the stlc chip. Looks like there's additional
hardware on your board that conveys interrupt signal and that has to
be configured.

In nokia's N810 stlc's IRQ line seems to be connected directly to gpio
pin. That gpio line is configured in p54spi_probe and that's enough
for interrupts to get to us.

--
Max

2010-09-22 14:57:16

by Max Filippov

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

> This code from Sagrad:
>
> ? ? ? ?SPI_IRQ(DISABLE);
>
> ? ? ? ?// Turn the device Off and then On again.
> ? ? ? ?SPIDRV_Pwr(FALSE);
> ? ? ? ?SPIDRV_Pwr(TRUE);
>
> ? ? ? ?// 1. Power up
> ? ? ? ?// 2. Wait 240 ms.
> ? ? ? ?Delay(480);
>
> [skiped]

If you look closer into the skipped part you'll see

// 13. Enable host interrupts (EHostIntEnable1 = KIrqReady |
KIrqWrReady | KHwUpdate | KSwUpdate)
TempReg = (SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE |
SPI_HOST_INT_SW_UPDATE| SPI_HOST_INT_WR_READY);
SPIDRVWriteReg32(SPI_ADRS_HOST_INT_EN, TempReg);

which actually enables interrupts, exactly as SPI_IRQ(ENABLE); does.

>
> ? ? ? // 14. Wait for the READY interrupt (100 ms timeout).
> ? ? ? ?// Loop while waiting for SPI device to respond with
> interrupt, max timeout is WIFI_BOOT_TIMEOUT
> ? ? ? ?for ( i = 0 ; i < WIFI_BOOT_TIMEOUT ; i++)
> ? ? ? ?{
> ? ? ? ? ? ? ? ?TempReg = SPIDRVReadReg32(SPI_ADRS_HOST_INTERRUPTS);
> ? ? ? ? ? ? ? ?if( TempReg && SPI_HOST_INT_READY)
> ? ? ? ? ? ? ? ?{
> ? ? ? ? ? ? ? ? ? ? ? ?// 15. Acknowledge the READY interrupt.
> ? ? ? ? ? ? ? ? ? ? ? ?SPIDRVWriteReg32(SPI_ADRS_HOST_INT_ACK,
> SPI_HOST_INT_READY);
> ? ? ? ? ? ? ? ? ? ? ? ?// 16. Issue the SLEEP interrupt.
> ? ? ? ? ? ? ? ? ? ? ? ?SPIDRVWriteReg32(SPI_ADRS_ARM_INTERRUPTS,
> SPI_ARM_INT_SLEEP);
> ? ? ? ? ? ? ? ? ? ? ? ?break;
> ? ? ? ? ? ? ? ?}
>
> ? ? ? ? ? ? ? ?Delay(1);
> ? ? ? ?}
>
> ? ? ? ?SPI_IRQ(ENABLE);
>
> ? ? ? ?if (i == WIFI_BOOT_TIMEOUT)
> ? ? ? ?{
> ? ? ? ? ? ? ? ?ret = FALSE;
> ? ? ? ?}
> ? ? ? ?else
> ? ? ? ?{
> ? ? ? ? ? ? ? ?ret = TRUE;
> ? ? ? ? ? ? ? ?SET_WIFI_ACTIVE();
> ? ? ? ?}
>

--
Max

2010-09-22 12:01:47

by Alex A. Mihaylov

[permalink] [raw]
Subject: Re: p54spi (STLC4560) with Marvel XScale CPU (kernel 2.6.25.4)

2010/9/22 Christian Lamparter <[email protected]>:
> their GPL driver looks funny. (Max, it's really worth a look)
> anyway found this:
> ? ? ? ?/*
> ? ? ? ? ? Sequence taken from STLC4560 DataSheet
> ? ? ? ? ? This sequence can be run with the maximum SPI clock frequency (that is, 48 MHz).
> ? ? ? ? ? 1. Power up.
> ? ? ? ? ? 2. Wait 240 ms.
> ? ? ? ? ? 3. Halt processor (EHostDeviceCntrl2 = KSetHostOverride | KSetHostCPUEn=0).
> ? ? ? ? ? 4. Wait 1 us.
> ? ? ? ? ? 5. Enable DMA TX (EHostDmaTxCntrl, KDmaTxCntrlEnable).
> ? ? ? ? ? 6. Write DMA TX length (EHostDmaTxLength).
> ? ? ? ? ? 7. Write DMA TX base (EHostDmaTxBase1).
> ? ? ? ? ? 8. Wait 1 ?s.
> ? ? ? ? ? 9. Write firmware image (EHostDmaData).
> ? ? ? ? ? 10. RAM reset (EHostDeviceCntrl2 = KSetHostOverride | KSetHostReset | KSetRamBoot).
> ? ? ? ? ? 11. Wait 40 ms.
> ? ? ? ? ? 12. RAM boot (EHostDeviceCntrl2 = KSetHostOverride | KSetRamBoot),
> ? ? ? ? ? 13. Enable host interrupts (EHostIntEnable1 = KIrqReady | KIrqWrReady | KHwUpdate | KSwUpdate).
> ? ? ? ? ? 14. Wait for the READY interrupt (100 ms timeout).
> ? ? ? ? ? 15. Acknowledge the READY interrupt.
> ? ? ? ? ? 16. Issue the SLEEP interrupt.
> ? ? ? ? */
>
> maybe it helps

Yes. I see this code. But in p54spi.c I found sequence from 1 to 13.
Sagrad make this steps with disabler interrupt from card (poll chip
register). But p54spi wait hardware READY IRQ from chip in 14 (and in
IRQ routine send acknowledge from 15).

I think about rewrite this driver complete, but... This solution not so pretty.


// stage 13
/* enable host interrupts */
p54spi_write32(priv, SPI_ADRS_HOST_INT_EN,
cpu_to_le32(SPI_HOST_INTS_DEFAULT));
// stage 10
/* boot the device */
p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET |
SPI_CTRL_STAT_RAM_BOOT));

msleep(TARGET_BOOT_SLEEP);
//stage 12
p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT));
msleep(TARGET_BOOT_SLEEP);

May be after RAM BOOT interrupts in chip disabled?

--
Sincerely,
Alex A. Mihaylov
AKA MinimumLaw