Discussion:
i.MX27: enable SDIO pull-up resistors
Peter Wurmsdobler
2008-01-14 10:34:05 UTC
Permalink
Hello,

On an i.MX27ADS board I am trying out two different types of an SDIO
peripheral. One is fitted with pull-up resistors on SDIO_DATA[0..3], the
other not. The former works properly, the latter not. That's why I would
like to enable SDIO pull-up resistors, but unfortunately, I do not know
how to do it, other than writel(value,IO_ADDRESS(base)+offset); Where
are these adresss defined?

Thanks for any hints,
peter


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Russell King - ARM Linux
2008-01-14 10:51:04 UTC
Permalink
Post by Peter Wurmsdobler
On an i.MX27ADS board I am trying out two different types of an SDIO
peripheral. One is fitted with pull-up resistors on SDIO_DATA[0..3], the
other not. The former works properly, the latter not. That's why I would
like to enable SDIO pull-up resistors, but unfortunately, I do not know
how to do it, other than writel(value,IO_ADDRESS(base)+offset); Where
are these adresss defined?
I can't answer your question. However...

Beware - there are some SoCs out there which adverise having programmable
pull up resistors, and people have thought "great, lets use that for the
MMC/SD/SDIO lines" only to find things still didn't work.

Before relying upon SoC integrated programmable pull up resistors, I
suggest you check their value and the tolerance on them to ensure that
they will reliably do the job, otherwise you're on a hiding to nothing
and might as well spend your time adding the external resistors.

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Joe
2008-01-14 11:09:19 UTC
Permalink
Post by Russell King - ARM Linux
Beware - there are some SoCs out there which adverise having programmable
pull up resistors, and people have thought "great, lets use that for the
MMC/SD/SDIO lines" only to find things still didn't work.
Before relying upon SoC integrated programmable pull up resistors, I
suggest you check their value and the tolerance on them to ensure that
they will reliably do the job, otherwise you're on a hiding to nothing
and might as well spend your time adding the external resistors.
I'd second that, with the AT91RM9200 in mind...

Greetz Joe
--
Sepp "ZaP" Holzmayr

please reply to:
***@gmail.com

watch out for:
www.rocksociety.de

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Mark Powell
2008-01-14 11:20:46 UTC
Permalink
Post by Peter Wurmsdobler
Hello,
On an i.MX27ADS board I am trying out two different types of an SDIO
peripheral. One is fitted with pull-up resistors on SDIO_DATA[0..3], the
other not. The former works properly, the latter not. That's why I would
like to enable SDIO pull-up resistors, but unfortunately, I do not know
how to do it, other than writel(value,IO_ADDRESS(base)+offset); Where
are these adresss defined?
The SDIO spec says that pull-up resistors should be on the controller
not the peripheral.

