[#4097] SPI bus driver misbehaves when operating with multiple devices in different modes

Document created by Aaronwu Employee on Aug 28, 2013
Version 1Show Document
  • View in full screen mode

[#4097] SPI bus driver misbehaves when operating with multiple devices in different modes

Submitted By: Mike Frysinger

Open Date

2008-05-09 15:29:36     Close Date

2008-11-14 06:46:33

Priority:

Medium     Assignee:

Bryan Wu

Status:

Closed     Fixed In Release:

N/A

Found In Release:

N/A     Release:

Category:

N/A     Board:

N/A

Processor:

N/A     Silicon Revision:

Is this bug repeatable?:

Yes     Resolution:

Fixed

Uboot version or rev.:

    Toolchain version or rev.:

App binary format:

N/A     

Summary: SPI bus driver misbehaves when operating with multiple devices in different modes

Details:

 

as reported on our forums here:

  blackfin.uclinux.org/gf/project/uclinux-dist/forum/?action=ForumBrowse&forum_id=39&_forum_action=ForumMessageBrowse&thread_id=27306

 

if you have one SPI device operating in a mode where CPHA is 0 (like mode 0 or mode 2) while another SPI device is operating in CPHA 1 (like mode 1 or mode 3), then the CS gets incorrectly managed.  the SPI_FLAG register seems to assert the FLS bits for all devices and then manages just the FLG bits.  while this is OK if all devices are operating with CPHA=1, this will not work for mixed mode scenarios.

 

so to test, take two SPI devices and open/operate them simultaneously.  one device has to be in a mode with CPHA=0 (so SPI_MODE_0) while the other has to be in a mode with CPHA=1 (so SPI_MODE_3).  when operating on them, the CS should obviously only toggle for one at a time.

 

Follow-ups

 

--- Bryan Wu                                                 2008-06-12 05:45:53

Hi Mike,

 

I am trying to reproduce this bug. I setup bf527-board with ad7877 spi

touchscreen module. So on spi.0 bus, CS 1 is for on-board spi flash and CS 2 is

for ad7877 spi touchscreen.

 

Then I mounted the spi flash jffs2 partition and do event_test on ad7877. There

is no such error or bug. Need I use oscilloscope to verify the cs change?

 

---

Linux version 2.6.22.19-ADI-2008R1-svn4822 (roc@roc-desktop) (gcc version 4.1.2

(ADI svn)) #5 Thu Jun 12 17:40:39 CST 2008

early printk enabled on early_BFuart0

Hardware Trace Active and Enabled

Reset caused by Software reset

Blackfin support (C) 2004-2007 Analog Devices, Inc.

Compiled for ADSP-BF527 Rev 0.0

Warning: Unsupported Chip Revision ADSP-BF527 Rev 0.0 detected

Blackfin Linux support by   blackfin.uclinux.org/

Processor Speed: 525 MHz core clock and 131 MHz System Clock

Board Memory: 64MB

Kernel Managed Memory: 64MB

Memory map:

  text      = 0x00001000-0x00131830

  rodata    = 0x00132000-0x0018cadc

  data      = 0x0018d000-0x001a2000

    stack   = 0x0018e000-0x00190000

  init      = 0x001a2000-0x00448000

  bss       = 0x00448000-0x00457ff0

  available = 0x00457ff0-0x03eff000

  DMA Zone  = 0x03f00000-0x04000000

On node 0 totalpages: 16127

  DMA zone: 125 pages used for memmap

  DMA zone: 0 pages reserved

  DMA zone: 16002 pages, LIFO batch:3

  Normal zone: 0 pages used for memmap

Instruction Cache Enabled

Data Cache Enabled (write-through)

Built 1 zonelists.  Total pages: 16002

Kernel command line: root=/dev/mtdblock0 rw earlyprintk=serial,uart0,57600

Configuring Blackfin Priority Driven Interrupts

PID hash table entries: 256 (order: 8, 1024 bytes)

console handover: boot [early_BFuart0] -> real [ttyBF0]

Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)

Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)

Kernel managed physical pages: 16127

Memory available: 59484k/65536k RAM, (2712k init code, 1218k kernel code, 513k

data, 1024k dma, 584k reserved)

Blackfin Scratchpad data SRAM: 4 KB

Blackfin Data A SRAM: 16 KB (15 KB free)

Blackfin Data B SRAM: 16 KB (16 KB free)

Blackfin Instruction SRAM: 48 KB (42 KB free)

