MMCHS driver for OMAP4 platform.
authorGerd Zellweger <mail@gerdzellweger.com>
Wed, 4 Sep 2013 15:33:59 +0000 (17:33 +0200)
committerGerd Zellweger <mail@gerdzellweger.com>
Thu, 5 Sep 2013 07:43:54 +0000 (09:43 +0200)
Simple driver that can read and write blocks one-at-the-time
on a SDHC card on the pandaboard. We currently don't support SD or MMC cards.
The code was written to for the AOS course at ETH.

Also contains an implementation for the ata_rw28 interface to work with the VFS
FAT implementation.

23 files changed:
devices/Hakefile
devices/omap/omap44xx_mmchs.dev [deleted file]
devices/ti_twl6030.dev
errors/errno.fugu
if/Hakefile
include/arch/arm/omap44xx/device_registers.h
usr/drivers/omap44xx/mmchs/Hakefile
usr/drivers/omap44xx/mmchs/cm2.c
usr/drivers/omap44xx/mmchs/ctrlmod.c
usr/drivers/omap44xx/mmchs/i2c.c
usr/drivers/omap44xx/mmchs/i2c.h [moved from kernel/include/arch/armv7/ti_i2c.h with 92% similarity]
usr/drivers/omap44xx/mmchs/main.c [new file with mode: 0644]
usr/drivers/omap44xx/mmchs/mmchs.c
usr/drivers/omap44xx/mmchs/mmchs.h [new file with mode: 0644]
usr/drivers/omap44xx/mmchs/mmchs_debug.h [new file with mode: 0644]
usr/drivers/omap44xx/mmchs/omap44xx_cm2.h
usr/drivers/omap44xx/mmchs/omap44xx_ctrlmod.h
usr/drivers/omap44xx/mmchs/omap44xx_mmchs.h [deleted file]
usr/drivers/omap44xx/mmchs/service.c [new file with mode: 0644]
usr/drivers/omap44xx/mmchs/twl6030.c
usr/drivers/omap44xx/mmchs/twl6030.h [moved from usr/drivers/omap44xx/mmchs/ti_twl6030.h with 90% similarity]
usr/kaluga/main.c
usr/kaluga/omap_startup.c

index fa0f9c0..8274e3c 100644 (file)
@@ -70,9 +70,9 @@
            "omap/omap44xx_cam_prm",
            "omap/omap44xx_cam_cm2",
            "omap/omap44xx_fdif",
-           "omap/omap44xx_sr_mpu",
            "omap/omap44xx_device_prm",
            "omap/omap44xx_mmchs",
+           "omap/omap44xx_mmchs1",           
            "omap/omap44xx_l3init_cm2",
            "omap/omap44xx_ckgen_cm2",
            "omap/omap44xx_l4per_cm2",
diff --git a/devices/omap/omap44xx_mmchs.dev b/devices/omap/omap44xx_mmchs.dev
deleted file mode 100644 (file)
index a448c64..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2012, ETH Zurich. All rights reserved.
- *
- * This file is distributed under the terms in the attached LICENSE file.
- * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
- */
-
-/*
- * omap44xx_mmchs.dev
- *
- * DESCRIPTION: MMC host controller for TI devices (PandaBoard)
- *
- * See:
- * OMAP4430 Multimedia Device Silicon Revision 2.x 
- *          Technical Reference Manual (Rev. 0)
- * SD Card Association - Physical Layer Simplified Specification Version 3.01 
- *          (referred to as PLS)
- * devices/sdhc.dev: the rest of this device. 
- * 
- * This specification holds the OMAP44xx-specific part of the device;
- * the rest (from offset 0x200 up) is mostly a standard SDHC adaptor,
- * for which see the separate file sdhc.dev.   The main exception is
- * the additional use of the sdhc arg1 register at 0x208 covered in
- * this file. 
- *
- */
- device omap44xx_mmchs msbfirst (addr base) "TI MMC host controller" {
-        
-     register HL_REV ro addr(base, 0x0) "revision identifier" 
-         type(uint32);
-     
-     register HL_HWINFO ro addr(base, 0x4) "hardware configuration" {
-         _              25 mbz;
-         RETMODE        1       "Retention Mode";
-         MEM_SIZE       4       "FIFO buffer size";
-         MERGE_MEM      1       "merged FIFO buffer";
-         MADMA_EN       1       "DMA master enabled";
-     };
-
-     // table 24-56, page 5144
-     register HL_SYSCONFIG rw addr(base, 0x10) "Clock management config" {
-         _              26 mbz;
-         STANDBYMODE    2       "Local initiator state mgmt mode conf";
-         IDLEMODE       2       "Local target state mgmt mode conf";
-         FREEEMU        1       "Sensitivity to emulation input signal";
-         SOFTRESET      1       "Software reset (optional)";
-     };
-
-     // table 24-66, page 5145
-     register SYSCONFIG rw addr(base, 0x110) "System config" {
-         _              18 mbz;
-         STANDBYMODE    2       "Master interface power management";
-         _              2 mbz;
-         CLOCKACTIVITY  2       "Clock activity during wake up period";
-         _              3 mbz;
-         SIDLEMODE      2       "Power management";
-         ENAWAKEUP      1       "Wakeup feature control";
-         SOFTRESET      1       "Software reset";
-         AUTOIDLE       1       "Internal Clock gating strategy";
-     };
-
-     // table 24-68, page 5147
-     register SYSSTATUS ro addr(base, 0x114) "Status information" {
-         _              31 mbz;
-         RESETDONE      1       "Internal reset monitoring";
-     };
-
-
-     // table 24-71
-     register CSRE rw addr(base, 0x124) "Card status response error"
-         type(uint32);
-     
-     // table 24-73
-     register SYSTEST addr(base, 0x128) "System test" {
-         _              15 mbz;
-         OBI            1 rw    "Out-Of-Band Interrupt (OBI)";
-         SDCD           1 ro    "Card detect input signal (SDCD)";
-         SDWP           1 ro    "Write protect input signal (SDWP)";
-         WAKD           1 rw    "Wake request output signal";
-         SSB            1 rw    "Set status bit";
-         D7D            1 rw    "DAT7 i/o signal";
-         D6D            1 rw    "DAT6 i/o signal";
-         D5D            1 rw    "DAT5 i/o signal";
-         D4D            1 rw    "DAT4 i/o signal";
-         D3D            1 rw    "DAT3 i/o signal";
-         D2D            1 rw    "DAT2 i/o signal";
-         D1D            1 rw    "DAT1 i/o signal";
-         D0D            1 rw    "DAT0 i/o signal";
-         DDIR           1 rw    "DAT[7:0] pins direction";
-         CDAT           1 rw    "CMD input/output signal";
-         CDIR           1 rw    "CMD pin direction";
-         MCKD           1 rw    "Clock output signal";
-     };
-
-     // table 24-74, page 5152
-     register CON rw addr(base, 0x12c) "Configuration" {
-         _              10 mbz;
-         SDMA_LNE       1       "Slave DMA/Edge Request";
-         DMA_MNS        1       "DMA Master or Slave selection";
-         DDR            1       "Dual Data Rate mode";
-         BOOT_CF0       1       "Boot status supported";
-         BOOT_ACK       1       "Book acknowledge received";
-         CLKEXTFREE     1       "External clock free running";
-         PADEN          1       "Control Power for MMC Lines";
-         OBIE           1       "Out-of-Band Interrupt Enable";
-         OBIP           1       "Out-of-Band Interrupt Polarity";
-         CEATA          1       "CE-ATA control mode";
-         CTPL           1       "Control power for DAT[1] line";
-         DVAL           2       "Debounce filter value";
-         WPP            1       "Write protect polarity";
-         CDP            1       "Card detect polarity";
-         MIT            1       "MMC interrupt command";
-         DW8            1       "8-bit mode MMC select";
-         MODE           1       "Mode select";
-         STR            1       "Stream command";
-         HR             1       "Broadcast host response";
-         INIT           1       "Send init stream";
-         OD             1       "Card open drain mode";
-     };
-
-     // table 24-77
-     register PWRCNT rw addr(base, 0x130) "Power control" {
-         _              16 mbz;
-         VAL            16      "Power counter value";
-     };
-   
- };
index 2574fc3..36be2aa 100644 (file)
@@ -114,6 +114,12 @@ device ti_twl6030 msbfirst (addr b) "TI TWL6030 Power Companion (via I2C)" {
         vsel 5 type(vsel) "Voltage to apply";
     };
 
+    regtype cfg_voltage2 "Voltage configuration" {
+        wr_s 1 type(wr) "Warm reset sensitivity";
+        _    1 rsvd;
+        vsel 6 "Voltage to apply";
+    };
+
     register mmcctrl id1(0xEE) "MMCCTRL" {
         _               4 rsvd;
         vmmc_auto_off   1 "Is the regulator turned off automatically in case card is extracted?";
@@ -128,6 +134,8 @@ device ti_twl6030 msbfirst (addr b) "TI TWL6030 Power Companion (via I2C)" {
         mext_deb        3 "Card extraction debouncing time";
     };
 
+    register vcore_cfg_voltage id1(0x62) "VCORE3 Config Voltage" type(cfg_voltage2);
+
     // VMMC registers
     // Table 152
     //register vmmc_cfg_grp addr(b, 0x98) "VMMC Group Configuration" type(cfg_grp);
index 8859cad..062baf0 100644 (file)
@@ -897,6 +897,12 @@ errors sata SATA_ERR_ {
     failure INVALID_TYPE        "Unknown FIS type or invalid/unimplemented field for type",
 };
 
+errors mmchs MMC_ERR_ {
+    failure TRANSFER                "Error during card read/write operation.",
+    FAILURE READ_READY              "Card not ready for reading.",
+    FAILURE WRITE_READY             "Card not ready for writing.",
+};
+
 // errors generated by FAT
 errors fat FAT_ERR_ {
     failure BAD_FS              "Filesystem does not look like FAT, or is an unsupported kind of FAT",
index 20b5883..9543c1a 100644 (file)
@@ -73,6 +73,7 @@
                "ping_pong",
                "mem",
                "xmplthc",
-               "octopus" ],
+               "octopus",
+               "ata_rw28" ],
              arch <- allArchitectures
 ]
index 9b7ee22..5e57b8a 100644 (file)
@@ -38,5 +38,9 @@
 
 // 4KB BYTES
 #define OMAP44XX_MMCHS1 0x4809C000
+#define OMAP44XX_MMCHS2 0x480B4000
+#define OMAP44XX_MMCHS3 0x480AD000
+#define OMAP44XX_MMCHS4 0x480D1000
+#define OMAP44XX_MMCHS5 0x480D5000
 
 #endif // DEVICE_REGISTERS_H_
\ No newline at end of file
index 6a7d28a..cc19eb2 100644 (file)
 
 [
     build application { target = "mmchs",
-                    cFiles = (find withSuffices [".c"]),
-                    mackerelDevices = [
-                        "ti_i2c",
-                        "ti_twl6030",
-                        "sdhc",
-                        "omap/omap44xx_mmchs",
-                        "omap/omap44xx_sysctrl_padconf_core",
-                        "omap/omap44xx_l3init_cm2",
-                        "omap/omap44xx_ckgen_cm2",
-                        "omap/omap44xx_l4per_cm2"
-                    ],
-                    addLibraries = ["driverkit"],
-                    addCFlags = [ "-DIN_KERNEL" ],
-                    addIncludes = [
-                        "../../../../kernel/include/",
-                        "../../../../kernel/include/arch/armv7/"
-                    ],
-                    architectures = ["armv7"]
-                  }
+                        cFiles = [
+                            "main.c", "cm2.c", "ctrlmod.c", 
+                            "i2c.c", "mmchs.c", "twl6030.c",
+                            "service.c"
+                        ],
+                        mackerelDevices = [
+                            "ti_i2c",
+                            "ti_twl6030",
+                            "omap/omap44xx_mmchs1",
+                            "omap/omap44xx_sysctrl_padconf_core",
+                            "omap/omap44xx_l3init_cm2",
+                            "omap/omap44xx_ckgen_cm2",
+                            "omap/omap44xx_l4per_cm2"
+                        ],
+
+                        flounderDefs = [ "ata_rw28" ],
+                        flounderBindings = [ "ata_rw28" ],
+                        flounderTHCStubs = [ "ata_rw28" ],
+
+                        addLibraries = [ "driverkit", "thc" ],
+                        architectures = ["armv7"]
+    }
 ]
\ No newline at end of file
index 2cdb4b6..884272d 100644 (file)
@@ -20,71 +20,19 @@ static omap44xx_l3init_cm2_t l3init_cm2;
 static omap44xx_l4per_cm2_t l4per_cm2;
 static omap44xx_ckgen_cm2_t clkgen_cm2;
 
