Bug 196081 - [PATCH] ARM: sunxi: Add driver for the MMC/SD host found in the Allwinner A10 SoC
Summary: [PATCH] ARM: sunxi: Add driver for the MMC/SD host found in the Allwinner A10...
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: CURRENT
Hardware: arm Any
: --- Affects Many People
Assignee: Luiz Otavio O Souza,+55 (14) 99772-1255
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-12-18 02:07 UTC by Martin Galvan
Modified: 2015-07-04 16:55 UTC (History)
9 users (show)

See Also:


Attachments
sunxi MMC/SD device driver (45.73 KB, patch)
2014-12-18 02:07 UTC, Martin Galvan
omgalvan.86: maintainer-approval? (imp)
omgalvan.86: maintainer-approval? (ian)
Details | Diff
Boot log and backtrace of kernel panic at boot (8.66 KB, text/plain)
2014-12-28 14:25 UTC, Bas Vermin
no flags Details
Possible bug fix in the MMC/SD driver. (802 bytes, patch)
2015-03-29 04:49 UTC, Pratik Singhal
no flags Details | Diff
Patch for adding DMA support to the MMC driver (15.67 KB, patch)
2015-06-21 08:04 UTC, Pratik Singhal
ps06756: maintainer-approval?
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Galvan 2014-12-18 02:07:45 UTC
Created attachment 150704 [details]
sunxi MMC/SD device driver

This is the device driver for the SD/MMC host controller found in Allwinner A10 SoCs. The original driver was written by Alexander Fedorov back in October 2013; however that version was lacking some features and had a couple of bugs that caused the kernel to panic when trying to boot. This version aims to correct those mistakes, as well as serving as a sort of documentation on this particular host, since the Allwinner datasheet is only available in Chinese language and one has to sign an NDA in order to get it.

Most of the work consisted in reverse-engineering the Linux and U-Boot drivers. Some of the registers and the DMA scheme used by this host are similar to the ones on the Synopsys Designware SD Host Controller and the Altera Arria V family of SoCs; as such we based some of our work on the datasheets for those hosts.

Right now the driver supports multiblock programmed I/O only. While that gives us a fairly decent performance, ideally we should add support for DMA. We already have a version which can perform DMA transfers, however we noticed the transferred data always ends up being corrupted. I'll be sending the DMA version after this one is reviewed an commited.

We left Alexander's name in the driver's copyright header as it's fair since he wrote the first version. We also made some changes to other files besides a10_mmc.c and a10_mmcreg.h; as those changes were relatively minor we didn't think it was necessary for us to include our names in the header.

As this is our first contribution to the project, any feedback is more than welcome. So far we've tested it with a few different microSD cards; it would be great if anyone could try using an actual MMC card.
Comment 1 Bas Vermin 2014-12-28 14:23:33 UTC
Hi,

I just tested your patch and I have a few comments.

First of all, thanks a lot for working on this!

In your patch a10_mmc.c tries to import a10_mmc.h instead of a10_mmcreg.h. So it doesn't build, but this was easy to fix.

After that I tried to boot the kernel and seem to be getting the same panic as Alexander Fedorov's patch. My knowledge of debugging this kind of stuff is very bad, so I attached the boot log and backtrace.