Calibrating delay loop... 1046.52 BogoMIPS (lpj=2093056)

Security Framework v1.0.0 initialized

Mount-cache hash table entries: 512

NET: Registered protocol family 16

Blackfin GPIO Controller

Blackfin DMA Controller

stamp_init(): registering device resources

Generic PHY: Registered new driver

SCSI subsystem initialized

usbcore: registered new interface driver usbfs

usbcore: registered new interface driver hub

usbcore: registered new device driver usb

musb_hdrc: version 6.0, pio, host, debug=0

musb_hdrc: ConfigData=0x00 (UTMI-8)

musb_hdrc: kernel must blacklist external hubs

musb_hdrc: hw_ep 0shared, max 64

musb_hdrc: hw_ep 1tx, max 128

musb_hdrc: hw_ep 1rx, max 128

musb_hdrc: hw_ep 2tx, max 128

musb_hdrc: hw_ep 2rx, max 128

musb_hdrc: hw_ep 3tx, max 128

musb_hdrc: hw_ep 3rx, max 128

musb_hdrc: hw_ep 4tx, max 128

musb_hdrc: hw_ep 4rx, max 128

musb_hdrc: hw_ep 5tx, max 1024

musb_hdrc: hw_ep 5rx, max 1024

musb_hdrc: hw_ep 6tx, max 1024

musb_hdrc: hw_ep 6rx, max 1024

musb_hdrc: hw_ep 7tx, max 1024

musb_hdrc: hw_ep 7rx, max 1024

musb_hdrc: USB Host mode controller at ffc03800 using PIO, IRQ 59

musb_hdrc musb_hdrc.0: MUSB HDRC host driver

musb_hdrc musb_hdrc.0: new USB bus registered, assigned bus number 1

usb usb1: configuration #1 chosen from 1 choice

hub 1-0:1.0: USB hub found

hub 1-0:1.0: 1 port detected

NET: Registered protocol family 2

IP route cache hash table entries: 1024 (order: 0, 4096 bytes)

TCP established hash table entries: 2048 (order: 2, 16384 bytes)

TCP bind hash table entries: 2048 (order: 1, 8192 bytes)

TCP: Hash tables configured (established 2048 bind 2048)

TCP reno registered

JFFS2 version 2.2. (NAND) �© 2001-2006 Red Hat, Inc.

io scheduler noop registered

io scheduler anticipatory registered (default)

io scheduler cfq registered

bfin-otp: initialized

bfin-wdt: initialized: timeout=20 sec (nowayout=0)

Serial: Blackfin serial driver

bfin-uart.1: ttyBF0 at MMIO 0xffc02000 (irq = 31) is a BFIN-UART

RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize

bfin_mac_mdio: probed

bfin_mac: attached PHY driver [Generic PHY] (mii_bus:phy_addr=0:01, irq=-1,

mdc_clk=2500000Hz(mdc_div=25)@sclk=131MHz)

bfin_mac: Version 1.1, Blackfin BF53[67] BF527 on-chip Ethernet MAC driver

m25p80 spi0.1: m25p16 (2048 Kbytes)

Creating 2 MTD partitions on "m25p80":

0x00000000-0x00040000 : "bootloader"

0x00040000-0x00200000 : "linux kernel"

bfin-spi bfin-spi.0: Blackfin BF5xx on-chip SPI Contoller Driver, Version 1.0,

regs_base@ffc00500, dma channel@7

Initializing USB Mass Storage driver...

usbcore: registered new interface driver usb-storage

USB Mass Storage support registered.

ad7877 spi0.2: touchscreen, irq 79

input: AD7877 Touchscreen as /class/input/input0

rtc-bfin rtc-bfin: rtc core: registered rtc-bfin as rtc0

usbcore: registered new interface driver usbhid

drivers/hid/usbhid/hid-core.c: v2.6:USB HID core driver

TCP cubic registered

NET: Registered protocol family 1

NET: Registered protocol family 17

Setting up Blackfin MMR debugfs

rtc-bfin rtc-bfin: setting the system clock to 1970-01-01 01:05:34 (3934)

Freeing unused kernel memory: 2712k freed

root:/> cat /proc/mtd

dev:    size   erasesize  name

mtd0: 00040000 00010000 "bootloader"

mtd1: 001c0000 00010000 "linux kernel"

root:/> mount -t jffs2 /dev/mtdblock1 mnt/

root:/> df

Filesystem           1k-blocks      Used Available Use% Mounted on