-#define CM2_BUF_SIZE (64*1024)
-static char cm2_buf[CM2_BUF_SIZE];
-
-/*
- * \brief Enable the clock
- *
- * See Free BSD: omap4_prcm_clks.c - omap4_clk_generic_activate()
- *
- * Module should be "fully functional" if ...
- * .. IDLEST reads as 0
- * .. STBYST reads as 0 (x)
- * Both of these fields are read-only values ..
- *
- * (x) won't enable here, but I saw this enabled once ..
- *     I guess this is happening some time later ..
- *     I think we can flip this bit by disabling standby mode on the MMC
- */
 void cm2_enable_hsmmc1(void)
 {
-    omap44xx_l3init_cm2_cm_l3init_hsmmc1_clkctrl_clksel_wrf(&l3init_cm2, 0x0);
-
-    // Handling clock dependencies!
-    //omap44xx_ckgen_cm2_cm_div_m4_dpll_per_pr(cm2_buf, CM2_BUF_SIZE, &ckgen_cm2);
-    //printf("%s", cm2_buf);
-
-    // Disabling clock manually
-    omap44xx_l3init_cm2_cm_l3init_hsmmc1_clkctrl_modulemode_wrf(&l3init_cm2, 0x0);
-
-    // Waiting for clock to be disabled ...
-    while (omap44xx_l3init_cm2_cm_l3init_hsmmc1_clkctrl_idlest_rdf(&l3init_cm2) != 0x3);
-
-    if (omap44xx_l3init_cm2_cm_l3init_hsmmc1_clkctrl_idlest_rdf(&l3init_cm2)==0x0) {
-        // Don't mess with the power controler the MMC is not powered up yet.
-        printf("cm2: Clock for HSMMC1 is already enabled\n");
-        return;
-    }
-
-    printf("cm2: Powering on HSMMC1... ");
+    omap44xx_l3init_cm2_cm_l3init_clkstctrl_clktrctrl_wrf(&l3init_cm2, 0x2);
     omap44xx_l3init_cm2_cm_l3init_hsmmc1_clkctrl_modulemode_wrf(&l3init_cm2, 0x2);
-
-    volatile int cm2loop = 0;
-    while (omap44xx_l3init_cm2_cm_l3init_hsmmc1_clkctrl_idlest_rdf(&l3init_cm2)!=0) {
-        if (++cm2loop>1000) {
-            assert(!"cm2: MMC power won't come up... "
-                   "Don't know what to do, IDLEST and STBYST are ro");
-        }
-    }
-    printf("done (%d cycles).\n", cm2loop);
-
-    if (omap44xx_l3init_cm2_cm_l3init_hsmmc1_clkctrl_stbyst_rdf(&l3init_cm2)==0x1) {
-        printf("cm2: module MMC1 is in standby state.\n");
-    }
+    while (omap44xx_l3init_cm2_cm_l3init_hsmmc1_clkctrl_idlest_rdf(&l3init_cm2) != 0x0);
 }
 
 void cm2_enable_i2c(size_t i2c_index)
 {
     assert (i2c_index < 4);
 
-    //omap44xx_l4per_prm_pm_l4per_pwrstctrl_prf(cm2_buf, 1024-1, &l4per_prm);
-    //printf("%s\n", cm2_buf);
-
     omap44xx_l4per_cm2_cm_l4per_i2c_clkctrl_modulemode_wrf(&l4per_cm2, i2c_index, 0x2);
-
-    // wait for module to get into functional state
-    while(omap44xx_l4per_cm2_cm_l4per_i2c_clkctrl_idlest_rdf(&l4per_cm2, i2c_index)
+    while (omap44xx_l4per_cm2_cm_l4per_i2c_clkctrl_idlest_rdf(&l4per_cm2, i2c_index)
             != 0x0);
 }
 
@@ -94,16 +42,16 @@ void cm2_init(void)
     errval_t err = map_device_register(OMAP44XX_CM2, 0x1000, &l3init_vaddr);
     assert(err_is_ok(err));
     omap44xx_l3init_cm2_initialize(&l3init_cm2, (mackerel_addr_t)l3init_vaddr);
-    
+
     lvaddr_t clkgen_vaddr;
     err = map_device_register(OMAP44XX_CLKGEN_CM2, 0x1000, &clkgen_vaddr);
     assert(err_is_ok(err));
     omap44xx_ckgen_cm2_initialize(&clkgen_cm2, (mackerel_addr_t)clkgen_vaddr);
 
-    lvaddr_t l4per_vaddr;
-    err = map_device_register(OMAP44XX_L4PER_CM2, 0x1000, &l4per_vaddr);
-    assert(err_is_ok(err));
-    omap44xx_l4per_cm2_initialize(&l4per_cm2, (mackerel_addr_t)l4per_vaddr);
+    //lvaddr_t l4per_vaddr;
+    //err = map_device_register(OMAP44XX_L4PER_CM2, 0x1000, &l4per_vaddr);
+    //assert(err_is_ok(err));
+    omap44xx_l4per_cm2_initialize(&l4per_cm2, (mackerel_addr_t)l3init_vaddr);
 }
 
 int cm2_get_hsmmc1_base_clock(void)
@@ -111,25 +59,3 @@ int cm2_get_hsmmc1_base_clock(void)
     return omap44xx_l3init_cm2_cm_l3init_hsmmc1_clkctrl_clksel_rdf(&l3init_cm2) == 0x0 ?
            64000000 : 96000000;
 }
-
-/*
- * \brief Print CM2 registers
- */
-void cm2_debug_print(void)
-{
-    omap44xx_l3init_cm2_pr(cm2_buf, 1024-1, &l3init_cm2);
-    printf("%s\n", cm2_buf);
-
-    omap44xx_ckgen_cm2_pr(cm2_buf, 1024-1, &clkgen_cm2);
-    printf("%s\n", cm2_buf);
-
-    omap44xx_l4per_cm2_pr(cm2_buf, 1024-1, &l4per_cm2);
-    printf("%s\n", cm2_buf);
-}
-
-void cm2_print_standby_state(void)
-{
-    omap44xx_l3init_cm2_cm_l3init_hsmmc1_clkctrl_pr(cm2_buf, 1024-1, &l3init_cm2);
-    printf("%s\n", cm2_buf);
-}
-
index f5db29b..2f5e6d1 100644 (file)
@@ -8,34 +8,54 @@
  */
 
 #include <barrelfish/barrelfish.h>
+#include <barrelfish/debug.h>
 #include <barrelfish/inthandler.h>
 #include <barrelfish/waitset.h>
 
 #include <driverkit/driverkit.h>
 
-#include <arm_hal.h>
-#include <gic.h>
-
-#include "ti_twl6030.h"
+#include "twl6030.h"
 #include "omap44xx_ctrlmod.h"
 
+#include "mmchs_debug.h"
+
+#if defined(CTRLMOD_SERVICE_DEBUG) || defined(MMCHS_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
+#define CTRLMOD_DEBUG(x...) debug_printf(x)
+#else
+#define CTRLMOD_DEBUG(x...) ((void)0)
+#endif
+
 #define SYSCTRL_PADCONF_CORE 0x4a100000u
 static omap44xx_sysctrl_padconf_core_t ctrlmod;
 
+static volatile uint32_t dummy = 0;
+static void wait_msec(long msec)
+{
+    int i = 0, sum = 0;
+    long end = (1200000 * msec / 8);
+
+    // Cannot use volatile variables in loop
+    while (++i < end)  {
+        sum += i + end;
+    }
+
+    dummy += sum;
+}
+
 /*
  * \brief Initialization of control module
  */
 void ctrlmod_init(void)
 {
+    CTRLMOD_DEBUG("%s:%d\n", __FUNCTION__, __LINE__);
     lvaddr_t vaddr;
     errval_t err = map_device_register(SYSCTRL_PADCONF_CORE, 0x1000, &vaddr);
     assert(err_is_ok(err));
 
     // Initialize Mackerel
-    omap44xx_sysctrl_padconf_core_initialize(&ctrlmod, (mackerel_addr_t) vaddr); 
+    omap44xx_sysctrl_padconf_core_initialize(&ctrlmod, (mackerel_addr_t) vaddr);
 }
 
-static bool pbias_got_irq = false;
 /*
  * We need to configure the extended-drain I/O pads to the right voltage and
  * turn on the external power supply (TWL6030 on the pandaboard)
@@ -44,21 +64,21 @@ void sdmmc1_enable_power(void)
 {
     // compare with Table 18-109 in OMAP TRM, p3681
     // Step 1: software must keep PWRDNZ low when setting up voltages
-    printf("%s: Step 1\n", __FUNCTION__);
+    CTRLMOD_DEBUG("%s: Step 1\n", __FUNCTION__);
     omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_pwrdnz_wrf(&ctrlmod, 0x0);
     omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pwrdnz_wrf(&ctrlmod, 0x0);
 
     // Step 2: preliminary settings for MMC1_PBIAS and MMC1 I/O cell
-    printf("%s: Step 2\n", __FUNCTION__);
+    CTRLMOD_DEBUG("%s: Step 2\n", __FUNCTION__);
     //  1. turn of hiz mode
     omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_hiz_mode_wrf(&ctrlmod, 0x0);
 
     //  2. setup PBIAS_IRQ (MA_IRQ_75)
-    errval_t err = inthandler_setup_arm(pbias_handle_irq, NULL, PBIAS_IRQ);
-    assert(err_is_ok(err));
+    // We don't use the interrupt
 
     //  3. pad multiplexing -- looks ok when dumping pad registers, so I'm
     //  not doing anything right now -SG
+
     //  4. set MMC1 speed control to 26MHz@30pF (0x0) -- alternative 65MHz@30pF (0x1)
     omap44xx_sysctrl_padconf_core_control_mmc1_sdmmc1_dr0_speedctrl_wrf(&ctrlmod,
             0x0);
@@ -66,6 +86,7 @@ void sdmmc1_enable_power(void)
             0x0);
     omap44xx_sysctrl_padconf_core_control_mmc1_sdmmc1_dr2_speedctrl_wrf(&ctrlmod,
             0x0);
+
     //  5. set MMC1 pullup strength to 10-50kOhm (0x1) -- alt. 50-110kOhm (0x0)
     omap44xx_sysctrl_padconf_core_control_mmc1_sdmmc1_pustrength_grp0_wrf(&ctrlmod,
             0x0);
@@ -77,59 +98,45 @@ void sdmmc1_enable_power(void)
             0x0);
 
     // Step 3: Program desired SDMMC1_VDDS for MMC I/O in I2C attached power
-    // controller TODO? -- assuming 3.0V for now, manual says reset value is
-    // 3.0V -SG
     // controller (3.0V)
-    //ti_twl6030_vmmc_off();
-    err = ti_twl6030_set_vmmc_vsel(3000);
+    errval_t err = ti_twl6030_set_vmmc_vsel(3000);
     assert(err_is_ok(err));
 
     // Step 4: Set VMODE bit according to Step 3 (0x1 == 3.0V)
-    printf("%s: Step 4\n", __FUNCTION__);
+    CTRLMOD_DEBUG("%s: Step 4\n", __FUNCTION__);
     omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_vmode_wrf(&ctrlmod, 0x1);
 
     // Step 5: wait for SDMMC1_VDDS voltage to stabilize TODO
     // might already be stable after reset? -SG
-    //ti_twl6030_vmmc_pr();
-    //mmchs_wait_msec(1000);
 
     // Step 6: Disable PWRDNZ mode for MMC1_PBIAS and MMC1 I/O cell
-    printf("%s: Step 6\n", __FUNCTION__);
+    CTRLMOD_DEBUG("%s: Step 6\n", __FUNCTION__);
     omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_pwrdnz_wrf(&ctrlmod, 0x1);
+    wait_msec(100);
     omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pwrdnz_wrf(&ctrlmod, 0x1);
 
-    //ti_twl6030_vmmc_on();
-
-    printf("%s:%d: wait until supply_hi_out is 0x1\n", __FUNCTION__, __LINE__);
-    while(omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_supply_hi_out_rdf(&ctrlmod)
-          != 0x1) {}
-    printf("%s:%d: done waiting for suply hi out\n", __FUNCTION__, __LINE__);
+    CTRLMOD_DEBUG("%s:%d: wait until supply_hi_out is 0x1\n", __FUNCTION__, __LINE__);
+    while (omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_supply_hi_out_rdf(&ctrlmod)
+            != 0x1) {}
 
     // Step 7: Store SUPPLY_HI_OUT bit
-    uint8_t supply_hi_out = 
+    uint8_t supply_hi_out =
         omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_supply_hi_out_rdf(&ctrlmod);
-    printf("%s: Step 7: supply_hi_out = %d\n", __FUNCTION__, supply_hi_out);
-    printf("%s: Step 7: vmode_error = %d\n", __FUNCTION__,
-            omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_vmode_error_rdf(&ctrlmod));
-
-    // Wait for Interrupt
-    //printf("Waiting for pbias Interrupt (id=%d)\n", PBIAS_IRQ);
-    //while(!pbias_got_irq) {
-    //    event_dispatch(get_default_waitset());
-    //}
-
-    printf("%s: Step 8\n", __FUNCTION__);
+    CTRLMOD_DEBUG("%s: Step 7: supply_hi_out = %d\n", __FUNCTION__, supply_hi_out);
+    CTRLMOD_DEBUG("%s: Step 7: vmode_error = %d\n", __FUNCTION__,
+                  omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_vmode_error_rdf(&ctrlmod));
+    CTRLMOD_DEBUG("%s: Step 8\n", __FUNCTION__);
 
     // Step 8: check VMODE_ERROR and set PWRDNZ if error
     if (omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_vmode_error_rdf(&ctrlmod)) {
-        printf("got VMODE error\n");
+        CTRLMOD_DEBUG("got VMODE error\n");
         omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pwrdnz_wrf(&ctrlmod, 0x0);
         omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_pwrdnz_wrf(&ctrlmod, 0x0);
     }
-    
+
     // Step 9: check if SUPPLY_HI_OUT corresponds to SDMMC1_VDDS (3.0V)
     if (supply_hi_out != 0x1) {
-        printf("SDMMC1_VDDS seems to be != 3.0V\n");
+        CTRLMOD_DEBUG("SDMMC1_VDDS seems to be != 3.0V\n");
         // TODO: redo setting SDMMC1_VDDS
     } else {
         // supply_hi_out should be 0x1 (3.0V)
@@ -139,19 +146,5 @@ void sdmmc1_enable_power(void)
     }
 
     // Step 12: clear PBIAS IRQ
-    pbias_got_irq = 0;
-
-    char buf[2048];
-    omap44xx_sysctrl_padconf_core_control_pbiaslite_pr(buf, 2047, &ctrlmod);
-    printf("%s:%d: %s\n", __FUNCTION__, __LINE__, buf);
-
-    ti_twl6030_vmmc_pr();
+    // Ignored
 }
-
-void pbias_handle_irq(void *args)
-{
-    printf("got pbias interrupt\n");
-    // set got-irq flag
-    pbias_got_irq = true;
-}
-
index e8f5210..8664ed5 100644 (file)
 #include <barrelfish/barrelfish.h>
 #include <driverkit/driverkit.h>
 
-#include "omap44xx_cm2.h" // for turning on I2C clocks
-#include "ti_i2c.h"
 #include <dev/ti_i2c_dev.h>
 
-#pragma GCC diagnostic ignored "-Wunused-variable" 
+#include "omap44xx_cm2.h" // for turning on I2C clocks
+#include "i2c.h"
 
-#if defined(I2C_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
-#define I2C_DEBUG(x...) printf("i2c: " x)
+#if defined(I2C_SERVICE_DEBUG) || defined(MMCHS_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
+#define I2C_DEBUG(x...) debug_printf(x)
+//#define PBS (10*1024)
+//static char prbuf[PBS];
 #else
 #define I2C_DEBUG(x...) ((void)0)
 #endif
 
-
 // there are 4 GP i2c controllers on the pandaboard
 #define I2C_COUNT 4
 static ti_i2c_t i2c[I2C_COUNT];
 static bool i2c_initialized[I2C_COUNT];
 
-static lpaddr_t i2c_pbase[I2C_COUNT] = 
-{
+static lpaddr_t i2c_pbase[I2C_COUNT] = {
     0x48070000u,
     0x48072000u,
     0x48060000u,
@@ -39,14 +38,13 @@ static lpaddr_t i2c_pbase[I2C_COUNT] =
 // default timeout for waits in ticks
 #define DEFAULT_TIMEOUT (tsc_get_hz() / 4)
 
-#define PBS (10*1024)
-static char prbuf[PBS];
-
-static int tsc_get_hz(void) {
+static int tsc_get_hz(void)
+{
     return 0x100000;
 }
 
-static int tsc_read(void) {
+static int tsc_read(void)
+{
     static int count = 0;
     return count++;
 }
@@ -54,8 +52,9 @@ static int tsc_read(void) {
 /*
  * \brief initialize I2C controller `i`.
  */