It's a while since I used the i.MX27ADS, but IIRC it has a weak pull-up
(~100K) on D0 and nothing on D1-D3. To make it work, we had to replace a
resistor on the main board and change some GPIO settings. I'm very
sorry, I no longer have the info on what to change :(

Mark Powell

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Peter Wurmsdobler
2008-01-14 12:03:22 UTC
Permalink
Hello,
Post by Mark Powell
It's a while since I used the i.MX27ADS, but IIRC it has a weak pull-up
(~100K) on D0 and nothing on D1-D3. To make it work, we had to replace a
resistor on the main board and change some GPIO settings. I'm very
sorry, I no longer have the info on what to change :(
What a pitty. There is definitely something going on with wrong resistors.

The correctly working SDIO module (with pull-ups fitted) shows on a
scope nice and crisp time signals with proper square transitions. The
other one exposes from time to time slower transients comming from a
higher voltage.

peter


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
David Vrabel
2008-01-15 11:58:03 UTC
Permalink
Post by Peter Wurmsdobler
Hello,
Post by Mark Powell
It's a while since I used the i.MX27ADS, but IIRC it has a weak pull-up
(~100K) on D0 and nothing on D1-D3. To make it work, we had to replace a
resistor on the main board and change some GPIO settings. I'm very
sorry, I no longer have the info on what to change :(
What a pitty. There is definitely something going on with wrong resistors.
The correctly working SDIO module (with pull-ups fitted) shows on a
scope nice and crisp time signals with proper square transitions. The
other one exposes from time to time slower transients comming from a
higher voltage.
This doesn't sound like anything to do with pull-ups. Missing pull-ups
will result in D[0:3] being low while idle and consequentially when
transferring data the initial falling edge of the start bit (0) will be
missing.

David
--
David Vrabel, Senior Software Engineer, Drivers Tel: +44 (0)1223 692562
CSR, Churchill House, Cambridge Business Park, Cowley Road, CB4 0WZ

-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Michael Bergandi
2008-01-14 13:44:45 UTC
Permalink
Post by Peter Wurmsdobler
Hello,
On an i.MX27ADS board I am trying out two different types of an SDIO
peripheral. One is fitted with pull-up resistors on SDIO_DATA[0..3], the
other not. The former works properly, the latter not. That's why I would
like to enable SDIO pull-up resistors, but unfortunately, I do not know
how to do it, other than writel(value,IO_ADDRESS(base)+offset); Where
are these adresss defined?
AFAIK, there is no API defined for configuring pads on the iMX27. The
default
pull-ups are being set to 22K for both of the SD host controllers. Look in:

/arch/arm/mach-mx27/mx27ads_gpio.c

for gpio_sdhc_active(). You will see that this is essentially the same thing
that you are already doing.

Hope this answers the how and where :)
Post by Peter Wurmsdobler
Thanks for any hints,
peter
-------------------------------------------------------------------
http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
--
Michael Bergandi
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Peter Wurmsdobler
2008-01-14 15:56:27 UTC
Permalink
Hello,
Post by Michael Bergandi
/arch/arm/mach-mx27/mx27ads_gpio.c
for gpio_sdhc_active(). You will see that this is essentially the same thing
that you are already doing.
Am I?
Post by Michael Bergandi
Hope this answers the how and where :)
Well, yes and no. I can see the code and I see that a u16 data is read,
|= 0x0c'ed and written back to the same address. But I do not understand
what register is written too, nor the value 0x0c.

Also, does it only affect data3, and not data0-2 ?

peter


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Michael Bergandi
2008-01-14 18:06:55 UTC
Permalink
Post by Peter Wurmsdobler
Hello,
Post by Michael Bergandi
/arch/arm/mach-mx27/mx27ads_gpio.c
for gpio_sdhc_active(). You will see that this is essentially the same
thing
Post by Michael Bergandi
that you are already doing.
Am I?
Well, maybe I was a little over presumptuous. You said that you knew how to
do
this using writel(value,IO_ADDRESS(base)+offset). That is essentially what
is done
by __raw_writew().
Post by Peter Wurmsdobler
Post by Michael Bergandi
Hope this answers the how and where :)
Well, yes and no. I can see the code and I see that a u16 data is read,
The register being read is 32 bit, but only the lower 16 are meaningful.
Post by Peter Wurmsdobler
|= 0x0c'ed and written back to the same address. But I do not understand
what register is written too, nor the value 0x0c.
/* 22k pull up for sd1 dat3 pins */
data = __raw_readw(IO_ADDRESS(SYSCTRL_BASE_ADDR + 0x54));
data |= 0x0c;
__raw_writew(data, IO_ADDRESS(SYSCTRL_BASE_ADDR + 0x54));
Post by Peter Wurmsdobler
From /include/asm/arch-mxc/mx27.h
./mx27.h:#define SYSCTRL_BASE_ADDR (AIPI_BASE_ADDR + 0x27800)
./mx27.h:#define AIPI_BASE_ADDR 0x10000000
./mx27.h:#define AIPI_BASE_ADDR_VIRT 0xD4000000

Putting all that together, you get to 0x1002_7854, the PSCR (Pull Strength
Control
Register), according to the iMX27 Reference Manual. If you don't have the
manual,
you can download it from Freescale.