/dev/mtdblock1            1792       196      1596  11% /mnt

root:/> cd /mnt/

root:/mnt> ls

test

root:/mnt> cd ..

root:/> cp /bin/busybox /mnt/

root:/> event_test /dev/input/

/dev/input/event0  /dev/input/ts0

root:/> event_test /dev/input/event0

Input driver version is 1.0.0

Input device ID: bus 0x0 vendor 0x0 product 0x0 version 0x0

Input device name: "AD7877 Touchscreen"

Supported events:

  Event type 0 (Reset)

    Event code 0 (Reset)

    Event code 3 (Absolute)

  Event type 3 (Absolute)

    Event code 0 (X)

      Value   2367

      Min        0

      Max     4095

    Event code 1 (Y)

      Value   2430

      Min        0

      Max     4095

    Event code 24 (Pressure)

      Value      0

      Min        0

      Max     1000

Testing ... (interrupt to exit)

Event: time 4021.972458, type 3 (Absolute), code 0 (X), value 2339

Event: time 4021.972485, type 3 (Absolute), code 1 (Y), value 2092

Event: time 4021.972489, type 3 (Absolute), code 24 (Pressure), value 228

Event: time 4021.972492, type 0 (Reset), code 0 (Reset), value 0

Event: time 4022.065412, type 3 (Absolute), code 24 (Pressure), value 0

Event: time 4022.065422, type 0 (Reset), code 0 (Reset), value 0

Event: time 4022.465204, type 3 (Absolute), code 0 (X), value 2388

Event: time 4022.465212, type 3 (Absolute), code 1 (Y), value 2001

Event: time 4022.465216, type 3 (Absolute), code 24 (Pressure), value 386

Event: time 4022.465229, type 0 (Reset), code 0 (Reset), value 0

Event: time 4022.557415, type 3 (Absolute), code 24 (Pressure), value 0

Event: time 4022.557426, type 0 (Reset), code 0 (Reset), value 0

Event: time 4022.835204, type 3 (Absolute), code 0 (X), value 2536

Event: time 4022.835217, type 3 (Absolute), code 1 (Y), value 2308

Event: time 4022.835220, type 3 (Absolute), code 24 (Pressure), value 410

Event: time 4022.835224, type 0 (Reset), code 0 (Reset), value 0

Event: time 4022.925413, type 3 (Absolute), code 24 (Pressure), value 0

Event: time 4022.925423, type 0 (Reset), code 0 (Reset), value 0

Event: time 4023.115208, type 3 (Absolute), code 0 (X), value 2783

Event: time 4023.115219, type 3 (Absolute), code 1 (Y), value 1651

Event: time 4023.115231, type 3 (Absolute), code 24 (Pressure), value 352

Event: time 4023.115244, type 0 (Reset), code 0 (Reset), value 0

Event: time 4023.156493, type 3 (Absolute), code 0 (X), value 2782

Event: time 4023.156514, type 3 (Absolute), code 24 (Pressure), value 353

Event: time 4023.156517, type 0 (Reset), code 0 (Reset), value 0

Event: time 4023.249413, type 3 (Absolute), code 24 (Pressure), value 0

Event: time 4023.249419, type 0 (Reset), code 0 (Reset), value 0

Event: time 4023.413459, type 3 (Absolute), code 0 (X), value 2371

Event: time 4023.413479, type 3 (Absolute), code 1 (Y), value 2024

Event: time 4023.413488, type 3 (Absolute), code 24 (Pressure), value 331

Event: time 4023.413491, type 0 (Reset), code 0 (Reset), value 0

Event: time 4023.505412, type 3 (Absolute), code 24 (Pressure), value 0

Event: time 4023.505419, type 0 (Reset), code 0 (Reset), value 0

---

 

-Bryan

 

--- Steve Strobel                                            2008-10-15 19:19:40

We are also experiencing this problem with uClinux-dist-2008R1.5-RC3 on a custom

BF537 board that is very similar to the BF537 Stamp.  After upgrading from

uClinux-dist-2007R1-RC3, when asserting the SPI chip select for one of our

devices, the chip selects for two other devices get asserted simultaneously.

Interestingly, it doesn't work the other way around;  the other two devices can

be accessed without any interactions. 

 

The two devices with chip selects that work correctly are a M25P128 SPI flash

on SPI_SSEL1 (our boot device, also used for a JFFS2 file system) and a SD card

on SPI_SSEL4.  The one that does not work correctly is a LTC1863 ADC on