-void ti_i2c_init(int i) 
+void ti_i2c_init(int i)
 {
+    I2C_DEBUG("%s:%d\n", __FUNCTION__, __LINE__);
     // map & initialize mackerel device
     lvaddr_t i2c_vbase;
     errval_t err = map_device_register(i2c_pbase[i], 0x1000, &i2c_vbase);
@@ -67,6 +66,8 @@ void ti_i2c_init(int i)
     // turn on clocks
     cm2_enable_i2c(i);
 
+    I2C_DEBUG("%s:%d\n", __FUNCTION__, __LINE__);
+
     // TODO?: enable interrupts
 
     // Disable i2c controller
@@ -137,7 +138,7 @@ void ti_i2c_init(int i)
 }
 
 static inline bool ti_i2c_poll_stat(ti_i2c_t *dev, ti_i2c_irqstatus_t flags,
-        ti_i2c_irqstatus_t *retflags, int32_t timeout)
+                                    ti_i2c_irqstatus_t *retflags, int32_t timeout)
 {
     // poll until timeout
     uint32_t start_ticks = tsc_read();
@@ -159,8 +160,7 @@ static inline bool ti_i2c_poll_stat(ti_i2c_t *dev, ti_i2c_irqstatus_t flags,
                 ti_i2c_stat_aas_wrf(dev, 1);
                 ti_i2c_stat_rrdy_wrf(dev, 1);
             }
-        }
-        else if (stat & flags) {
+        } else if (stat & flags) {
             if (retflags) {
                 *retflags = stat;
             }
@@ -214,10 +214,10 @@ ti_i2c_read(ti_i2c_t *dev, uint8_t *buf, uint16_t length)
     ti_i2c_irqstatus_t events = 0, retevents;
 
     events = ti_i2c_irq_flag_al // arbitration lost
-           | ti_i2c_irq_flag_nack // no acknowledgement
-           | ti_i2c_irq_flag_ardy // register access ready
-           | ti_i2c_irq_flag_rdr // receive draining
-           | ti_i2c_irq_flag_rrdy; // receive ready
+             | ti_i2c_irq_flag_nack // no acknowledgement
+             | ti_i2c_irq_flag_ardy // register access ready
+             | ti_i2c_irq_flag_rdr // receive draining
+             | ti_i2c_irq_flag_rrdy; // receive ready
 
     uint16_t amount = 0, sofar = 0;
     errval_t err = SYS_ERR_OK;
@@ -225,7 +225,7 @@ ti_i2c_read(ti_i2c_t *dev, uint8_t *buf, uint16_t length)
     while (true) {
         // poll for NACK, AL, ARDY, RDR and RRDY
         I2C_DEBUG("waiting for 0x%"PRIx16"\n", events);
-        while(!ti_i2c_poll_stat(dev, events, &retevents, DEFAULT_TIMEOUT)) {
+        while (!ti_i2c_poll_stat(dev, events, &retevents, DEFAULT_TIMEOUT)) {
             // poll for receive ready
         }
 
@@ -257,8 +257,7 @@ ti_i2c_read(ti_i2c_t *dev, uint8_t *buf, uint16_t length)
 
             /* get the number of bytes in the FIFO */
             amount = ti_i2c_bufstat_rxstat_rdf(dev);
-        }
-        else if (retevents & ti_i2c_irq_flag_rrdy) {
+        } else if (retevents & ti_i2c_irq_flag_rrdy) {
             // Receive data ready interrupt --> got data
             I2C_DEBUG("Receive data ready interrupt\n");
 
@@ -332,17 +331,17 @@ ti_i2c_write(ti_i2c_t *dev, uint8_t *buf, uint16_t length)
 
     ti_i2c_irqstatus_t events = 0, retevents;
     events = ti_i2c_irq_flag_al // arbitration lost
-           | ti_i2c_irq_flag_nack // no acknowledgement
-           | ti_i2c_irq_flag_ardy // register access ready
-           | ti_i2c_irq_flag_xdr // transmit draining
-           | ti_i2c_irq_flag_xrdy; // transmit ready
+             | ti_i2c_irq_flag_nack // no acknowledgement
+             | ti_i2c_irq_flag_ardy // register access ready
+             | ti_i2c_irq_flag_xdr // transmit draining
+             | ti_i2c_irq_flag_xrdy; // transmit ready
 
 
     // writing loop
     while (true) {
         // poll for NACK, AL, ARDY, XDR and XRDY
         I2C_DEBUG("waiting for 0x%"PRIx16"\n", events);
-        while(!ti_i2c_poll_stat(dev, events, &retevents, DEFAULT_TIMEOUT)) {
+        while (!ti_i2c_poll_stat(dev, events, &retevents, DEFAULT_TIMEOUT)) {
             // poll for events
         }
 
@@ -375,8 +374,7 @@ ti_i2c_write(ti_i2c_t *dev, uint8_t *buf, uint16_t length)
             /* get the number of bytes that fit in the FIFO */
             amount = ti_i2c_bufstat_txstat_rdf(dev);
             I2C_DEBUG("#bytes = %"PRIu16"\n", amount);
-        }
-        else if (retevents & ti_i2c_irq_flag_xrdy) {
+        } else if (retevents & ti_i2c_irq_flag_xrdy) {
             // transmit data ready interrupt --> can send data
             I2C_DEBUG("Receive data ready interrupt\n");
 
similarity index 92%
rename from kernel/include/arch/armv7/ti_i2c.h
rename to usr/drivers/omap44xx/mmchs/i2c.h
index 6f3fddd..ee13f9f 100644 (file)
@@ -9,6 +9,9 @@
 #ifndef __TI_I2C_H__
 #define __TI_I2C_H__
 
+#include <barrelfish/types.h>
+#include <errors/errno.h>
+
 enum i2c_flags {
     I2C_RD     = 0x1,
     I2C_WR     = 0x2,
diff --git a/usr/drivers/omap44xx/mmchs/main.c b/usr/drivers/omap44xx/mmchs/main.c
new file mode 100644 (file)
index 0000000..91c772e
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * \file
+ * \brief MMCHS Driver main routine.
+ */
+/*
+ * Copyright (c) 2013, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <stdlib.h>
+#include "mmchs.h"
+
+
+int main(int argc, char **argv)
+{
+    cm2_init();
+    ti_twl6030_init();
+    ctrlmod_init();
+    cm2_enable_hsmmc1();
+    sdmmc1_enable_power();
+
+    mmchs_init();
+
+    init_service();
+
+    return 0;
+}
\ No newline at end of file
index f1c05f8..9944667 100644 (file)
- /*
- * Copyright (c) 2012, ETH Zurich.
+/**
+ * \file
+ * \brief OMAP44xx MMC Controller driver implementation
+ */
+/*
+ * Copyright (c) 2013, ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
  * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
  */
 
 #include <barrelfish/barrelfish.h>
 #include <barrelfish/inthandler.h>
 
 #include <driverkit/driverkit.h>
+#include <arch/arm/omap44xx/device_registers.h>
 
-#include "omap44xx_mmchs.h"
-#include "omap44xx_cm2.h"
-#include "omap44xx_ctrlmod.h"
-#include "ti_twl6030.h"
-
-#include <dev/omap/omap44xx_mmchs_dev.h>
-#include <dev/sdhc_dev.h>
-
-#include <gic.h>
+#include <dev/omap/omap44xx_mmchs1_dev.h>
 
-static sdhc_t sdhc;
-static omap44xx_mmchs_t mmchs;
+#include "mmchs.h"
 
-// XXX Temporarily disable annoying warnings about unused functions!!
-#pragma GCC diagnostic ignored "-Wunused-function" 
-#pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
+#define DBUF_SIZE (64*1024)
+static char dbuf[DBUF_SIZE];
 
-#define PBS (64*1024)
-static char PRBUF[PBS];
-#define PRBUFL PRBUF, (PBS-1)
+static omap44xx_mmchs1_t mmchs;
 
-/*
- * \brief Set divider for frequency configuration
- */
-static void mmchs_set_frequency(int freq_div)
+static void mmchs_soft_reset(void)
 {
-    int base_clock;
-    base_clock = cm2_get_hsmmc1_base_clock();
-
-    printf("mmchs: setting clock frequency to %d Hz\n",
-           (base_clock/freq_div));
-    sdhc_sysctl_clkd_wrf(&sdhc, freq_div);
+    MMCHS_DEBUG("%s:%d\n", __FUNCTION__, __LINE__);
+    omap44xx_mmchs1_mmchs_sysconfig_softreset_wrf(&mmchs, 0x1);
+    while (omap44xx_mmchs1_mmchs_sysstatus_resetdone_rdf(&mmchs) != 0x1);
 
+    MMCHS_DEBUG("%s:%d: sysctl reset\n", __FUNCTION__, __LINE__);
+    omap44xx_mmchs1_mmchs_sysctl_sra_wrf(&mmchs, 0x1);
+    while (omap44xx_mmchs1_mmchs_sysctl_sra_rdf(&mmchs) != 0x0);
 }
 
-/*
- * \brief Do a software reset of the MMC module
- *
- * Reset is only done if resetdone flag is not 1 already .. 
- *
- * Otherwise there is a risk that we cannot detect when the second reset
- * is acutally completed (since the flag is 1 alread) which might make us
- * loose some of the future actions on the MMC since it is not ready.
- *
- * After powering up the PandaBoard, RESETDONE usually is 1 already 
- *
- * Figure 24-36 
- */
-static void mmchs_do_sw_reset(void)
+static void set_hardware_capabilities(void)
 {
-    printf("mmchs: do_sw_reset()\n");
-    omap44xx_mmchs_SYSSTATUS_pr(PRBUFL,&mmchs);
-    printf("mmchs:  %s", PRBUF);
-    omap44xx_mmchs_HL_SYSCONFIG_SOFTRESET_wrf(&mmchs, 0x1);
-
-    volatile uint32_t l;
-    for(l = 0; omap44xx_mmchs_HL_SYSCONFIG_SOFTRESET_rdf(&mmchs) == 1; l++);
-    printf("mmchs:  waited %d loops for HL_SYSCONFIG_SOFTRESET\n", l);
-    for(l = 0; omap44xx_mmchs_SYSCONFIG_SOFTRESET_rdf(&mmchs) == 1; l++);
-    printf("mmchs:  waited %d loops for SYSCONFIG_SOFTRESET\n", l);
-    for(l = 0; omap44xx_mmchs_SYSSTATUS_RESETDONE_rdf(&mmchs) == 0; l++);
-    printf("mmchs:  waited %d loops for SYSSTATUS_RESETDONE\n", l);
+    omap44xx_mmchs1_mmchs_capa_vs18_wrf(&mmchs, 0x1);
+    omap44xx_mmchs1_mmchs_capa_vs30_wrf(&mmchs, 0x1);
 }
 
+static void set_wake_up_configuration(void)
+{
+    omap44xx_mmchs1_mmchs_sysconfig_enawakeup_wrf(&mmchs, 0x1);
+    omap44xx_mmchs1_mmchs_hctl_iwe_wrf(&mmchs, 0x1);
+}
 
-/*
- * \brief Reset command and data state machine
- *
- * See BSD code ti_mmchs.c line 1357
+/**
+ * \see TRM rev Z, Section 24.5.1.2.1.7.2
  */
-static void mmchs_do_state_machine_reset(void)
+static void change_clock_frequency_to_fit_protocol(uint32_t clock)
 {
-    volatile uint32_t l;
-    printf("mmchs: do_state_machine_reset()\n");
+    omap44xx_mmchs1_mmchs_sysctl_cen_wrf(&mmchs, 0x0);
+    omap44xx_mmchs1_mmchs_sysctl_clkd_wrf(&mmchs, clock);
+
+    MMCHS_DEBUG("%s:%d: Wait until clock is stable.\n", __FUNCTION__, __LINE__);
+    while (omap44xx_mmchs1_mmchs_sysctl_ics_rdf(&mmchs) != 0x1);
 
-    sdhc_sysctl_sra_wrf(&sdhc, 0x1);
-    for(l = 0; sdhc_sysctl_sra_rdf(&sdhc) != 0; l++);
-    printf("mmchs:  waited %d loops for sysctl_sra\n", l);
+    omap44xx_mmchs1_mmchs_sysctl_cen_wrf(&mmchs, 0x1);
 }
 
+static void mmc_host_and_bus_configuration(void)
+{
+    omap44xx_mmchs1_mmchs_con_od_wrf(&mmchs, 0x0);
+    omap44xx_mmchs1_mmchs_con_dw8_wrf(&mmchs, 0x0);
+    omap44xx_mmchs1_mmchs_con_ceata_wrf(&mmchs, 0x0);
+
+    omap44xx_mmchs1_mmchs_hctl_sdvs_wrf(&mmchs, 0x6);
+    omap44xx_mmchs1_mmchs_hctl_sdbp_wrf(&mmchs, 0x0);
+    omap44xx_mmchs1_mmchs_hctl_dtw_wrf(&mmchs, 0x0);
 
-/*
- * \brief Print MMCHS registers
+    omap44xx_mmchs1_mmchs_sysctl_cen_wrf(&mmchs, 0x0);
+    omap44xx_mmchs1_mmchs_sysctl_ice_wrf(&mmchs, 0x1);
+
+    MMCHS_DEBUG("%s:%d: clksel = %u\n", __FUNCTION__, __LINE__, cm2_get_hsmmc1_base_clock());
+    change_clock_frequency_to_fit_protocol(0x258);
+
+    MMCHS_DEBUG("%s:%d: Wait until internal clock is stable.\n", __FUNCTION__, __LINE__);
+    while (omap44xx_mmchs1_mmchs_sysctl_ics_rdf(&mmchs) != 0x1);
+
+    omap44xx_mmchs1_mmchs_hctl_sdbp_wrf(&mmchs, 0x1);
+    assert(omap44xx_mmchs1_mmchs_hctl_sdbp_rdf(&mmchs) == 0x1);
+
+    // Pessimistic settings, we want to have this thing always ON for testing
+    omap44xx_mmchs1_mmchs_sysconfig_clockactivity_wrf(&mmchs, 0x3);
+    omap44xx_mmchs1_mmchs_sysconfig_standbymode_wrf(&mmchs, 0x1);
+    omap44xx_mmchs1_mmchs_sysconfig_sidlemode_wrf(&mmchs, 0x1);
+    omap44xx_mmchs1_mmchs_sysconfig_autoidle_wrf(&mmchs, 0x0);
+}
+
+/**
+ * \see TRM rev Z, Section 24.5.1.2.1.1.1
  */
-static void print_mmchs(void)
+static void cmd_line_reset(void)
 {
-    omap44xx_mmchs_pr(PRBUFL, &mmchs);
-    printf("%s\n", PRBUF);
-    sdhc_pr(PRBUFL, &sdhc);
-    printf("%s\n", PRBUF);
+    MMCHS_DEBUG("%s:%d\n", __FUNCTION__, __LINE__);
+
+    omap44xx_mmchs1_mmchs_sysctl_src_wrf(&mmchs, 0x1);
+    while (omap44xx_mmchs1_mmchs_sysctl_src_rdf(&mmchs) != 0x1);
+    while (omap44xx_mmchs1_mmchs_sysctl_src_rdf(&mmchs) != 0x0);
 }
 
-/*
- * \brief Print MMC error state
+/**
+ * \see TRM rev Z, Section 24.5.1.2.1.2.1
  */
-static void print_mmchs_state(void)
+static void dat_line_reset(void)
 {
-    sdhc_stat_pr(PRBUFL, &sdhc);
-    printf("%s\n", PRBUF);
-
-    sdhc_ps_pr(PRBUFL, &sdhc);
-    printf("%s\n", PRBUF);
+    MMCHS_DEBUG("%s:%d\n", __FUNCTION__, __LINE__);
 
+    omap44xx_mmchs1_mmchs_sysctl_srd_wrf(&mmchs, 0x1);
+    while (omap44xx_mmchs1_mmchs_sysctl_srd_rdf(&mmchs) != 0x1);
+    while (omap44xx_mmchs1_mmchs_sysctl_srd_rdf(&mmchs) != 0x0);
 }
 
-volatile uint32_t dummy = 0;
 
-/*
- * \brief Sleep for @msec miliseconds
- *
- * XXX I am sure there is a better way to do this ..
- */
-static void mmchs_wait_msec(long msec)
+// TODO(gz): Got this from old mmchs code, its ugly and should
+// go away with a proper sleep functionality
+volatile uint32_t dummy = 0;
+static void wait_msec(long msec)
 {
-    int i=0, sum = 0; 
-    long end = (1200000*msec/8);
+    int i = 0, sum = 0;
+    long end = (1200000 * msec / 8);
 
     // Cannot use volatile variables in loop
-    while (++i<end)  {
-        sum+=i+end;
+    while (++i < end)  {
+        sum += i + end;
     }
 
     dummy += sum;
 }
 
-/*
- * \brief Do CMD line reset
- *
- * TRM 24.5.1.2.1.2, page 5120
- */
-static void mmchs_cmd_line_reset(void)
-{
-    sdhc_sysctl_src_wrf(&sdhc, 0x1);
-    while (sdhc_sysctl_src_rdf(&sdhc)!=0x1)
-        ;
-    while (sdhc_sysctl_src_rdf(&sdhc)!=0x0)
-        ;
-}
 
-/*
- * \brief Initialize and identify
- *
- * This is according to SD card spec v3, chp 3.6
+/**
+ * \see TRM rev Z, Section 24.5.1.2.1.7.1
  */
-int mmchs_init_and_ident_card(void)
+static void send_command(omap44xx_mmchs1_indx_status_t cmd, uint32_t arg)
 {
-    // Reset card
-    // XXX Keep pin 1 high during execution??
-    printf("identify: cmd0\n");
-    mmchs_send_cmd(0, 0);
-
-    mmchs_wait_msec(1000);
-
-    // Free BSD: mmc_send_if_conf [mmc.c]
-    // Sets vhs, and uses 0xAA as pattern
-    uint32_t cmd8arg = 0;
-    sdhc_cmd8_t cp= (sdhc_cmd8_t)&cmd8arg;
-    // 2.7-3.6V (seems to  be the only value allowed .. )
-    sdhc_cmd8_vhs_insert(cp, 0x1);
-    // Recommended pattern is: 0x1010101010
-    sdhc_cmd8_pattern_insert(cp, 0xaa);
-    printf("identify: cmd8\n");
-    mmchs_send_cmd(8, cmd8arg);
-
-    // Wait for result
-    return mmchs_finalize_cmd();
-}
+    MMCHS_DEBUG("%s:%d: cmd = 0x%x arg=0x%x\n", __FUNCTION__, __LINE__, cmd, arg);
 
-/*
- * \brief TBD
- *
- * see TRM Figure 24-38 left-handed
- * and BSD code in ti_mmchs_send_init_stream in ti_mmchs.c
- *
- * Free BSD has a slightly different approach compared to the
- * TRM. They issue CMD0 commands and wait for the STAT_CC bit to be
- * set, whereas the TRM just waits for 1 ms.
- *
- * Precondition: Module initiliaztion
- */
-static void mmchs_init_stream(void)
-{
-    printf("mmchs: initializing stream .. \n");
-
-    // Make sure that the command line is not busy at this point 
-    assert (sdhc_ps_cmdi_rdf(&sdhc)==0x0);
-
-    // Save original IE and ISE registers
-    sdhc_ir_t ie = sdhc_ie_rd(&sdhc);
-    sdhc_ir_t ise = sdhc_ise_rd(&sdhc);
-
-    // Enable interrupts, so that CC will be set
-    // These are SD card interrupts.
-    // If we don't do that, STAT_CC will not be set
-    // BSD line 894
-    // XXX Don't use constant here .. 
-    sdhc_ie_wr(&sdhc, 0x307F0033);
-
-    // Disable genernation of status events
-    sdhc_ise_wr(&sdhc, 0x0);
-
-    // Initialize stream
-    omap44xx_mmchs_CON_INIT_wrf(&mmchs, 0x1); 
-    // Writing a dummy command
-    // CMD0 seems to be a reset command ..
-    sdhc_ctm_rawwr(&sdhc, 0x0);
-    // Wait for completion of command
-    while (sdhc_stat_cc_rdf(&sdhc)!=0x1) ;
-    mmchs_wait_msec(1);
-    // Clear status field, so that we see when CC (command complete) sticks
-    sdhc_stat_cc_wrf(&sdhc, 0x1);
-
-    // Need to do the whole procedure twice, since we cannot
-    // make our clock slow enough to not have more  than 80 cycles 
-    // in one msec .. 
-
-    // End initialization sequence ...
-    omap44xx_mmchs_CON_INIT_wrf(&mmchs, 0x0);
-
-    printf("mmchs: stream init done (how do we know it works?)\n");
-
-    // Reset the interrupt configuration
-    sdhc_ie_wr(&sdhc, ie);
-    sdhc_ise_wr(&sdhc, ise);
-
-    // Unset STAT 
-    sdhc_stat_rawwr(&sdhc, ~0x0);
-    /* sdhc_stat_rd(&sdhc); // << why are we reading this (from BSD) */
-
-    // Change clock frequency to fit protocol?
-    // TRM 24.5.1.2.1.7.2
-    /* mmchs_change_clock_frequency(); */
-
-    mmchs_cmd_line_reset();
-
-    // Make sure nothing went wrong in init
-    /* assert(sdhc_stat_bada_rdf(&sdhc)==0x0); */
-    /* assert(sdhc_stat_erri_rdf(&sdhc)==0x0); */
-}
+    MMCHS_DEBUG("%s:%d: Wait until command line is free.\n", __FUNCTION__, __LINE__);
+    while (omap44xx_mmchs1_mmchs_pstate_cmdi_rdf(&mmchs) != 0x0);
+    MMCHS_DEBUG("%s:%d: \n", __FUNCTION__, __LINE__);
 
-/* 
- * \brief Identify card
- *
- * Does currently not work! Report all card types being present, 
- * no matter what and if any card is actually inserted!
- *
- * This is according to TI TRM
- */
-void mmchs_identify_card(void)
-{
-    // << OMAP TRM method does not work!
+    omap44xx_mmchs1_mmchs_stat_rawwr(&mmchs, ~0x0);
 
-    // send a CMD0 command
-    // TRM 24.5.1.2.1.7.1
-    mmchs_send_cmd(CMD0, 0);
+    // Only for MMC cards
+    omap44xx_mmchs1_mmchs_con_mit_wrf(&mmchs, 0x0);
+    omap44xx_mmchs1_mmchs_con_str_wrf(&mmchs, 0x0);
 
-    // send a CMD5 command
-    // XXX don't use the wrapper function    mmchs_send_cmd(CMD5);
+    omap44xx_mmchs1_mmchs_csre_rawwr(&mmchs, 0x0);
 
-    // Wait for CMD line to become available
-    while (sdhc_ps_cmdi_rdf(&sdhc)!=0);
-    // Unset STAT bits. These bits will reflect completion of command execution
-    sdhc_stat_wr(&sdhc, ~0x0);
-    assert (sdhc_stat_cc_rdf(&sdhc)==0x0);
-    // Issue the command
-    sdhc_ctm_index_wrf(&sdhc, 0x5);
+    omap44xx_mmchs1_mmchs_blk_blen_wrf(&mmchs, 512);
+    omap44xx_mmchs1_mmchs_blk_nblk_wrf(&mmchs, 0x1);
 
-    // XXX Does this detect if there is actually a card in the slot or just
-    //     if the controller has the capability to read a card of that type?
-    uint32_t cc, cto, run = 0;
+    omap44xx_mmchs1_mmchs_sysctl_dto_wrf(&mmchs, 0xE); // omapconf
 
-    // Wait for completion
-    do {
-        cc = sdhc_stat_cc_rdf(&sdhc); 
-        cto = sdhc_stat_cto_rdf(&sdhc); 
-        run = 0;
-
-        if (cc==0x1) {
-            printf("SDIO card detected .. printing registers ..\n");
-            assert (sdhc_stat_bada_rdf(&sdhc)==0x0);
-        } else if (cto==0x1) {
-            printf("No SDIO card detected .. \n");
-        } else {
-            run = 1;
-        }
-    } while(run);
+    omap44xx_mmchs1_mmchs_arg_rawwr(&mmchs, arg);
 
-    assert(sdhc_stat_bada_rdf(&sdhc)==0x0);
+    // Enable interrupts
+    omap44xx_mmchs1_mmchs_ie_rawwr(&mmchs, ~0x0);
+    //omap44xx_mmchs1_mmchs_ise_rawwr(&mmchs, ~0x0);
+
+    omap44xx_mmchs1_mmchs_cmd_t cmdreg = omap44xx_mmchs1_mmchs_cmd_default;
+
+    // see TRM rev Z, Table 24-4
+    // and Physical Layer Simplified Spec 3.01, Section 4.7.4
+    switch (cmd) {
+        // R2
+    case omap44xx_mmchs1_INDX_2:
+    case omap44xx_mmchs1_INDX_9:
+        cmdreg = omap44xx_mmchs1_mmchs_cmd_rsp_type_insert(cmdreg, 0x1);
+        cmdreg = omap44xx_mmchs1_mmchs_cmd_ccce_insert(cmdreg, 0x1);
+        break;
+        // R1, R6, R5, R7
+    case omap44xx_mmchs1_INDX_17:
+        cmdreg = omap44xx_mmchs1_mmchs_cmd_ddir_insert(cmdreg, 0x1);
+    case omap44xx_mmchs1_INDX_24:
+        cmdreg = omap44xx_mmchs1_mmchs_cmd_dp_insert(cmdreg, 0x1);
+        cmdreg = omap44xx_mmchs1_mmchs_cmd_acen_insert(cmdreg, 0x1);
+        // Fallthrough desired!
+    case omap44xx_mmchs1_INDX_0:
+    case omap44xx_mmchs1_INDX_3:
+    case omap44xx_mmchs1_INDX_5:
+    case omap44xx_mmchs1_INDX_8:
+    case omap44xx_mmchs1_INDX_16:
+    case omap44xx_mmchs1_INDX_41:
+    case omap44xx_mmchs1_INDX_55:
+        cmdreg = omap44xx_mmchs1_mmchs_cmd_rsp_type_insert(cmdreg, 0x2);
+        cmdreg = omap44xx_mmchs1_mmchs_cmd_ccce_insert(cmdreg, 0x1);
+        cmdreg = omap44xx_mmchs1_mmchs_cmd_cice_insert(cmdreg, 0x1);
+        break;
+        // R1b, R5b
+    case omap44xx_mmchs1_INDX_7:
+    case omap44xx_mmchs1_INDX_12:
+        cmdreg = omap44xx_mmchs1_mmchs_cmd_rsp_type_insert(cmdreg, 0x3);
+        cmdreg = omap44xx_mmchs1_mmchs_cmd_ccce_insert(cmdreg, 0x1);
+        cmdreg = omap44xx_mmchs1_mmchs_cmd_cice_insert(cmdreg, 0x1);
+        break;
+    default:
+        assert(!"Unsupported command\n");
+        break;
+    }
 
-    // CMD line reset
-    mmchs_cmd_line_reset();
+    cmdreg = omap44xx_mmchs1_mmchs_cmd_indx_insert(cmdreg, cmd);
+    omap44xx_mmchs1_mmchs_cmd_wr(&mmchs, cmdreg);
 
-    // Send a CMD8 command
-    // CC value?          0x1 -> SD card
-    // CMD8 needs an argument ..
-    mmchs_send_cmd(CMD8, 0);
+    MMCHS_DEBUG("%s:%d: Wait until mmchs_stat.cc == 0x1\n", __FUNCTION__, __LINE__);
+    uint32_t cc = 0;
+    size_t i = 0;
     do {
-        if (sdhc_stat_cc_rdf(&sdhc)) {
-            printf("SD card found .. (v 2.0 or higher)\n");        
+        uint32_t cto = omap44xx_mmchs1_mmchs_stat_cto_rdf(&mmchs);
+        uint32_t ccrc = omap44xx_mmchs1_mmchs_stat_ccrc_rdf(&mmchs);
+        cc = omap44xx_mmchs1_mmchs_stat_cc_rdf(&mmchs);
+
+        if (cto == 0x1 && ccrc == 0x1) {
+            MMCHS_DEBUG("%s:%d: cto = 1 ccrc = 1: Conflict on cmd line.\n", __FUNCTION__, __LINE__);
+            cmd_line_reset();
+            return;
+        }
+        if (cto == 0x1 && ccrc == 0x0) {
+            MMCHS_DEBUG("%s:%d: cto = 1 ccrc = 0: Abort.\n", __FUNCTION__, __LINE__);
+            cmd_line_reset();
             return;
-        } else {
-            printf("No SD card found .. \n");
         }
-    } while (sdhc_stat_cto_rdf(&sdhc)!=0x1);
 
-    // We do not check for other cards (i.e. SD v1.x, or unknown cards .. )
-    assert(!"There is no SD v2 card in the slot .. \n");
-}
+        if (i++ > 1000) {
+            omap44xx_mmchs1_mmchs_stat_pr(dbuf, DBUF_SIZE, &mmchs);
+            MMCHS_DEBUG("%s:%d: %s\n", __FUNCTION__, __LINE__, dbuf);
+            USER_PANIC("Command not Ackd?");
+        }
+        wait_msec(1);
+    } while (cc != 0x1);
 
-/*
- * \brief Change the block frequency
- *
- * The maximum operating frequency is 50 MHz [PLS. page 1] 
- * TRM, Figure 24-48, page 5132
- * 
- * \param clkdiv Clockdivider value to use
- */
-static void mmchs_change_clock_frequency(int clkdiv)
-{
-    // Disable clock
-    sdhc_sysctl_cen_wrf(&sdhc, 0x0);
 
-    // Set the frequency
-    // The base frequency we get from the L3 interconnect is 96 MHz,
-    // we want to be below 50 MHz, so we use 2 as a divider for the clock
-    mmchs_set_frequency(clkdiv);
+    /*omap44xx_mmchs1_mmchs_pstate_pr(dbuf, DBUF_SIZE, &mmchs);
+    MMCHS_DEBUG("%s:%d: \n%s\n", __FUNCTION__, __LINE__, dbuf);
+    MMCHS_DEBUG("%s:%d: mmchs_rsp10 = 0x%x\n", __FUNCTION__, __LINE__,
+           omap44xx_mmchs1_mmchs_rsp10_rd(&mmchs));
+    MMCHS_DEBUG("%s:%d: mmchs_rsp32 = 0x%x\n", __FUNCTION__, __LINE__,
+           omap44xx_mmchs1_mmchs_rsp32_rd(&mmchs));
+    MMCHS_DEBUG("%s:%d: mmchs_rsp54 = 0x%x\n", __FUNCTION__, __LINE__,
+           omap44xx_mmchs1_mmchs_rsp54_rd(&mmchs));
+    MMCHS_DEBUG("%s:%d: mmchs_rsp76 = 0x%x\n", __FUNCTION__, __LINE__,
+           omap44xx_mmchs1_mmchs_rsp76_rd(&mmchs));*/
 
-    // Wait for internal clock to be stable .. 
-    while (!sdhc_sysctl_ics_rdf(&sdhc));
 
-    // Enable SD card clock
-    sdhc_sysctl_cen_wrf(&sdhc, 0x1);
+    uint32_t resp_type = omap44xx_mmchs1_mmchs_cmd_rsp_type_rdf(&mmchs);
+    if (resp_type == 0x0) {
+        MMCHS_DEBUG("%s:%d: No response.\n", __FUNCTION__, __LINE__);
+        return;
+    }
 }
 
-/*
- * \brief Send a command using polling
- *
- * \param cmd_idx Index of the command to issue (e.g. 0 for CMD0)
- * \param arg Argument of the command, will be written to the ARG register.
- *    These are given as bits [8:39] in the Physical Layer spec (see page 25)
- *
- * TRM Figure 24-46, page 5129
- * HCS      3.7.1.1, page 107
- *          3.7.1.2, page 109
- *
+
+/**
+ * \see TRM rev Z, Figure 24-38
  */
-void mmchs_send_cmd(int cmd_idx, uint32_t arg)
+static void mmchs_identify_card(void)
 {
-    // Wait for previous command to finish
-    int loop = 0;
-    while (sdhc_ps_cmdi_rdf(&sdhc)!=0x0/*  ||  */
-           /* sdhc_ps_DATI_rdf(&mmchs)!=0x0 */) { // HCS, 2.2.6
-        // but DATI not mentioned in HCS 3.7.1.2
-        // okay, depends on busy signal. Don't need to check if the busy signal is used
+    // Module Initialization is done in mmchs_init()
+    omap44xx_mmchs1_mmchs_ie_rawwr(&mmchs, 0xFFFFFFFF);
 
-        mmchs_wait_msec(1);
+    omap44xx_mmchs1_mmchs_con_init_wrf(&mmchs, 0x1);
 
-        if(++loop>10000) {
+    omap44xx_mmchs1_mmchs_cmd_rawwr(&mmchs, 0x0);
+    while (omap44xx_mmchs1_mmchs_stat_cc_rdf(&mmchs) != 0x1);
 
-            print_mmchs();
-            assert(!"mmchs_send_cmd failed, CMDI seems to stick .. ");
-        }
-    }
+    wait_msec(10);
+    omap44xx_mmchs1_mmchs_stat_cc_wrf(&mmchs, 0x1);
 
-    // FreeBSD: ti_mmchs.c, line 589
-    // These values are only valid for MMC cards
-    omap44xx_mmchs_CON_t con = omap44xx_mmchs_CON_rd(&mmchs);
-    con = omap44xx_mmchs_CON_MIT_insert(con, 0x0);
-    con = omap44xx_mmchs_CON_STR_insert(con, 0x0);
-    // Written later .. 
-
-    // XXX Set CSRE if response type permits
-    //     see standard spec
-    // This seems to be to detect some kind of card error
-    // Don't think we need this, FreeBSD does not use it either
-
-    // Write MMCHS_SYSCTL . DTO
-    // DTO is the data timout counter
-    // XXX CAPA_TCP is 0, does this mean that the timeout counter will not work?
-    /* printf("Timeout counter base frequency: %d\n", sdhc_capa_TCF_rdf(&mmchs)); */
-    /* printf("Timeout value is: %d\n", sdhc_sysctl_dto_rdf(&sdhc)); */
-    sdhc_sysctl_dto_wrf(&sdhc, 0xe);
-
-    // XXX Interrupt configuration
-    //     Setting MMCHS_IE
-    //     and MMCHS_ISE
-    //     to enable interrupts
-    /* sdhc_ie_wr(&sdhc, ~0x0); */
-    /* sdhc_ise_wr(&sdhc, 0x0); */
-    sdhc_ir_t ise = sdhc_ir_default;
-    ise = sdhc_ir_cerr_insert(ise, 0x1);
-    ise = sdhc_ir_cto_insert(ise, 0x1); 
-    ise = sdhc_ir_cc_insert(ise, 0x1);
-    ise = sdhc_ir_ceb_insert(ise, 0x1);
-    // Written later .. 
-
-    // Unset all bits in STAT
-    sdhc_stat_wr(&sdhc, ~0x0);
-
-    sdhc_ctm_t cmd = sdhc_ctm_default;
-
-    // Configure command
-    // For cmd8, which expects R7, .. 
-    cmd = sdhc_ctm_index_insert(cmd, cmd_idx); // Command ID
-    switch (cmd_idx) {
-    case CMD8:
-        // Free BSD: mmc_send_if_conf [mmc.c]
-        // RSP_TYPE follows from MMC_CMD_BCR
-        cmd = sdhc_ctm_rsp_type_insert(cmd, 0x2); // R7
-        // MMC_RSP_R7 = MMC_RSP_PRESENT | MMC_RSP_CRC
-        cmd = sdhc_ctm_dp_insert(cmd, 0x1); // Data present
-        // Do a CRC check
-        cmd = sdhc_ctm_ccce_insert(cmd, 0x1);
-        ise = sdhc_ir_ccrc_insert(ise, 0x1);
-        // Do index checking
-        ise = sdhc_ir_cie_insert(ise, 0x1);
-        break;
-    case CMD0:
-        cmd = sdhc_ctm_rsp_type_insert(cmd, 0x0); // R7
-        break;
-    default:
-        assert(!"Unknown command .. ");
-    }
+    omap44xx_mmchs1_mmchs_cmd_rawwr(&mmchs, 0x0);
+    while (omap44xx_mmchs1_mmchs_stat_cc_rdf(&mmchs) != 0x1);
 
-    if (1) { // no data
-        // XXX Write MMCHS_BLK
-        //     Free BSD ti_mmchs.c l 631'ish
-        //     for now, we don't have any data .. 
-        sdhc_blckcnt_wr(&sdhc, 0x0);
-
-        // Write CON
-        omap44xx_mmchs_CON_wr(&mmchs, con);
-
-        // Write IE (to enable internal generation of interrupts)
-        // These are not actual interrupts
-        sdhc_ie_wr(&sdhc, ise);
-        
-        // Write ISE (to enable interrupts passed to the system)
-        // Enabling some interrupts I believe could be useful for debugging
-        ise = sdhc_ir_default;
-        ise = sdhc_ir_bada_insert(ise, 0x1); // Bad access 
-        ise = sdhc_ir_dto_insert(ise, 0x1);  // Data timeout
-        ise = sdhc_ir_cto_insert(ise, 0x1);  // Command timeout
-        ise = sdhc_ir_cerr_insert(ise, 0x1); // Card error
-        ise = sdhc_ir_dcrc_insert(ise, 0x1); // Data CRC error
-        ise = sdhc_ir_ccrc_insert(ise, 0x1); // Command CRC err
-        ise = sdhc_ir_cirq_insert(ise, 0x1); // Command CRC err
-        ise = sdhc_ir_crem_insert(ise, 0x1); // Command CRC err
-        ise = sdhc_ir_cins_insert(ise, 0x1); // Command CRC err
-        sdhc_ise_wr(&sdhc, ise);
-
-        // Write command argument
-       sdhc_arg1_wr(&sdhc, arg);
-        sdhc_ctm_wr(&sdhc, cmd);
-    }
-}
+    omap44xx_mmchs1_mmchs_stat_cc_wrf(&mmchs, 0x1);
+    omap44xx_mmchs1_mmchs_con_init_wrf(&mmchs, 0x0);
 
-static int mmchs_finalize_cmd(void)
-{
-    volatile int32_t cto;
-    volatile int32_t ccrc;
-    volatile int32_t cc;
+    //omap44xx_mmchs1_mmchs_stat_rawwr(&mmchs, 0xFFFFFFFF);
 
-    int loop = 1; // << run loop until 0
-    int cnt = 0;
+    omap44xx_mmchs1_mmchs_hctl_sdbp_wrf(&mmchs, 0x1);
+    change_clock_frequency_to_fit_protocol(0xF0UL);
 
-    do {
-        
-        if (++cnt>1000) {
+    send_command(0, 0x0);
 
-            printf("Timout for command, aborting .. \n");
-            loop = 0;
-            print_mmchs_state();
-        }
+    uint32_t arg8 = (0x1  << 8) | 0b10101010;
+    send_command(8, arg8);
+    assert(omap44xx_mmchs1_mmchs_stat_cc_rdf(&mmchs) == 0x1);
+
+    send_command(55, 0x0);
+    uint32_t ocrdata = 0;
+    do {
+        send_command(55, 0x0);
+        MMCHS_DEBUG("%s:%d: ACMD41\n", __FUNCTION__, __LINE__);
+        uint32_t arg41 = 0x1 << 30 | ocrdata;
+        send_command(41, arg41);
+        wait_msec(10);
+        ocrdata = omap44xx_mmchs1_mmchs_rsp10_rd(&mmchs);
+    } while ((omap44xx_mmchs1_mmchs_rsp10_rd(&mmchs) & (1 << 31)) == 0);
+
+    MMCHS_DEBUG("%s:%d: CMD2\n", __FUNCTION__, __LINE__);
+    send_command(2, 0x0);
+
+    MMCHS_DEBUG("%s:%d: CMD3\n", __FUNCTION__, __LINE__);
+    send_command(3, 0x1);
+    uint32_t rca = omap44xx_mmchs1_mmchs_rsp10_rd(&mmchs) >> 16;
+    MMCHS_DEBUG("Status: 0x%X\n", rca & 0xFFFF);
+    MMCHS_DEBUG("RCA: 0x%X\n", (rca >> 16) & 0xFFFF);
+
+    MMCHS_DEBUG("%s:%d: CMD9\n", __FUNCTION__, __LINE__);
+    send_command(9, rca << 16);
+
+    MMCHS_DEBUG("%s:%d: CMD7\n", __FUNCTION__, __LINE__);
+    send_command(7, rca << 16);
+
+    MMCHS_DEBUG("%s:%d: CMD16\n", __FUNCTION__, __LINE__);
+    send_command(16, 512);
+}
 
-        cto = sdhc_stat_cto_rdf(&sdhc); // < Command Timeout Error
-        ccrc = sdhc_stat_ccrc_rdf(&sdhc);
-        cc = sdhc_stat_cc_rdf(&sdhc);
-        
-        if (cto==0x1) { // << Timeout?
-            loop = 0;
-            mmchs_cmd_line_reset();
-            return MMCHS_RESP_TIMEOUT;
-        } else if (cc==0x1) { // << Command complete?
-            sdhc_resp_pr(PRBUFL, &sdhc);
-            sdhc_ctm_pr(PRBUFL, &sdhc);
-            printf("CMD:\n%s\n", PRBUF);
-            loop = 0;
-            // Check for response ..
-            if (sdhc_ctm_rsp_type_rdf(&sdhc)!=0x0) {
-                // Read response
-                printf("mmchs_send_cmd: CC - got a response! "
-                       "Doing a mackerel print .. \n");
-                sdhc_resp_pr(PRBUFL, &sdhc);
-                // Verify error
-                if (sdhc_stat_cie_rdf(&sdhc)!=0x0 ||
-                    sdhc_stat_ceb_rdf(&sdhc)!=0x0 ||
-                    sdhc_stat_ccrc_rdf(&sdhc)!=0x0 ||
-                    sdhc_stat_cerr_rdf(&sdhc)!=0x0) {
-                    
-                    print_mmchs();
-                    cm2_debug_print();
-                    assert(!"mmchs_send_cmd: error - registers got dumped .. ");
-                }
-            } else {
-                printf("mmchsd_send_cmd: no response \n");
+static errval_t complete_card_transaction(void)
+{
+    size_t i = 0;
+    do {
+        if ( omap44xx_mmchs1_mmchs_stat_tc_rdf(&mmchs) == 0x1 )  {
+            //send_command(12, 0);
+            return SYS_ERR_OK; // Fine as long as we support only finite transfers
+        } else {
+            bool deb = omap44xx_mmchs1_mmchs_stat_deb_rdf(&mmchs);
+            bool dcrc = omap44xx_mmchs1_mmchs_stat_dcrc_rdf(&mmchs);
+            bool dto = omap44xx_mmchs1_mmchs_stat_dto_rdf(&mmchs);
+
+            if (deb || dcrc || dto) {
+                MMCHS_DEBUG("%s:%d: Error interrupt during transfer: deb=%d dcrc=%d dto=%d.\n",
+                            __FUNCTION__, __LINE__, deb, dcrc, dto);
+                dat_line_reset();
+                return MMC_ERR_TRANSFER;
             }
         }
 
-        mmchs_wait_msec(1);
+        wait_msec(10);
+    } while (i++ < 1000);
 
-    } while(loop);
-        
-    printf("mmchs_send_cmd end (result after %d loop iterations) \n", cnt);
-    return MMCHS_RESP_SUCCESS;
+    MMCHS_DEBUG("%s:%d: No transfer complete interrupt?\n", __FUNCTION__, __LINE__);
+    return MMC_ERR_TRANSFER;
 }
 
-#ifdef MMCHS_DEBUG
-/*
- * \brief Test register access
- *
- * Triest to write a couple of registers and reads them 
- * again to see if the reads return the changed value.
+/**
+ * \brief Reads a 512-byte block on the card.
  *
- * I am doing this in a loop because I read somewhere that
- * the device might be idle and needs to wake up first (which
- * is triggered by the register access)
+ * \param block_nr Index number of block to read.
+ * \param buffer Non-null buffer with a size of at least 512 bytes.
  *
- * STATE: This works for all but DVAL
+ * \retval SYS_ERR_OK Block successfully written in buffer.
+ * \retval MMC_ERR_TRANSFER Error interrupt or no transfer complete interrupt.
+ * \retval MMC_ERR_READ_READY Card not ready to read.
  */
-static void mmchs_test_register_write(void)
+errval_t mmchs_read_block(size_t block_nr, void *buffer)
 {
-    printf("mmchs_test_register_write\n");
-
-    for(int i=0; i<100; i++) {
+    MMCHS_DEBUG("%s:%d: Wait for free data lines.\n", __FUNCTION__, __LINE__);
+    while (omap44xx_mmchs1_mmchs_pstate_dati_rdf(&mmchs) != 0x0);
 
-        printf("HL standby is: %d - "
-               "HL idle is: %d - "
-               "DVAL is: %d - "
-               "standby is: %d \n", 
-               omap44xx_mmchs_HL_SYSCONFIG_STANDBYMODE_rdf(&mmchs),
-               omap44xx_mmchs_HL_SYSCONFIG_IDLEMODE_rdf(&mmchs),
-               omap44xx_mmchs_CON_DVAL_rdf(&mmchs),
-               omap44xx_mmchs_SYSCONFIG_STANDBYMODE_rdf(&mmchs));
+    // Send data command
+    send_command(17, block_nr);
+    // TODO(gz): Check for errors
 
-        omap44xx_mmchs_HL_SYSCONFIG_STANDBYMODE_wrf(&mmchs, 0x1);
-        omap44xx_mmchs_HL_SYSCONFIG_IDLEMODE_wrf(&mmchs, 0x1);
-        omap44xx_mmchs_SYSCONFIG_STANDBYMODE_wrf(&mmchs, 0x1);
-        omap44xx_mmchs_CON_DVAL_wrf(&mmchs, 0x1);
-
-        volatile int t = 0;
-        do {
-            t++;
-        } while(t<CYCLES_PER_MSEC/10);
+    for (size_t i = 0; i < (omap44xx_mmchs1_mmchs_blk_blen_rdf(&mmchs) + 3) / 4; i++) {
+        size_t timeout = 1000;
+        while (omap44xx_mmchs1_mmchs_stat_brr_rdf(&mmchs) == 0x0 && timeout--) {
+            wait_msec(1);
+        }
+        if (timeout == 0) {
+            return MMC_ERR_READ_READY;
+        }
 
+        ((uint32_t *) buffer)[i] = omap44xx_mmchs1_mmchs_data_rd(&mmchs);
     }
 
-    printf("mmchs_test_register_write .. DONE\n");
-}
-#endif
-
-/*
- * \brief Print information on the power state of the MMC
- *
- * See SD Host Controller Spec, 1.10
- */
-static void mmchs_print_power_state(void)
-{
-    printf("Internal clock enable: %d\n", sdhc_sysctl_ice_rdf(&sdhc));
-    printf("Card Inserted: %d\n", sdhc_ps_cins_rdf(&sdhc));
-    printf("SD Bus Power: %d\n", sdhc_hctl_sdbp_rdf(&sdhc));
-    printf("SD Clock Enable: %d\n", sdhc_sysctl_cen_rdf(&sdhc));
-    printf("Command Inhibit: %d\n", sdhc_ps_cmdi_rdf(&sdhc));
-    printf("DAT inhibit: %d\n", sdhc_ps_dati_rdf(&sdhc));
-}
-
-/*
- * \brief Disable standby mode
- *
- * Figured this one out by reading descriptions of device regiters ..
- */
- static void mmchs_disable_standby(void) 
-{
-    // This is not part of the official initialization flow documentation
-    omap44xx_mmchs_HL_SYSCONFIG_STANDBYMODE_wrf(&mmchs, 0x1);
-    omap44xx_mmchs_HL_SYSCONFIG_IDLEMODE_wrf(&mmchs, 0x1);
-    omap44xx_mmchs_SYSCONFIG_STANDBYMODE_wrf(&mmchs, 0x1);
-}
-
-/*
- * \brief Enable wakupe of the host controller
- *
- * OMAP TRM 24.5.1.1.2.4
- */
-static void mmchs_enable_wakeup(void)
-{
-    omap44xx_mmchs_SYSCONFIG_ENAWAKEUP_wrf(&mmchs, 0x1);
-    sdhc_hctl_iwe_wrf(&sdhc, 0x1);
-}
-
-/*
- * \brief Detect if there is a card in the card reader
- *
- * SD card spec 3.1
- * This is not working! Maybe we do need interrupt for that?
- */
-static void mmchs_detect_card(void)
-{
-    sdhc_stat_wr(&sdhc, ~0x0);
-    assert(sdhc_stat_cirq_rdf(&sdhc)==0x0);
-
-    // Read old interrupt configuration
-    sdhc_ir_t ie = sdhc_ie_rd(&sdhc);
-    sdhc_ir_t ise = sdhc_ise_rd(&sdhc);
-    // Enable detection for insertion of card .. 
-    ie =  sdhc_ir_cins_insert(ie, 0x1);
-    ie =  sdhc_ir_crem_insert(ie, 0x1);
-    ise = sdhc_ir_crem_insert(ise, 0x1);
-    ise = sdhc_ir_cins_insert(ise, 0x1);
-    // Write new interrupt configuration
-    sdhc_ie_wr(&sdhc, ie);
-    sdhc_ise_wr(&sdhc, ise);
-
-    printf("Waiting for card to be inserted .. \n");
-    //sdhc_pr(PRBUFL, &sdhc);
-    //printf("%s\n", PRBUF);
-
-    //sdhc_ise_pr(PRBUFL, &sdhc);
-    //printf("%s\n", PRBUF);
-    //sdhc_ie_pr(PRBUFL, &sdhc);
-    //printf("%s\n", PRBUF);
-
-     int i = 0;
-     while (sdhc_ps_cins_rdf(&sdhc)!=0x1) {
-
-         if (++i>10000) {
-             printf("No card detected .. \n");
-             return;
-         }
-
-         mmchs_wait_msec(1);
-     }
-
-     printf("Card detected .. \n");
-      mmchs_init_stream();
-     mmchs_identify_card();
-}
-
-/*
- * \brief Prepare configuration of MMC host controller
- *
- */
-static void mmchs_pre_configure(void) 
-{
-    printf("mmchs: pre_configure()\n");
-
-    // need connection to TWL6030 for sdmmc1_enable_power()
-    ti_twl6030_init();
-    // for testing
-    ti_twl6030_vmmc_pr();
-
-    // TRM chapter 18: Control module? Is that CM2?
-    sdmmc1_enable_power();
-
-    // ==================================================
-    // STEP 2: Software reset
-    mmchs_do_sw_reset();
-    mmchs_do_state_machine_reset();
-    
-    // ==================================================
-    // Step 1b: Disable idle and stanbdy states
-    mmchs_disable_standby();
-    mmchs_enable_wakeup();
+    return complete_card_transaction();
 }
 
-/*
- * \brief Configure and initialize MMC
+/**
+ * \brief Write a 512-byte block in the card.
  *
- * TRM Section 24.5.1.1.2 on page 5114 ff
- * and BSD code ti_mmchs_hw_init in ti_mmchs.c
+ * \param block_nr Index number of block to write.
+ * \param buffer Data to write (must be at least 512 bytes in size).
  *
+ * \retval SYS_ERR_OK Block written to card.
+ * \retval MMC_ERR_TRANSFER Error interrupt or no transfer complete interrupt.
+ * \retval MMC_ERR_WRITE_READY Card not ready to write.
  */
-static void mmchs_configure(void) 
+errval_t mmchs_write_block(size_t block_nr, void *buffer)
 {
-    // ==================================================
-    // STEP 3: Set module hardware capabilities
-    // Need to write MMCHS_CAPA[26:24] ..
-    // BSD: ti_mmchs_hw_init, line 1373
-    sdhc_capa_t capa = sdhc_capa_rd(&sdhc);
-    capa = sdhc_capa_vs18_insert(capa, 0x1);
-    capa = sdhc_capa_vs30_insert(capa, 0x1);
-#if defined(MMCHS_VS33)
-    // According to the Spec, the card should support 2.7-3.6V
-    // chp 3.2 in PLS
-    capa = sdhc_capa_vs33_insert(capa, 0x1); // < NOT done by Free BSD
-#endif
-    sdhc_capa_wr(&sdhc, capa);
-    // .. and MMCHS_CUR_CAPA[23:0]
-    // This is not done by BSD code either!
-    // Also: a comment in the TRM says that this is not implemented
-
-    // MMC host and bust configuration
-    // TRM: see Figure 24-37, page 5116
-    // BSD: ti_mmchs_hw_init, line 1375, point 5
-    omap44xx_mmchs_CON_t con = omap44xx_mmchs_CON_rd(&mmchs);
-    // Set a couple of default values
-    con = omap44xx_mmchs_CON_OD_insert(con, 0x0);
-    con = omap44xx_mmchs_CON_DW8_insert(con, 0x0);
-    con = omap44xx_mmchs_CON_CEATA_insert(con, 0x0); // Standard, not ATA mode
-    // Written later
-
-    // Make sure SD bus power is not yet turned on
-    assert(sdhc_hctl_sdbp_rdf(&sdhc)==0x0);
-
-    // Get old configuration
-    sdhc_hctl_t hctl = sdhc_hctl_rd(&sdhc);
-
-    // Step 4
-    // ==================================================
-    // It seems that all cards need to support a bus width of 1
-    // SD card spec v1
-    // This is from the Free BSD code
-    uint32_t bus_width = 1;
-    switch (bus_width) {
-    case 1:
-        printf("mmchs: setting bus width to 1\n");
-        hctl = sdhc_hctl_dtw_insert(hctl, 0x0); // Data transfer width 0=1 Bit
-        con = omap44xx_mmchs_CON_DW8_insert(con, 0x0); // must be 0 for SD cards
-        break;
-    case 4:
-        printf("mmchs: setting bus width to 4\n");
-        hctl = sdhc_hctl_dtw_insert(hctl, 0x1); // Data transfer width 1=4 Bit
-        con = omap44xx_mmchs_CON_DW8_insert(con, 0x0); // must be 0 for SD cards
-        break;
-    case 8:
-        assert(!"DW8=1 (a bus width of 8) is not supported for SD cards");
-        con = omap44xx_mmchs_CON_DW8_insert(con, 0x1);
-        break;
-    default:
-        assert(!"Given bus width not supported\n");
+    MMCHS_DEBUG("%s:%d: Wait for free data lines.\n", __FUNCTION__, __LINE__);
+    size_t timeout = 1000;
+    while (omap44xx_mmchs1_mmchs_pstate_dati_rdf(&mmchs) != 0x0 && timeout--) {
+        wait_msec(1);
     }
-    
-    // Write configuration
-    omap44xx_mmchs_CON_wr(&mmchs, con);
-
-    // Step 5
-    // ==================================================
-    // XXX There seems to be a lot of redundancy with the previous setup ..
-#if defined(MMCHS_VS33)
-    hctl = sdhc_hctl_sdvs_insert(hctl, 0x7); // 0x7=3.3V
-#else
-    hctl = sdhc_hctl_sdvs_insert(hctl, 0x6); // 0x6=3.0V, 0x5=1.8V
-#endif
-    hctl = sdhc_hctl_sdbp_insert(hctl, 0x0); // Disable SD bus power
-    sdhc_hctl_wr(&sdhc, hctl);
-
-    // XXX Something happening with the TWL now, see BSE @ 1032
-    // Just ignore this for now
-
-    // Power on the BUS
-    sdhc_hctl_sdbp_wrf(&sdhc, 0x1);
-
-    // Wait for SDBP to come up
-    printf("mmchsh: turning on SD bus power .. ");
-    // Wait for init to be done
-    uint32_t sdbp_loop = 0;
-    while (sdhc_hctl_sdbp_rdf(&sdhc)==0x0) {
-        if (++sdbp_loop>1000) {
-            printf("\n");
-            print_mmchs();
-            assert(!"Timeout in setting SDBP");
-        }
-        mmchs_wait_msec(1);
-    }
-    printf("done (loop=%d)\n", sdbp_loop);
-
-    // Enable internal clock
-    // TRM Figure 24-37
-    sdhc_sysctl_ice_wrf(&sdhc, 0x1);
-
-    // Clock configuration
-    mmchs_set_frequency(0x3FF);
-
-    // BSD: get the clock from omap4_clk_hsmmc_get_source_freq
-    //          which is in arm/ti/omap4/omap4_prcm_clks.c
-    //          which then calls into omap4_clk_details
-    //          which returns 64 MHz or 96 MHz
-    
-    // Could not yet figure out what ios->clock is supposed to be ..
-    // Let's assume it is 1 ..
-    // In that case we need to divide by 1200 to get 80 kHz
-    // The closest we can get is 1023 ....
-
-    // Waiting for internal clock to become stable
-    int ics_loop = 0;
-    while (sdhc_sysctl_ics_rdf(&sdhc)!=1) {
-        ics_loop++;
-    }
-    printf("mmchs: internal clock stable .. %d loops\n", ics_loop);
-
-    // 0x3 means MMC1_ICLK=on and MMC1_FCLK=1 (see Table 24-9)
-    omap44xx_mmchs_SYSCONFIG_t sysconfig = omap44xx_mmchs_SYSCONFIG_rd(&mmchs);
-    /* sysconfig = omap44xx_mmchs_SYSCONFIG_AUTOIDLE_insert(sysconfig, 0x0); */
-    /* sysconfig = omap44xx_mmchs_SYSCONFIG_SIDLEMODE_insert(sysconfig, 0x1); */
-    sysconfig = omap44xx_mmchs_SYSCONFIG_CLOCKACTIVITY_insert(sysconfig, 0x3);
-    omap44xx_mmchs_SYSCONFIG_wr(&mmchs, sysconfig);
-    int clkactiv = 0;
-    while (omap44xx_mmchs_SYSCONFIG_CLOCKACTIVITY_rdf(&mmchs)!=0x3) {
-        clkactiv++;
+    if (timeout == 0) {
+        return MMC_ERR_WRITE_READY;
     }
-    printf("mmchs: clock acitivity enabled .. %d loops\n", clkactiv);
-
-    printf("mmchs: configuration done\n");
-    // EOF Figure 24-37
-}
-
-void mmchs_init(void)
-{
-    cm2_init();
-
-    lvaddr_t mmchs_vaddr;
-    errval_t err = map_device_register(MMCHS_BASE, 0x1000, &mmchs_vaddr);
-    assert(err_is_ok(err));
-    
-    // Initialize devices
-    omap44xx_mmchs_initialize(&mmchs, (mackerel_addr_t)mmchs_vaddr);
-    sdhc_initialize(&sdhc, (mackerel_addr_t) mmchs_vaddr + 0x200);
-    ctrlmod_init();
 
-    printf("\nmmchs: entered init().\n");
+    // Send data command
+    send_command(24, block_nr);
+    // TODO(gz): Check for errors
 
-    // Enable interrupts
-    err = inthandler_setup_arm(mmchs_handle_irq, NULL, MMC1_IRQ);
-    assert(err_is_ok(err));
-
-    // Configure Pad multiplexing
-    // Does not change anything ctrlmod_init();
-
-    // Enable power
-    cm2_enable_hsmmc1();
-
-    // Configure device
-    mmchs_pre_configure();
-    mmchs_configure();
-
-    /* // Change clock frequency to 50 MHz (as Linux) */
-    /* mmchs_change_clock_frequency(0x2); */
-    /* mmchs_do_state_machine_reset(); */
-
-    switch (sdhc_rev_srev_rdf(&sdhc)) {
-    case 0x0:
-        printf("SD Host Specification Version 1.0\n");
-        break;
-    case 0x1:
-        printf("SD Host Specification Version 2.0\n");
-        break;
-    default:
-        assert(!"Don't understand SREV field");
+    for (size_t i = 0; i < (omap44xx_mmchs1_mmchs_blk_blen_rdf(&mmchs) + 3) / 4; i++) {
+        while (omap44xx_mmchs1_mmchs_stat_bwr_rdf(&mmchs) == 0x0);
+        omap44xx_mmchs1_mmchs_data_wr(&mmchs, ((uint32_t *) buffer)[i]);
     }
-    
-
-    mmchs_init_stream();
-    mmchs_detect_card();
-    /* mmchs_init_and_ident_card(); */
-
-
-    /* printf("mmchs_detect_card\n"); */
-    /* /\* mmchs_detect_card(); *\/ */
-    /* sdhc_ie_wr(&sdhc, ~0x0); */
-    /* sdhc_ise_wr(&sdhc, ~0x0); */
-    
-    /* mmchs_print_power_state(); */
-
-    /* int resp; */
-    /* int loop = 0; */
-
-    /* do { */
-
-    /*     printf("Trying to init card, step %d\n", ++loop); */
-        
-    /*     /\* mmchs_wait_msec(100); *\/ */
-        
-    /*     /\* // See diagram 24-48 for details on how to set card frequency *\/ */
-    /*     /\* mmchs_change_clock_frequency(); *\/ */
-
-    /*     mmchs_wait_msec(100); */
-    /*     printf("Init and ident card .. \n"); */
-    /*     resp = mmchs_init_and_ident_card(); */
-
-    /*     mmchs_wait_msec(1000); */
-
-    /* } while(resp!=MMCHS_RESP_SUCCESS && loop<100); */
 
+    return complete_card_transaction();
 }
 
-/*
- * \brief Interrupt handler for MMC
+/**
+ * MMC Initialization
  *
- * See TRM 24.4.4.1, page 5092
+ * \see TRM rev Z, 24.5.1.1.2
  */
-void mmchs_handle_irq(void *args)
+void mmchs_init(void)
 {
-    printf("mmchs: got interrupt\n");
+    lvaddr_t mmchs_vaddr;
+    errval_t err = map_device_register(OMAP44XX_MMCHS1, 0x1000, &mmchs_vaddr);
+    assert(err_is_ok(err));
 
-    cm2_print_standby_state();
-    sdhc_stat_t stat = sdhc_stat_rd(&sdhc);
+    omap44xx_mmchs1_initialize(&mmchs, (mackerel_addr_t)mmchs_vaddr);
 
-    sdhc_stat_pr(PRBUFL, &sdhc);
-    printf("%s\n", PRBUF);
+    mmchs_soft_reset();
+    set_hardware_capabilities();
+    set_wake_up_configuration();
+    mmc_host_and_bus_configuration();
 
-    // Handle interrupt
-    if (sdhc_stat_bada_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt BADA\n");
-    }
-    else if (sdhc_stat_cerr_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt CERR\n");
-    }
-    else if (sdhc_stat_admae_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt ADMAE\n");
-    }
-    else if (sdhc_stat_ace_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt ACE\n");
-    }
-    else if (sdhc_stat_deb_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt DEB\n");
-    }
-    else if (sdhc_stat_dcrc_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt DCRC\n");
-    }
-    else if (sdhc_stat_dto_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt DTO\n");
-    }
-    else if (sdhc_stat_cie_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt CIE\n");
-    }
-    else if (sdhc_stat_ceb_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt CEB\n");
-    }
-    else if (sdhc_stat_ccrc_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt CCRC\n");
-    }
-    else if (sdhc_stat_cto_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt CTO\n");
-    }
-    else if (sdhc_stat_erri_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt ERRI\n");
-    }
-    else if (sdhc_stat_intb_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt BSR\n");
-    }
-    else if (sdhc_stat_inta_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt OBI\n");
-    }
-    else if (sdhc_stat_cirq_extract(stat)==0x1) {
-        sdhc_ise_cirq_wrf(&sdhc, 0x0);
-        sdhc_ie_cirq_wrf(&sdhc, 0x0);
-        printf("Implement mmch interrupt handler action for interrupt CIRQ\n");
-    }
-    else if (sdhc_stat_crem_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt CREM\n");
-    }
-    else if (sdhc_stat_cins_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt CINS\n");
-    }
-    else if (sdhc_stat_brr_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt BRR\n");
-    }
-    else if (sdhc_stat_bwr_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt BWR\n");
-    }
-    else if (sdhc_stat_dma_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt DMA\n");
-    }
-    else if (sdhc_stat_bge_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt BGE\n");
-    }
-    else if (sdhc_stat_tc_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt TC\n");
-    }
-    else if (sdhc_stat_cc_extract(stat)==0x1) {
-        printf("Implement mmch interrupt handler action for interrupt CC\n");
-    }
-
-    // Unset STAT bits
-    sdhc_stat_wr(&sdhc, ~0x0);
-    
-    printf("%s:%d: Never return ..\n", __FUNCTION__, __LINE__);
-    while (1) ;
+    mmchs_identify_card();
 }
-
-
-int main(int argc, char** argv) 
-{
-    mmchs_init();
-    return 0;
-}
\ No newline at end of file
diff --git a/usr/drivers/omap44xx/mmchs/mmchs.h b/usr/drivers/omap44xx/mmchs/mmchs.h
new file mode 100644 (file)
index 0000000..3872717
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2013, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef MMCHS2_H
+#define MMCHS2_H
+
+#include <barrelfish/barrelfish.h>
+
+#include "mmchs_debug.h"
+#include "omap44xx_cm2.h"
+#include "omap44xx_ctrlmod.h"
+#include "i2c.h"
+#include "twl6030.h"
+
+void mmchs_init(void);
+errval_t mmchs_read_block(size_t block_nr, void *buffer);
+errval_t mmchs_write_block(size_t block_nr, void *buffer);
+
+void init_service(void);
+
+#endif // MMCHS2_H
\ No newline at end of file
diff --git a/usr/drivers/omap44xx/mmchs/mmchs_debug.h b/usr/drivers/omap44xx/mmchs/mmchs_debug.h
new file mode 100644 (file)
index 0000000..e73703f
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2013, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#ifndef MMCHS2_DEBUG_H
+#define MMCHS2_DEBUG_H
+
+//#define MMCHS_SERVICE_DEBUG 1
+
+#if defined(MMCHS_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
+#define MMCHS_DEBUG(x...) debug_printf(x)
+#else
+#define MMCHS_DEBUG(x...) ((void)0)
+#endif
+
+#endif // MMCHS2_DEBUG_H
\ No newline at end of file
index 52f537d..6011278 100644 (file)
@@ -7,21 +7,10 @@
  * ETH Zurich D-INFK, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
  */
 
-#ifndef __ARM_CM2_H__
-#define __ARM_CM2_H__
+#ifndef __OMAP44XX_CM2_H__
+#define __OMAP44XX_CM2_H__
 
 #include <barrelfish/barrelfish.h>
-#include <dev/omap/omap44xx_mmchs_dev.h>
-#include <dev/omap/omap44xx_sysctrl_padconf_core_dev.h>
-
-// We need this because paging_arm_device returns the address 
-// of the beginning of the section in virtual memory ..
-// We map sections because we don't use the second level page table 
-// at this point yet. XXXX Is this actually true?
-#define omap_dev_map(p) \
-    (mackerel_addr_t) \
-    (paging_map_device(p, ARM_L1_SECTION_BYTES) \
-     + (p & ARM_L1_SECTION_MASK))
 
 void cm2_enable_i2c(size_t i2c_index);
 int  cm2_get_hsmmc1_base_clock(void);
@@ -31,4 +20,4 @@ void cm2_print_standby_state(void);
 void cm2_enable_hsmmc1(void);
 void cm2_init(void);
 
-#endif /* __ARM_CM2_H__ */
+#endif /* __OMAP44XX_CM2_H__ */
index 391f28f..6afb429 100644 (file)
@@ -7,8 +7,8 @@
  * ETH Zurich D-INFK, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
  */
 
-#ifndef __ARM_CTRLMOD_H__
-#define __ARM_CTRLMOD_H__
+#ifndef __OMAP44XX_CTRLMOD_H__
+#define __OMAP44XX_CTRLMOD_H__
 
 #include <barrelfish/barrelfish.h>
 #include <dev/omap/omap44xx_sysctrl_padconf_core_dev.h>
@@ -24,4 +24,4 @@ void sdmmc1_enable_power(void);
 
 void pbias_handle_irq(void *args);
 
-#endif /* __ARM_CTRLMOD_H__ */
+#endif /* __OMAP44XX_CTRLMOD_H__ */
diff --git a/usr/drivers/omap44xx/mmchs/omap44xx_mmchs.h b/usr/drivers/omap44xx/mmchs/omap44xx_mmchs.h
deleted file mode 100644 (file)
index c3faeff..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012, ETH Zurich.
- * All rights reserved.
- *
- * This file is distributed under the terms in the attached LICENSE file.
- * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
- */
-
-#ifndef __ARM_MMCHS_H__
-#define __ARM_MMCHS_H__
-
-#include <barrelfish/types.h>
-
-// Use 3.3 Volt for bus voltage
-// #define MMCHS_VS33 1
-
-// Base address of the MMC host controller
-// TRM Table 24-56, page 5140
-#define MMCHS_BASE 0x4809C000U
-
-/*
- * List of commands
- *
- * see TRM MMCHS_CMD documentation, table 24-83, page 5160
- * and SD card specification
- */
-#define CMD0 0x0   // GO_IDLE_STATE / maybe also just a card reset ..
-#define CMD5 0x5   // SEND_OP_COND
-#define CMD8 0x8   // Detect v2 card, handshake voltage
-
-#define MMCHS_RESP_SUCCESS 0UL
-#define MMCHS_RESP_TIMEOUT 1UL
-
-#define CYCLES_PER_MSEC 1200000UL
-#define CYCLES_PER_SEC (1000*CYCLES_PER_MSEC)
-
-void        mmchs_send_cmd(int cmd_idx, uint32_t arg);
-void        mmchs_identify_card(void);
-int         mmchs_init_and_ident_card(void);
-
-static void mmchs_change_clock_frequency(int clkdiv);
-static int  mmchs_finalize_cmd(void);
-void mmchs_handle_irq(void *args);
-void mmchs_init(void);
-
-// MMC1 interrupt, two lines
-//    (MM_IRQ_50 for Cortex-M3 INTC)
-//     MA_IRQ_83 for Cortex-A9 INTC
-// see Free BSD sys/arm/ti/omap4/omap4_reg.h
-#define MMC1_IRQ (32+83) 
-
-#endif /* __ARM_MMCHS_H__ */
diff --git a/usr/drivers/omap44xx/mmchs/service.c b/usr/drivers/omap44xx/mmchs/service.c
new file mode 100644 (file)
index 0000000..d5f7735
--- /dev/null
@@ -0,0 +1,175 @@
+/**
+ * \file
+ * \brief Implementation of ata_rw28.if interface (to enable working vfs_fat)
+ */
+/*
+ * Copyright (c) 2013, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <barrelfish/barrelfish.h>
+
+#include <barrelfish/nameservice_client.h>
+
+#include <if/ata_rw28_defs.h>
+#include <if/ata_rw28_thc.h>
+#include <thc/thc.h>
+
+#include "mmchs.h"
+#include "mmchs_debug.h"
+
+#define SECTION_SIZE 512
+#define SECTION_ROUND_UP(x) ( ((x) + (SECTION_SIZE-1))  & (~(SECTION_SIZE-1)) )
+
+static void read_dma(struct ata_rw28_thc_service_binding_t *sv,
+                     uint32_t read_size, uint32_t start_lba)
+{
+    MMCHS_DEBUG("%s:%d\n", __FUNCTION__, __LINE__);
+    size_t buffer_size = SECTION_ROUND_UP(read_size);
+    void *buffer = malloc(buffer_size);
+    assert(buffer != NULL);
+
+    uint8_t *bufptr = (uint8_t *)buffer;
+    for (size_t i = 0; i < (buffer_size / SECTION_SIZE); i++) {
+        errval_t err = mmchs_read_block(start_lba, bufptr);
+        assert(err_is_ok(err));
+        bufptr += SECTION_SIZE;
+    }
+    sv->send.read_dma(sv, buffer, buffer_size);
+    free(buffer);
+}
+
+static void read_dma_block(struct ata_rw28_thc_service_binding_t *sv, uint32_t lba)
+{
+    MMCHS_DEBUG("%s:%d lba=%d\n", __FUNCTION__, __LINE__, lba);
+
+    void *buffer = malloc(SECTION_SIZE);
+    assert(buffer != NULL);
+
+    errval_t err = mmchs_read_block(lba, buffer);
+    assert(err_is_ok(err));
+
+    sv->send.read_dma_block(sv, buffer, SECTION_SIZE);
+    free(buffer);
+}
+
+static void write_dma(struct ata_rw28_thc_service_binding_t *sv,
+                      uint8_t *buffer, size_t buffer_len, uint32_t lba)
+{
+    MMCHS_DEBUG("%s:%d\n", __FUNCTION__, __LINE__);
+    sv->send.write_dma(sv, LIB_ERR_NOT_IMPLEMENTED);
+}
+
+static void identify_device(struct ata_rw28_thc_service_binding_t *sv)
+{
+    MMCHS_DEBUG("%s:%d\n", __FUNCTION__, __LINE__);
+    sv->send.identify_device(sv, NULL, 0);
+}
+
+
+static void flush_cache(struct ata_rw28_thc_service_binding_t *sv)
+{
+    MMCHS_DEBUG("%s:%d\n", __FUNCTION__, __LINE__);
+    sv->send.flush_cache(sv, SYS_ERR_OK);
+}
+
+static void service_client(struct ata_rw28_thc_service_binding_t *sv)
+{
+    DO_FINISH({
+        bool stop = false;
+        while (!stop) {
+            ata_rw28_service_msg_t m;
+            sv->recv_any(sv, &m, (struct ata_rw28_service_selector) {
+                .read_dma = 1,
+                .read_dma_block = 1,
+                .write_dma = 1,
+                .identify_device = 1,
+                .flush_cache = 1
+            });
+
+            switch (m.msg) {
+
+            case ata_rw28_read_dma:
+                read_dma(sv, m.args.read_dma.in.read_size, m.args.read_dma.in.start_lba);
+                break;
+
+            case ata_rw28_read_dma_block:
+                read_dma_block(sv, m.args.read_dma_block.in.lba);
+                break;
+
+            case ata_rw28_write_dma:
+                write_dma(sv, m.args.write_dma.in.buffer, m.args.write_dma.in.buffer_size, m.args.write_dma.in.lba);
+                break;
+
+            case ata_rw28_identify_device:
+                identify_device(sv);
+                break;
+
+            case ata_rw28_flush_cache:
+                flush_cache(sv);
+                break;
+
+            default:
+                assert(!"Unexpected message");
+                break;
+            }
+        }
+    });
+}
+
+void init_service(void)
+{
+    errval_t err;
+    iref_t iref;
+    struct ata_rw28_thc_service_binding_t *sv;
+    struct ata_rw28_binding *b;
+    struct ata_rw28_thc_export_info info;
+
+    MMCHS_DEBUG("%s:%d: Starting server\n", __FUNCTION__, __LINE__);
+    err = ata_rw28_thc_export(&info,
+                              "mmchs",
+                              get_default_waitset(),
+                              IDC_EXPORT_FLAGS_DEFAULT,
+                              &iref);
+
+    MMCHS_DEBUG("%s:%d: Done export iref=%"PRIuIREF"\n", __FUNCTION__, __LINE__, iref);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "export failed");
+        abort();
+    }
+
+    DO_FINISH({
+        while (1) {
+            MMCHS_DEBUG("%s:%d: Server waiting for connection\n", __FUNCTION__, __LINE__);
+            err = ata_rw28_thc_accept(&info, &b);
+            if (err_is_fail(err)) {
+                DEBUG_ERR(err, "accept failed");
+                abort();
+            }
+
+            sv = malloc(sizeof(struct ata_rw28_thc_service_binding_t));
+            if (sv == NULL) {
+                DEBUG_ERR(err, "malloc failed");
+                abort();
+            }
+
+            err = ata_rw28_thc_init_service(sv, b, b);
+            if (err_is_fail(err)) {
+                DEBUG_ERR(err, "init failed");
+                abort();
+            }
+
+            MMCHS_DEBUG("%s:%d: Got service %p\n", __FUNCTION__, __LINE__, sv);
+            ASYNC({service_client(sv);});
+        }
+    });
+}
index 0a10f5e..2516033 100644 (file)
@@ -6,42 +6,50 @@
  * If you do not find this file, copies can be found by writing to:
  * ETH Zurich D-INFK, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
  */
-
-#include <kernel.h>
-#include <paging_kernel_arch.h>
-
-#include <arm_hal.h>
-#include <ti_i2c.h>
-#include <ti_twl6030.h>
+#include "i2c.h"
+#include "twl6030.h"
 
 static uint8_t _ti_twl6030_id1_read_8(void *d, size_t off);
 static void _ti_twl6030_id1_write_8(void *d, size_t off, uint8_t regval);
-
 #define ti_twl6030_id1_read_8(dev, off) _ti_twl6030_id1_read_8(dev, off)
 #define ti_twl6030_id1_write_8(dev, off, regval) _ti_twl6030_id1_write_8(dev, off, regval)
-
 #include <dev/ti_twl6030_dev.h>
+
 // I2C Host controller id
 #define I2C_HC 0
-
 // I2C slave address for id1 reads and writes is 0x48
 #define ID1_I2C_ADDR 0x48
+
+#define PBS (8*1024)
+static char PRBUF[PBS];
+#define PRBUFL PRBUF, (PBS-1)
+
+#include "mmchs_debug.h"
+#if defined(TWL_SERIVCE_DEBUG) || defined(MMCHS_SERVICE_DEBUG) || defined(GLOBAL_DEBUG)
+#define TWL_DEBUG(x...) printf(x)
+#else
+#define TWL_DEBUG(x...) ((void)0)
+#endif
+
+static ti_twl6030_t twl;
+
 static inline uint8_t _ti_twl6030_id1_read_8(void *d, size_t off)
 {
+    errval_t err;
+
     struct i2c_msg msg[2];
 
     uint8_t reg = off & 0xff;
     uint8_t result = 0;
 
-    errval_t err;
-
-    printf("id1_read_8(reg=0x%"PRIx8")\n", reg);
+    TWL_DEBUG("id1_read_8(reg=0x%"PRIx8")\n", reg);
 
     /* set register to read from */
     msg[0].slave = ID1_I2C_ADDR;
     msg[0].flags = I2C_WR | I2C_NOSTOP;
     msg[0].length = 1;
     msg[0].buf = &reg;
+
     /* read data back */
     msg[1].slave = ID1_I2C_ADDR;
     msg[1].flags = I2C_RD;
@@ -51,12 +59,13 @@ static inline uint8_t _ti_twl6030_id1_read_8(void *d, size_t off)
     err = ti_i2c_transfer(I2C_HC, msg, 2);
 
     if (err_is_fail(err)) {
-        printf("ti_i2c_transfer: %"PRIuERRV"\n", err);
+        TWL_DEBUG("ti_i2c_transfer: %"PRIuERRV"\n", err);
         return 0;
     }
 
     return result;
 }
+
 static inline void _ti_twl6030_id1_write_8(void *d, size_t off, uint8_t regval)
 {
     struct i2c_msg msg;
@@ -76,141 +85,95 @@ static inline void _ti_twl6030_id1_write_8(void *d, size_t off, uint8_t regval)
     err = ti_i2c_transfer(I2C_HC, &msg, 1);
 
     if (err_is_fail(err)) {
-        printf("ti_i2c_transfer failed in mackerel: %"PRIuERRV"\n", err);
+        TWL_DEBUG("ti_i2c_transfer failed in mackerel: %"PRIuERRV"\n", err);
     }
 
     return;
 }
 
-#define PBS (8*1024)
-static char PRBUF[PBS];
-#define PRBUFL PRBUF, (PBS-1)
-
-static ti_twl6030_t twl;
-
 void ti_twl6030_init(void)
 {
-    printf("twl init\n");
-    //ti_twl6030_initialize(&twl, 0x0);
-
-    // initialize I2C1 host controller
+    TWL_DEBUG("%s:%d\n", __FUNCTION__, __LINE__);
     ti_i2c_init(I2C_HC);
-    //printf("read VMMC_CFG_VOLTAGE %"PRIu8"\n", _ti_twl6030_id1_read_8(NULL, 0x9B));
-    //printf("read VMMC_CFG_VOLTAGE %"PRIu8"\n", _ti_twl6030_id1_read_8(NULL, 0x9B));
-
-    //ti_twl6030_vmmc_pr();
-    /*printf("scanning TWL\n");
-    ti_twl6030_scan();
-    printf("after scan\n");*/
 }
 
 void ti_twl6030_vmmc_pr(void)
 {
     ti_twl6030_pr(PRBUFL, &twl);
-    printf("%s\n", PRBUF);
-}
-
-void ti_twl6030_scan(void)
-{
-    int i, base = 0x48;
-    for (i = 0; i < 4; i++) {
-        struct i2c_msg msg;
-        uint8_t tmp;
-        msg.slave = base + i;
-        msg.flags = I2C_RD;
-        msg.length = 1;
-        msg.buf = &tmp;
-
-        errval_t err = ti_i2c_transfer(I2C_HC, &msg, 1);
-        if (err_is_ok(err)) {
-            printf("found subdev at 0x%x\n", base + i);
-        }
-    }
-    return;
+    TWL_DEBUG("%s\n", PRBUF);
 }
 
 static ti_twl6030_vsel_t millis_to_vsel(int millis)
 {
     switch (millis) {
-        case 0:
-            return ti_twl6030_v0v0;
-        case 1000:
-            return ti_twl6030_v1v0;
-        case 1100:
-            return ti_twl6030_v1v1;
-        case 1200:
-            return ti_twl6030_v1v2;
-        case 1300:
-            return ti_twl6030_v1v3;
-        case 1400:
-            return ti_twl6030_v1v4;
-        case 1500:
-            return ti_twl6030_v1v5;
-        case 1600:
-            return ti_twl6030_v1v6;
-        case 1700:
-            return ti_twl6030_v1v7;
-        case 1800:
-            return ti_twl6030_v1v8;
-        case 1900:
-            return ti_twl6030_v1v9;
-        case 2000:
-            return ti_twl6030_v2v0;
-        case 2100:
-            return ti_twl6030_v2v1;
-        case 2200:
-            return ti_twl6030_v2v2;
-        case 2300:
-            return ti_twl6030_v2v3;
-        case 2400:
-            return ti_twl6030_v2v4;
-        case 2500:
-            return ti_twl6030_v2v5;
-        case 2600:
-            return ti_twl6030_v2v6;
-        case 2700:
-            return ti_twl6030_v2v7;
-        case 2750:
-            return ti_twl6030_v2v75;
-        case 2800:
-            return ti_twl6030_v2v8;
-        case 2900:
-            return ti_twl6030_v2v9;
-        case 3000:
-            return ti_twl6030_v3v0;
-        case 3100:
-            return ti_twl6030_v3v1;
-        case 3200:
-            return ti_twl6030_v3v2;
-        case 3300:
-            return ti_twl6030_v3v3;
-        default:
-            printf("voltage (%d) not available, returning 0.0V\n", millis);
-            return ti_twl6030_v0v0;
+    case 0:
+        return ti_twl6030_v0v0;
+    case 1000:
+        return ti_twl6030_v1v0;
+    case 1100:
+        return ti_twl6030_v1v1;
+    case 1200:
+        return ti_twl6030_v1v2;
+    case 1300:
+        return ti_twl6030_v1v3;
+    case 1400:
+        return ti_twl6030_v1v4;
+    case 1500:
+        return ti_twl6030_v1v5;
+    case 1600:
+        return ti_twl6030_v1v6;
+    case 1700:
+        return ti_twl6030_v1v7;
+    case 1800:
+        return ti_twl6030_v1v8;
+    case 1900:
+        return ti_twl6030_v1v9;
+    case 2000:
+        return ti_twl6030_v2v0;
+    case 2100:
+        return ti_twl6030_v2v1;
+    case 2200:
+        return ti_twl6030_v2v2;
+    case 2300:
+        return ti_twl6030_v2v3;
+    case 2400:
+        return ti_twl6030_v2v4;
+    case 2500:
+        return ti_twl6030_v2v5;
+    case 2600:
+        return ti_twl6030_v2v6;
+    case 2700:
+        return ti_twl6030_v2v7;
+    case 2750:
+        return ti_twl6030_v2v75;
+    case 2800:
+        return ti_twl6030_v2v8;
+    case 2900:
+        return ti_twl6030_v2v9;
+    case 3000:
+        return ti_twl6030_v3v0;
+    case 3100:
+        return ti_twl6030_v3v1;
+    case 3200:
+        return ti_twl6030_v3v2;
+    case 3300:
+        return ti_twl6030_v3v3;
+    default:
+        TWL_DEBUG("voltage (%d) not available, returning 0.0V\n", millis);
+        return ti_twl6030_v0v0;
     }
 }
 
 
-/*static void ti_twl6030_vmmc_sleep(void) 
+void ti_twl6030_vmmc_off(void)
 {
     // turn off
     ti_twl6030_cfg_state_w_t st = ti_twl6030_cfg_state_w_default;
-    st = ti_twl6030_cfg_state_w_grp_app_insert(st, 0x11);
-    st = ti_twl6030_cfg_state_w_grp_con_insert(st, 0x11);
-    st = ti_twl6030_cfg_state_w_grp_mod_insert(st, 0x11);
-    st = ti_twl6030_cfg_state_w_state_insert(st, ti_twl6030_pwr_sleep);
-    ti_twl6030_vmmc_cfg_state_w_wr(&twl, st);
-}*/
-
-void ti_twl6030_vmmc_off(void) 
-{
-    // turn off
-    ti_twl6030_cfg_state_w_t st = ti_twl6030_cfg_state_w_default;
-    st = ti_twl6030_cfg_state_w_grp_app_insert(st, 0x0);
-    st = ti_twl6030_cfg_state_w_grp_con_insert(st, 0x0);
-    st = ti_twl6030_cfg_state_w_grp_mod_insert(st, 0x0);
+    st = ti_twl6030_cfg_state_w_grp_app_insert(st, 0x1);
+    st = ti_twl6030_cfg_state_w_grp_con_insert(st, 0x1);
+    st = ti_twl6030_cfg_state_w_grp_mod_insert(st, 0x1);
     st = ti_twl6030_cfg_state_w_state_insert(st, 0x0);
-    
+
     ti_twl6030_vmmc_cfg_state_w_rawwr(&twl, st);
 }
 
@@ -221,27 +184,35 @@ void ti_twl6030_vmmc_on(void)
     st = ti_twl6030_cfg_state_w_grp_app_insert(st, 0x1);
     st = ti_twl6030_cfg_state_w_grp_con_insert(st, 0x1);
     st = ti_twl6030_cfg_state_w_grp_mod_insert(st, 0x1);
-    st = ti_twl6030_cfg_state_w_state_insert(st, ti_twl6030_pwr_on);
+    st = ti_twl6030_cfg_state_w_state_insert(st, 0x1);
     ti_twl6030_vmmc_cfg_state_w_wr(&twl, st);
 }
 
+static volatile uint32_t dummy = 0;
+static void wait_msec(long msec)
+{
+    int i = 0, sum = 0;
+    long end = (1200000 * msec / 8);
+
+    // Cannot use volatile variables in loop
+    while (++i < end)  {
+        sum += i + end;
+    }
+
+    dummy += sum;
+}
+
 
 errval_t ti_twl6030_set_vmmc_vsel(int millis)
 {
-    printf("ti_twl6030_vmmc_vsel\n");
+    TWL_DEBUG("ti_twl6030_vmmc_vsel\n");
     //ti_twl6030_mmcctrl_vmmc_auto_off_wrf(&twl, 0x0);
     ti_twl6030_mmcctrl_sw_fc_wrf(&twl, 0x1);
-    
-    //ti_twl6030_vmmc_off();
-    //ti_twl6030_vmmc_sleep();
-    ti_twl6030_vmmc_pr();
 
-    ti_twl6030_vsel_t vsel = millis_to_vsel(millis);
-    // set regulator to application mode
-    //ti_twl6030_vmmc_cfg_grp_grp_app_wrf(&twl, 0x1);
-    //ti_twl6030_vmmc_cfg_grp_grp_mod_wrf(&twl, 0x1);
-    //ti_twl6030_vmmc_cfg_grp_grp_con_wrf(&twl, 0x1);
+    ti_twl6030_vmmc_off();
+    wait_msec(10);
 
+    ti_twl6030_vsel_t vsel = millis_to_vsel(millis);
     ti_twl6030_vmmc_cfg_voltage_vsel_wrf(&twl, vsel);
 
     ti_twl6030_vmmc_on();
similarity index 90%
rename from usr/drivers/omap44xx/mmchs/ti_twl6030.h
rename to usr/drivers/omap44xx/mmchs/twl6030.h
index aaf1682..370dcee 100644 (file)
@@ -9,14 +9,14 @@
 #ifndef __TI_TWL6030_H__
 #define __TI_TWL6030_H__
 
-#include <barrelfish/types.h> 
+#include <barrelfish/types.h>
 #include <errors/errno.h>
 
 void ti_twl6030_init(void);
-void ti_twl6030_scan(void);
-void ti_twl6030_vmmc_pr(void);
 errval_t ti_twl6030_set_vmmc_vsel(int millis);
 
+void ti_twl6030_vmmc_pr(void);
+
 void ti_twl6030_vmmc_on(void);
 void ti_twl6030_vmmc_off(void);
 
index c24fa68..01568fb 100644 (file)
@@ -145,6 +145,11 @@ int main(int argc, char** argv)
         err = mi->start_function(0, mi, "hw.arm.omap44xx.mmchs {}");
         assert(err_is_ok(err));
     }
+    mi = find_module("mmchs2");
+    if (mi != NULL) {
+        err = mi->start_function(0, mi, "hw.arm.omap44xx.mmchs {}");
+        assert(err_is_ok(err));
+    }
     mi = find_module("prcm");
     if (mi != NULL) {
         err = mi->start_function(0, mi, "hw.arm.omap44xx.prcm {}");
index d32ae62..2f9d9a8 100644 (file)
@@ -64,6 +64,10 @@ static struct allowed_registers mmchs = {
         {OMAP44XX_SYSCTRL_PADCONF_WAKEUP, 0X1000},
         // MMCHS
         {OMAP44XX_MMCHS1, 0x1000},
+        {OMAP44XX_MMCHS2, 0x1000},
+        {OMAP44XX_MMCHS3, 0x1000},
+        {OMAP44XX_MMCHS4, 0x1000},
+        {OMAP44XX_MMCHS5, 0x1000},
         {0x0, 0x0}
     }
 };