This register effects only the dat3 pin. The dat3 pin is sometimes pulled
low for card
detection. In this case, it is being pulled with a 22K resister. However, it
could be set
to use a 47K or 100K. It can also be pulled down with a 100K. The other
lines are
pulled high using internal 69K resistors by default. They can be turned off
by writing
the appropriate value to the corresponding PUEN (Pull Up ENable) register.
For this,
you can use gpio_set_puen(iomux_pin_name_t pin, bool en) in gpio_mux.c.
Post by Peter Wurmsdobler
Also, does it only affect data3, and not data0-2 ?
Yes, the code in mx27ads_gpio.c only affects the dat3 pull up value. It is
the only line
that you can set to different resistance values. The others are on/off only.
Post by Peter Wurmsdobler
peter
--
Michael Bergandi
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Peter Wurmsdobler
2008-01-15 14:52:17 UTC
Permalink
Hello,

Many thanks for all the information.
Post by Michael Bergandi
Putting all that together, you get to 0x1002_7854, the PSCR (Pull
Strength Control Register), according to the iMX27 Reference Manual.
Cheers, found it, 4.2.19 explains all that.

Stupid question: the address ought to be 0x10027854, however

printk("0x%x",IO_ADDRESS(SYSCTRL_BASE_ADDR+0x54))

prints 0xd4027854, the virtual address. Why is that so?
Post by Michael Bergandi
The other lines are pulled high using internal 69K resistors by default.
From what I understand now:

SD2:

- D0, D1, D2, D3, CMD and CLK can be set either of 100k down, 100k up,
47k up, or 22k up, by writing to the PSCR register, bits 15-4.
- D0, D1, D2, D3, CLK and CMD can be pull-up enabled by using
gpio_set_puen(MX27_PIN_SD2_D0,1) etc.

SD1:

- only D3 can be set either of 100k down, 100k up, 47k up, or 22k up, by
writing to the PSCR register, bits 3-2.
- D0, D1, D2, CLK and CMD are fitted with fixed pull-up resistors (69k)

one question remains for me: can all lines still be en/disabled? What
happens using gpio_set_puen(MX27_PIN_SD1_D0,1) for SD1?

Anyway, I have now added a few lines in gpio_sdhc_active() that enable
the pull-ups for D0-3 and CLK for both SD1 and SD2 using gpio_set_puen.
However, my original problem is still not resolved: the module does not
work.

The SDIO module is called apm6628 and contains a CSR (Cambridge Silicon
Radio) UniFi WiFi chip together with a BlueTooth chip. As far I am
aware, it does not contain any pull-up resistors on board.

The driver I use is CSR's unifi driver, v3.0.2 which works with a
simpler module, called 1824V3, that has only a WiFi chip onit _and_ pull
up resistors fitted. As this is the only obvious difference, my
assumption was that the pull-up resistors are the culprits for the the
driver not working.

Booting the system (with the capricious apm6628 module without
pull-ups), and inserting the unifi_sdio kernel module generates the
following error:

unifi:Chip ID 0x1301
unifi:needs firmware
unifi:downloading loader...
unifi:downloading firmware...
unifi:unable to set CM53: dir=1, block=1, addr=0x1, len=0x20
unifi:Block write failed
unifi:CMD53 failed writing 2048 bytes to handle 1
unifi:Failed to copy block to UniFi after 45044 bytes of 200272
unifi:Secondary download failed after 16348 bytes
unifi:Failed to download image using secondary loader
unifi:Failed to download firmware.

I still wonder what is going wrong. What might be the reason that CM53
cannot be set sucessfully? Might it be something stupid like too long
cables on the development board?

