Friday, July 1, 2016

MMC2 Linux Device Tree Configuration For SD CARD on ARM PART i

Update: 


  • This blog is useful for ARM microprocessors running Linux Kernel versions 4.1.2-ti-r4 to 4.4.0.
  • It could still be relevant for earlier kernel releases but earlier releases have not been tested.
  • If your ARM microprocessor is running kernel's 4.4.16-ti-rt and newer go to part II:

Interfacing a second SD card reader to the Beaglebone Black 

  • I could not find any tutorials or guides in forums on how to interface another SD card to the beaglebone black, so I thought I'd share and show you how I got mine up and running.  I won't explain the device tree bindings in detail but you can use my solution as a reference.


MMC2 PINMUX CONFIGURATION:


Added in file: am335x-bone-common.dtsi

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
mmc3_pins: pinmux_mmc3_pins { 

    pinctrl-single,pins = < 

       0x44 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a1.mmc2_dat0, INPUT_PULLUP | MODE3 */

         0x48 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a2.mmc2_dat1, INPUT_PULLUP | MODE3 */ 

         0x4C (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a3.mmc2_dat2, INPUT_PULLUP | MODE3 */ 

         0x78 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ben1.mmc2_dat3, INPUT_PULLUP | MODE3 */

         0x88 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_csn3.mmc2_cmd, INPUT_PULLUP | MODE3 */ 

         0x8C (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_clk.mmc2_clk, INPUT_PULLUP | MODE3 */ 

         0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a0.gpio1_16 */ 

         0x74 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* mmc2_sdcd, p9_13, Note: Dont know why but we set card detect pinout to be GPIO */ 

         0x15c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mmc2_sdwp, p9_17, Note: Write protect is not configured in the device tree settings*/ 

    >; 

};
 

  • Note that the mmc0, mmc1, and mmc2 lines on the beaglebone refer to mmc1, mmc2, and mmc3 in the device tree.


1
2
3
4
         0x88 (PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_csn3.mmc2_cmd, INPUT_PULLUP | MODE3 */ 
                    ...
                    ...
         0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a0.gpio1_16 */ 

  • You can see that the two lines are connected:





MMC2 DEVICE TREE BINDINGS:




Added in file: am335x-bone-common.dtsi


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
&mmc3 {
      vmmc-supply = <&vmmcsd_fixed>;
      ti,dual-volt;
      ti,needs-special-reset;
      ti,needs-special-hs-handling;
      pinctrl-names = "default";
      pinctrl-0 = <&mmc3_pins>;
      cd-gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
      cd-inverted;
      bus-width = <4>;
      max-frequency = <25000000>;
      dmas = <&edma 12
              &edma 13>;
      dma-names = "tx", "rx";
      status = "okay";
};

&edma {
 ti,edma-xbar-event-map = /bits/ 16 <1 12 
                                     2 13>;

};
 


    18 Comments:

    At August 22, 2016 at 10:25 AM , Blogger Unknown said...

    I'm getting the following message in the kernel log:
    /ocp/mmc@47810000: could not get #dma-cells for /ocp/l4_wkup@44c00000/prcm@200000/clocks/dpll_disp_ck

    Also I've read somewhere that MMC2 must be enabled in u-boot, I've recompiled u-boot with the corresponding changes, however there is no clock signal on the pin although u-boot does show MMC2 in the list.

     
    At August 22, 2016 at 8:46 PM , Blogger Thomas said...

    This comment has been removed by the author.

     
    At August 22, 2016 at 9:02 PM , Blogger Unknown said...

    Regarding the "mmc3" in "am33xx.dtsi": that's exactly what I have, I haven't touched that part.

    In u-boot code I've modified several files and enabled clock. Will provide details later, since it's in my workplace computer. Do you think I could screw up something in u-boot, and that's why your way doesn't work? I'll revert back to the standard u-boot and check.

    Thanks!

     
    At August 22, 2016 at 9:03 PM , Blogger Unknown said...

    Regarding the "mmc3" in "am33xx.dtsi": that's exactly what I have, I haven't touched that part.

    In u-boot code I've modified several files and enabled clock. Will provide details later, since it's in my workplace computer. Do you think I could screw up something in u-boot, and that's why your way doesn't work? I'll revert back to the standard u-boot and check.

    Thanks!

     
    At August 22, 2016 at 9:09 PM , Blogger Thomas said...

    You should also check your edma settings in am33xx.dtsi. Does #dma-cells = <1> for you?

     
    At August 22, 2016 at 9:11 PM , Blogger Thomas said...

    What steps did you take to enable mmc2 in u-boot? Configuring mmc2 in u-boot might not be necessary.
    Also, what are your "mmc3:" settings that is located in am33xx.dtsi? it should look something like:

    mmc3: mmc@47810000 {
    compatible = "ti,omap4-hsmmc";
    ti,hwmods = "mmc3";
    ti,needs-special-reset;
    interrupts = <29>;
    interrupt-parent = <&intc>;
    reg = <0x47810000 0x1000>;
    status = "disabled";
    };

     
    At August 23, 2016 at 8:27 AM , Blogger Unknown said...

    Below is what I have for edma in am33xx.dtsi:
    ------------------------8<------------------------
    edma: edma@49000000 {
    compatible = "ti,edma3-tpcc";
    ti,hwmods = "tpcc";
    reg = <0x49000000 0x10000>;
    reg-names = "edma3_cc";
    interrupts = <12 13 14>;
    interrupt-names = "edma3_ccint", "emda3_mperr",
    "edma3_ccerrint";
    dma-requests = <64>;
    #dma-cells = <2>;

    ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
    <&edma_tptc2 0>;
    ti,edma-memcpy-channels = <20 21>;
    };
    ------------------------8<------------------------
    #dma-cells = <2> and assigning 1 or 3 makes it freeze when booting at:
    ------------------------8<------------------------
    Starting kernel ...

    [ 0.001297] clocksource_probe: no matching clocksources found
    [ 1.889323] wkup_m3_ipc 44e11324.wkup_m3_ipc: could not get rproc handle
    [ 2.073446] omap_hsmmc 481d8000.mmc: RX DMA channel request failed
    [ 2.093261] omap_hsmmc 47810000.mmc: RX DMA channel request failed
    [ 2.126905] omap_voltage_late_init: Voltage driver support not added
    [ 2.134621] PM: Cannot get wkup_m3_ipc handle
    [ 2.232672] bone_capemgr bone_capemgr: slot #0: No cape found
    [ 2.276667] bone_capemgr bone_capemgr: slot #1: No cape found
    [ 2.320666] bone_capemgr bone_capemgr: slot #2: No cape found
    [ 2.364666] bone_capemgr bone_capemgr: slot #3: No cape found
    ------------------------8<------------------------

     
    At August 23, 2016 at 8:41 AM , Blogger Unknown said...

    Thomas, I tried your method with the standard u-boot too, but got the same unsuccessful result...

    Here are the changes to u-boot I made, but there is no clock on the pin:

    1) mux.c
    added pins description

    2) board.c:
    added call to
    omap_mmc_init(2, 0, 0, -1, -1);

    3) mmc_host_def.h
    added the base address
    #define OMAP_HSMMC3_BASE 0x47810100

    4) spl.h
    added boot device
    #define BOOT_DEVICE_MMC3 0x10

    5) clock_am33xx.c
    added clock to the array
    clk_modules_explicit_en[]
    ... , &cmper->mmc2clkctrl, ...
    used by:
    do_enable_clocks(clk_domains, clk_modules_explicit_en, 1)

    6) clock_ti814x.c
    added clock control
    writel(PRCM_MOD_EN, &cmalwon->mmchs2clkctrl);
    while (readl(&cmalwon->mmchs2clkctrl) != PRCM_MOD_EN)
    ;

     
    At August 23, 2016 at 1:23 PM , Blogger Thomas said...

    This comment has been removed by the author.

     
    At August 23, 2016 at 1:24 PM , Blogger Thomas said...

    Hmmm I see, yeah changing #dma-cells to <1> wouldnt work since eDMA3 needs 2 cells, 1 for the channel controller and the other for the transfer controller.

    I'm curious, what kernel version are you using for your microprocessor?

     
    At August 23, 2016 at 1:33 PM , Blogger Unknown said...

    I'm using 4.4.16-ti-rt kernel (before it was 4.4.8-ti-rt).

     
    At August 23, 2016 at 3:53 PM , Blogger Thomas said...

    My suggestion would be to first revert back to the standard u-boot then check the mmc3:" settings that is located in am33xx.dtsi to see if anything has changed. Then just interface the SD card to the microprocessor, making sure that the wiring is correct. Next add the pinmux configuration and bindings for mmc3. recompile and reboot and check the kernel log.

    My guess is that you just need to configure the device tree correctly without using u-boot. The only problem would be the edma settings. In my situation my edma was configured to use 1 channel per DMA request, a "DEPRECATED binding" which is stated in this document:

    http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/dma/ti-edma.txt

    I believe to get mmc3 working you need to use the DEPRECATED edma binding in order to have the Crossbar event to channel map property: "ti,edma-xbar-event-map" because mmc3's source modules are crossbar mapped using events 1 and 2.

    One idea i have is to replace your current edma binding in am33xx.dtsi with the DEPRECATED binding (The binding I use):

    edma: edma@49000000 {
    compatible = "ti,edma3";
    ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
    reg = <0x49000000 0x10000>,
    <0x44e10f90 0x40>;
    interrupts = <12 13 14>;
    #dma-cells = <1>;
    };

    then configure mmc3 and edma like i show you in this tutorial.
    ...
    ...
    If you still decide to use uboot, have you tried defining OMAP_HSMMC3_BASE as 0x47810000 instead of 0x47810100 ?


     
    At August 24, 2016 at 8:41 AM , Blogger Unknown said...

    Thank you, Thomas!
    I reverted back to the standard u-boot and changed the edma configuration to deprecated binding. Now I have both mmc0 and mmc2 DMA channels errors and boot process stops at:

    [ 2.356078] omap_hsmmc 48060000.mmc: RX DMA channel request failed
    [ 2.381924] omap_hsmmc 47810000.mmc: RX DMA channel request failed
    [ 2.400342] omap_hsmmc 48060000.mmc: RX DMA channel request failed
    [ 2.418247] omap_hsmmc 47810000.mmc: RX DMA channel request failed

    ...Regarding u-boot OMAP_HSMMC3_BASE: I just followed existing definitions in arch-am33xx/mmc_host_def.h, they all use that 0x100 offset:

    #define OMAP_HSMMC1_BASE 0x48060100
    #define OMAP_HSMMC2_BASE 0x481D8100
    #define OMAP_HSMMC3_BASE 0x47810100

    However, if you were able to make mmc2 work without messing with u-boot, I'd prefer your way.

     
    At August 24, 2016 at 3:04 PM , Blogger Unknown said...

    I was able to make it work by adding:
    #address-cells = <1>;
    #size-cells = <0>;

    &mmc3 {
    vmmc-supply = <&vmmcsd_fixed>;
    ti,dual-volt;
    ti,needs-special-reset;
    ti,needs-special-hs-handling;
    pinctrl-names = "default";
    pinctrl-0 = <&mmc3_pins>;
    cd-gpios = <&gpio3 16 GPIO_ACTIVE_LOW>;
    bus-width = <4>;
    max-frequency = <25000000>;

    dmas = <&edma_xbar 12 0 1
    &edma_xbar 13 0 2>;

    #address-cells = <1>;
    #size-cells = <0>;

    dma-names = "tx", "rx";
    status = "okay";
    };

    Thank you for advices and directions, Thomas!

     
    At August 24, 2016 at 4:27 PM , Blogger Thomas said...

    Great Sergey, that's good to hear! I see that there was a recent patch for the edma3 bindings for edma_xbar.

    Did you get mmc3 to work with the original u-boot configuration and original edma settings that's configured in am33xx.dtsi?

     
    At August 24, 2016 at 6:56 PM , Blogger Unknown said...

    Yes, I used the original u-boot and original edma settings. Also I DID NOT need edma events map:

    &edma {
    ti,edma-xbar-event-map = /bits/ 16 <1 12 2 13>;
    };

     
    At August 25, 2016 at 1:40 AM , Blogger Thomas said...

    Okay thanks for letting my know. I'm gonna have to update my blog now haha

     
    At September 7, 2021 at 9:00 AM , Blogger Unknown said...

    Thank you all for this information!

    With it, I've managed to get mmc0, mmc1, and mmc2 working on our board, based on the beaglebone black. I'm using kernel 5.10.59-bone49.

     

    Post a Comment

    Subscribe to Post Comments [Atom]

    << Home