1/* 2 * Copyright (c) 2012, ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, CAB F.78, Universitaetstr 6, CH-8092 Zurich. 8 */ 9 10#include <barrelfish/barrelfish.h> 11#include <barrelfish/debug.h> 12#include <barrelfish/inthandler.h> 13#include <barrelfish/waitset.h> 14 15#include <driverkit/driverkit.h> 16 17#include "omap44xx_ctrlmod.h" 18 19#include "mmchs.h" 20#include "cap_slots.h" 21#include "mmchs_debug.h" 22 23#if defined(CTRLMOD_SERVICE_DEBUG) || defined(MMCHS_SERVICE_DEBUG) || defined(GLOBAL_DEBUG) 24#define CTRLMOD_DEBUG(x...) debug_printf(x) 25#else 26#define CTRLMOD_DEBUG(x...) ((void)0) 27#endif 28 29static volatile uint32_t dummy = 0; 30static void wait_msec(long msec) 31{ 32 int i = 0, sum = 0; 33 long end = (1200000 * msec / 8); 34 35 // Cannot use volatile variables in loop 36 while (++i < end) { 37 sum += i + end; 38 } 39 40 dummy += sum; 41} 42 43/* 44 * \brief Initialization of control module 45 */ 46void ctrlmod_init(struct mmchs_driver_state* st) 47{ 48 CTRLMOD_DEBUG("%s:%d\n", __FUNCTION__, __LINE__); 49 50 lvaddr_t vaddr; 51 errval_t err = map_device_cap(st->caps[PADCONF_CORE_SLOT], &vaddr); 52 assert(err_is_ok(err)); 53 54 // Initialize Mackerel 55 omap44xx_sysctrl_padconf_core_initialize(&st->ctrlmod, (mackerel_addr_t) vaddr); 56} 57 58/* 59 * We need to configure the extended-drain I/O pads to the right voltage and 60 * turn on the external power supply (TWL6030 on the pandaboard) 61 */ 62void sdmmc1_enable_power(struct mmchs_driver_state* st) 63{ 64 // compare with Table 18-109 in OMAP TRM, p3681 65 // Step 1: software must keep PWRDNZ low when setting up voltages 66 CTRLMOD_DEBUG("%s: Step 1\n", __FUNCTION__); 67 omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_pwrdnz_wrf(&st->ctrlmod, 0x0); 68 omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pwrdnz_wrf(&st->ctrlmod, 0x0); 69 70 // Step 2: preliminary settings for MMC1_PBIAS and MMC1 I/O cell 71 CTRLMOD_DEBUG("%s: Step 2\n", __FUNCTION__); 72 // 1. turn of hiz mode 73 omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_hiz_mode_wrf(&st->ctrlmod, 0x0); 74 75 // 2. setup PBIAS_IRQ (MA_IRQ_75) 76 // We don't use the interrupt 77 78 // 3. pad multiplexing -- looks ok when dumping pad registers, so I'm 79 // not doing anything right now -SG 80 81 // 4. set MMC1 speed control to 26MHz@30pF (0x0) -- alternative 65MHz@30pF (0x1) 82 omap44xx_sysctrl_padconf_core_control_mmc1_sdmmc1_dr0_speedctrl_wrf(&st->ctrlmod, 83 0x0); 84 omap44xx_sysctrl_padconf_core_control_mmc1_sdmmc1_dr1_speedctrl_wrf(&st->ctrlmod, 85 0x0); 86 omap44xx_sysctrl_padconf_core_control_mmc1_sdmmc1_dr2_speedctrl_wrf(&st->ctrlmod, 87 0x0); 88 89 // 5. set MMC1 pullup strength to 10-50kOhm (0x1) -- alt. 50-110kOhm (0x0) 90 omap44xx_sysctrl_padconf_core_control_mmc1_sdmmc1_pustrength_grp0_wrf(&st->ctrlmod, 91 0x0); 92 omap44xx_sysctrl_padconf_core_control_mmc1_sdmmc1_pustrength_grp1_wrf(&st->ctrlmod, 93 0x0); 94 omap44xx_sysctrl_padconf_core_control_mmc1_sdmmc1_pustrength_grp2_wrf(&st->ctrlmod, 95 0x0); 96 omap44xx_sysctrl_padconf_core_control_mmc1_sdmmc1_pustrength_grp3_wrf(&st->ctrlmod, 97 0x0); 98 99 // Step 3: Program desired SDMMC1_VDDS for MMC I/O in I2C attached power 100 // controller (3.0V) 101 errval_t err = st->twl6030_binding->rpc_tx_vtbl.vmmc_vsel(st->twl6030_binding, 3000); 102 assert(err_is_ok(err)); 103 104 // Step 4: Set VMODE bit according to Step 3 (0x1 == 3.0V) 105 CTRLMOD_DEBUG("%s: Step 4\n", __FUNCTION__); 106 omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_vmode_wrf(&st->ctrlmod, 0x1); 107 108 // Step 5: wait for SDMMC1_VDDS voltage to stabilize TODO 109 // might already be stable after reset? -SG 110 111 // Step 6: Disable PWRDNZ mode for MMC1_PBIAS and MMC1 I/O cell 112 CTRLMOD_DEBUG("%s: Step 6\n", __FUNCTION__); 113 omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_pwrdnz_wrf(&st->ctrlmod, 0x1); 114 wait_msec(100); 115 omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pwrdnz_wrf(&st->ctrlmod, 0x1); 116 117 CTRLMOD_DEBUG("%s:%d: wait until supply_hi_out is 0x1\n", __FUNCTION__, __LINE__); 118 while (omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_supply_hi_out_rdf(&st->ctrlmod) 119 != 0x1) {} 120 121 // Step 7: Store SUPPLY_HI_OUT bit 122 uint8_t supply_hi_out = 123 omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_supply_hi_out_rdf(&st->ctrlmod); 124 CTRLMOD_DEBUG("%s: Step 7: supply_hi_out = %d\n", __FUNCTION__, supply_hi_out); 125 CTRLMOD_DEBUG("%s: Step 7: vmode_error = %d\n", __FUNCTION__, 126 omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_vmode_error_rdf(&st->ctrlmod)); 127 CTRLMOD_DEBUG("%s: Step 8\n", __FUNCTION__); 128 129 // Step 8: check VMODE_ERROR and set PWRDNZ if error 130 if (omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_vmode_error_rdf(&st->ctrlmod)) { 131 CTRLMOD_DEBUG("got VMODE error\n"); 132 omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pwrdnz_wrf(&st->ctrlmod, 0x0); 133 omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_pwrdnz_wrf(&st->ctrlmod, 0x0); 134 } 135 136 // Step 9: check if SUPPLY_HI_OUT corresponds to SDMMC1_VDDS (3.0V) 137 if (supply_hi_out != 0x1) { 138 CTRLMOD_DEBUG("SDMMC1_VDDS seems to be != 3.0V\n"); 139 // TODO: redo setting SDMMC1_VDDS 140 } else { 141 // supply_hi_out should be 0x1 (3.0V) 142 assert(supply_hi_out == 0x1); 143 // set VMODE bit to supply_hi_out 144 omap44xx_sysctrl_padconf_core_control_pbiaslite_mmc1_pbiaslite_vmode_wrf(&st->ctrlmod, supply_hi_out); 145 } 146 147 // Step 12: clear PBIAS IRQ 148 // Ignored 149} 150