Regards and thanks,
peter


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Michael Bergandi
2008-01-15 15:33:39 UTC
Permalink
Post by Peter Wurmsdobler
Hello,
Many thanks for all the information.
Post by Michael Bergandi
Putting all that together, you get to 0x1002_7854, the PSCR (Pull
Strength Control Register), according to the iMX27 Reference Manual.
Cheers, found it, 4.2.19 explains all that.
Stupid question: the address ought to be 0x10027854, however
printk("0x%x",IO_ADDRESS(SYSCTRL_BASE_ADDR+0x54))
prints 0xd4027854, the virtual address. Why is that so?
This is due the use of virtual memory in the kernel. Some address spaces
need
to be remapped. You will need to investigate that on your own.
Post by Peter Wurmsdobler
Post by Michael Bergandi
The other lines are pulled high using internal 69K resistors by default.
- D0, D1, D2, D3, CMD and CLK can be set either of 100k down, 100k up,
47k up, or 22k up, by writing to the PSCR register, bits 15-4.
- D0, D1, D2, D3, CLK and CMD can be pull-up enabled by using
gpio_set_puen(MX27_PIN_SD2_D0,1) etc.
- only D3 can be set either of 100k down, 100k up, 47k up, or 22k up, by
writing to the PSCR register, bits 3-2.
- D0, D1, D2, CLK and CMD are fitted with fixed pull-up resistors (69k)
one question remains for me: can all lines still be en/disabled? What
happens using gpio_set_puen(MX27_PIN_SD1_D0,1) for SD1?
If I recall correctly, the pull-ups on these lines are _on_ when the chip
powers
up, according to the SD host controller section of the reference manual. You

can verify this by reading the pull-up enable register. However, setting
them
again can't hurt anything. The pull-ups can also be disabled using the same
function allowing you to add your own pull-ups.
Post by Peter Wurmsdobler
Anyway, I have now added a few lines in gpio_sdhc_active() that enable
the pull-ups for D0-3 and CLK for both SD1 and SD2 using gpio_set_puen.
However, my original problem is still not resolved: the module does not
work.
The SDIO module is called apm6628 and contains a CSR (Cambridge Silicon
Radio) UniFi WiFi chip together with a BlueTooth chip. As far I am
aware, it does not contain any pull-up resistors on board.
The driver I use is CSR's unifi driver, v3.0.2 which works with a
simpler module, called 1824V3, that has only a WiFi chip onit _and_ pull
up resistors fitted. As this is the only obvious difference, my
assumption was that the pull-up resistors are the culprits for the the
driver not working.
Booting the system (with the capricious apm6628 module without
pull-ups), and inserting the unifi_sdio kernel module generates the
unifi:Chip ID 0x1301
unifi:needs firmware
unifi:downloading loader...
unifi:downloading firmware...
unifi:unable to set CM53: dir=1, block=1, addr=0x1, len=0x20
unifi:Block write failed
unifi:CMD53 failed writing 2048 bytes to handle 1
unifi:Failed to copy block to UniFi after 45044 bytes of 200272
unifi:Secondary download failed after 16348 bytes
unifi:Failed to download image using secondary loader
unifi:Failed to download firmware.
I still wonder what is going wrong. What might be the reason that CM53
cannot be set sucessfully? Might it be something stupid like too long
cables on the development board?
It is possible that an excessively long cable may cause you to have timing
violations, but I'm not so sure that is the problem.

I'm afraid my SDIO experience is minimal. Hopefully someone else can give
more insight as to the behavior you are seeing. I do suggest trying the
Freescale support (***@freescale.com) and the vendor's support
channel.
Post by Peter Wurmsdobler
Regards and thanks,
peter
--
Michael Bergandi
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Peter Wurmsdobler
2008-01-15 15:51:23 UTC
Permalink
Hello,
Post by Michael Bergandi
Post by Peter Wurmsdobler
cannot be set sucessfully? Might it be something stupid like too long
cables on the development board?
It is possible that an excessively long cable may cause you to have timing
violations, but I'm not so sure that is the problem.
As a matter of fact, this is what is was. We have cut the cable that
came with the apm6628, hence reduced the length from 20cm to 2cm. Now it
works! I had not questioned the hardware provided.

Thanks again to all helping me to find the problem. I hope that you can
benefit from this shared experience.

Regards,
peter


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Loading...