Bas
Comment 2 Bas Vermin 2014-12-28 14:25:41 UTC
Created attachment 151035 [details]
Boot log and backtrace of kernel panic at boot
Comment 3 Martin Galvan 2014-12-28 18:59:38 UTC
(In reply to Bas Vermin from comment #1)
> Hi,
> 
> I just tested your patch and I have a few comments.
> 
> First of all, thanks a lot for working on this!
> 
> In your patch a10_mmc.c tries to import a10_mmc.h instead of a10_mmcreg.h.
> So it doesn't build, but this was easy to fix.

Sorry about that! Must've been a leftover from a previous version where a10_mmcreg.h was called a10_mmc.h. Will fix it in the next version.

> After that I tried to boot the kernel and seem to be getting the same panic
> as Alexander Fedorov's patch. My knowledge of debugging this kind of stuff
> is very bad, so I attached the boot log and backtrace.

That's interesting. From the boot log I can see you're testing it on a Hackberry; I made it work on a Cubieboard. I'll take a look at it and see what I can find.

Thanks a lot!
Comment 4 Bas Vermin 2014-12-28 19:57:56 UTC
Hey Martin,

I totally forgot to mention it actually is a Cubieboard 1, 1024MB edition.
I am using the u-boot that was described on the Cubieboard wiki page
https://wiki.freebsd.org/FreeBSD/arm/Cubieboard
Seems to be a version for the Hackberry.

I updated to the latest spl and u-boot specifically for the Cubieboard,
but this made no difference.

Thanks for the quick response.

Bas
Comment 5 Martin Galvan 2014-12-28 20:05:15 UTC
(In reply to Bas Vermin from comment #4)
> Hey Martin,
> 
> I totally forgot to mention it actually is a Cubieboard 1, 1024MB edition.
> I am using the u-boot that was described on the Cubieboard wiki page
> https://wiki.freebsd.org/FreeBSD/arm/Cubieboard
> Seems to be a version for the Hackberry.

It's ok, that's the same configuration I'm using.

> I updated to the latest spl and u-boot specifically for the Cubieboard,
> but this made no difference.

It's definitely a driver problem. I developed this driver on 10.0 stable, so I'm suspecting something changed between versions. I smoke-tested it on current before submitting this though, but maybe something changed. Unfortunately I won't be able to resume work on this until february, as I don't have the actual board with me right now. If you would be so kind to test this on 10.0 just to be sure it's still working it would be great, if not don't worry, I'll handle it as soon as I can :)

Again, thanks a lot.
Comment 6 Pratik Singhal 2015-03-29 04:49:54 UTC
Created attachment 154947 [details]
Possible bug fix in the MMC/SD driver.

In the a10_mmc_reset_controller function, the purpose of the do while loop is to wait till the register reset is done or time out has occurred. 

In the current code, the do while loop will continue to loop if the reset is done but timeout is not done. Also, it will exit if the reset is not done instead of waiting for the time out to occur. The patch corrects this. 

In the a10_mmc_attach function, the maximum value of operable frequency is termed as 50Hz, but it is coded as 52MHz which I have changed.
Comment 7 Martin Galvan 2015-03-29 19:05:49 UTC
(In reply to Pratik Singhal from comment #6)
I looked at the patch you sent. Did you actually test this on the
board with CURRENT? The reason I'm asking is that I don't think that
patch could work as intended.

You're doing:

do {
    reg_value = a10_mmc_read_4(sc, A10_MMC_GLOBAL_CONTROL_REG);
} while ((!reg_value & A10_MMC_HARDWARE_RESET_BITS) && (--time_left));

Do you realize the ! is zeroing reg_value before it gets AND-ed with
A10_MMC_HARDWARE_RESET_BITS? I think what you wanted to do was:

!(reg_value & A10_MMC_HARDWARE_RESET_BITS)

Now, I don't remember every detail of how the host worked, but I
recall I had to wait while the hardware reset bits were set on the
global control reg; it would be safe to proceed only after those bits
were cleared. I think the hardware automatically clears those bits
after the reset is finished. I may be wrong, though.

The problem Bas reported sounds to me like a NULL pointer being
dereferenced somewhere, or something like that. I think that may be
the cause because we'd always get a translation fault when doing
something like that, while waiting forever would usually just cause
the system to hang.
Comment 8 commit-hook freebsd_committer freebsd_triage 2015-05-21 17:39:46 UTC
A commit references this bug:

Author: loos
Date: Thu May 21 17:39:44 UTC 2015
New revision: 283253
URL: https://svnweb.freebsd.org/changeset/base/283253

Log:
  Add the MMC/SD driver for Allwinner SoCs.

  This is based on the patch sent by Alexander Fedorov with the following
  fixes/improvements:

   - Better error handling;
   - Clock is derived from PLL6 (obtained from netbsd);
   - No more unnecessary busy loops on interrupt handler;
   - style(9) fixes and code cleanup.

  I also want to thanks Martin Galvan who has sent an alternative
  implementation with some interesting fixes.

  Tested on CubieBoard2, Banana-Pi (thanks to netgate!) and Cubieboard1
  (Pratik Singhal).

  This is intended to pave the way for the upcoming GSoC work (and make
  easier the build of images for the supported boards).

  PR:		196081
  Submitted by:	Alexander Fedorov <alexander.fedorov@rtlservice.com>

Changes:
  head/sys/arm/allwinner/a10_clk.c
  head/sys/arm/allwinner/a10_clk.h
  head/sys/arm/allwinner/a10_mmc.c
  head/sys/arm/allwinner/a10_mmc.h
  head/sys/arm/allwinner/files.allwinner
  head/sys/arm/conf/CUBIEBOARD
  head/sys/arm/conf/CUBIEBOARD2
  head/sys/boot/fdt/dts/arm/cubieboard.dts
  head/sys/boot/fdt/dts/arm/cubieboard2.dts
  head/sys/boot/fdt/dts/arm/sun4i-a10.dtsi
  head/sys/boot/fdt/dts/arm/sun7i-a20.dtsi
  head/sys/dev/mmc/mmc.c
Comment 9 Pratik Singhal 2015-06-21 08:04:51 UTC
Created attachment 157917 [details]
Patch for adding DMA support to the MMC driver

This patch adds support for DMA I/O in the current implementation of the MMC driver for Allwinner A10 Soc. . I have tested in on Allwinner A10 Soc (Cubieboard 1). It is submitted as part of my Google summer of code 2015 project.
Comment 10 Luiz Otavio O Souza,+55 (14) 99772-1255 freebsd_committer freebsd_triage 2015-07-04 16:55:04 UTC
SD/MMC driver committed to -head with DMA support.

Many thanks to everyone involved.