SPI_SSEL6 using a simple custom driver that delegates the real work to the SPI

subsystem (please let me know if you want a copy).  The SPI is configured in the

board file as follows:

 

static struct bfin5xx_spi_chip ltc1863_spi_chip_info = {

    .enable_dma = 0,

    .bits_per_word = 16,

};

 

    {

    .modalias = "ltc1863-spi",       

        .max_speed_hz = 2000000,

        .bus_num = 0,

        .chip_select = 6,

        .platform_data = NULL,

        .controller_data = &ltc1863_spi_chip_info,

        .mode = SPI_MODE_0,

    },

 

The only things I changed when upgrading the kernel were the SPI bus number

(from 1 to 0) and omitting the following line from immediately above the

enable_dma line:

 

    .ctl_reg = 0x1000,

 

--- Mike Frysinger                                           2008-10-15 21:16:10

please post the spi settings for every part you're actively using

 

--- Steve Strobel                                            2008-10-22 10:46:13

I use two SPI busses.  Bus 0 is hardware bus (the one we have an issue with)

while bus 2 is a bit-banged SPI bus.  The following is the info for the devices

on bus 0.  The attached file has all of my board definitions, including those

for the other bus (if that is relevant).

 

It is interesting that the ltc1863 chip select (the one that is causing

trouble) is the only one using SPI_MODE_0.

 

static struct bfin5xx_spi_chip spi_flash_chip_info = {

    .enable_dma = 0,

    .bits_per_word = 8,

};

 

static struct bfin5xx_spi_chip spi_mmc_chip_info = {

    .enable_dma = 1,

    .bits_per_word = 8,

};

 

static struct bfin5xx_spi_chip ltc1863_spi_chip_info = {

    .enable_dma = 0,

    .bits_per_word = 16,

};

 

static struct spi_board_info bfin_spi_board_info[] __initdata = {

{

    .modalias = "m25p80",

    .max_speed_hz = 25000000,

    .bus_num = 0,

    .chip_select = 1,

    .platform_data = &bfin_spi_flash_data,

    .controller_data = &spi_flash_chip_info,

    .mode = SPI_MODE_3,

},

{

    .modalias = "spi_mmc_dummy",

    .max_speed_hz = 20000000,

    .bus_num = 0,

    .chip_select = 0,

    .platform_data = NULL,

    .controller_data = &spi_mmc_chip_info,

    .mode = SPI_MODE_3,

},

{

    .modalias = "spi_mmc",

    .max_speed_hz = 20000000,

    .bus_num = 0,

    .chip_select = CONFIG_SPI_MMC_CS_CHAN,

    .platform_data = NULL,

    .controller_data = &spi_mmc_chip_info,

    .mode = SPI_MODE_3,

},

{

    .modalias = "ltc1863-spi",       

    .max_speed_hz = 2000000,

    .bus_num = 0,

    .chip_select = 6,

    .platform_data = NULL,

    .controller_data = &ltc1863_spi_chip_info,

    .mode = SPI_MODE_0,

},

};

 

static struct bfin5xx_spi_master bfin_spi0_info = {

    .num_chipselect = 8,

    .enable_dma = 1,

    .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},

};

 

static struct resource bfin_spi0_resource[] = {

    [0] = {

        .start = SPI0_REGBASE,

        .end   = SPI0_REGBASE + 0xFF,

        .flags = IORESOURCE_MEM,

        },

    [1] = {

        .start = CH_SPI,

        .end   = CH_SPI,

        .flags = IORESOURCE_IRQ,

    },

};

 

static struct platform_device bfin_spi0_device = {

    .name = "bfin-spi",

    .id = 0,

    .num_resources = ARRAY_SIZE(bfin_spi0_resource),

    .resource = bfin_spi0_resource,

    .dev = {

        .platform_data = &bfin_spi0_info,

    },

};

 

--- Mike Frysinger                                           2008-11-14 06:46:33

i think Adam has fixed this in current trunk with the CS changes

 

--- Steve Strobel                                            2010-07-28 13:24:23

I can confirm that this problem was fixed sometime between Linux version

2.6.22.19-ADI-2008R1.5 and 2.6.28.10-ADI-2009R1.1.  It now works fine for me.

 

 

 

    Files

    Changes

    Commits

    Dependencies

    Duplicates

    Associations

    Tags

 

File Name     File Type     File Size     Posted By

No Files Were Found

Attachments

    Outcomes