| /* |
| * (C) Copyright 2009 SAMSUNG Electronics |
| * Minkyu Kang <mk7.kang@samsung.com> |
| * Portions Copyright (C) 2011-2012 NVIDIA Corporation |
| * |
| * Copyright 2013 Google Inc. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| * |
| */ |
| |
| #ifndef __DRIVERS_BLOCKDEV_TEGRA_MMC_H_ |
| #define __DRIVERS_BLOCKDEV_TEGRA_MMC_H_ |
| |
| #include "base/io.h" |
| #include "drivers/blockdev/blockdev.h" |
| #include "drivers/blockdev/mmc.h" |
| #include "drivers/gpio/gpio.h" |
| |
| typedef struct { |
| uint32_t sysad; // _SYSTEM_ADDRESS_0 |
| uint16_t blksize; // _BLOCK_SIZE_BLOCK_COUNT_0 15:00 |
| uint16_t blkcnt; // _BLOCK_SIZE_BLOCK_COUNT_0 31:16 |
| uint32_t argument; // _ARGUMENT_0 |
| uint16_t trnmod; // _CMD_XFER_MODE_0 15:00 xfer mode |
| uint16_t cmdreg; // _CMD_XFER_MODE_0 31:16 cmd reg |
| uint32_t rspreg0; // _RESPONSE_R0_R1_0 CMD RESP 31:00 |
| uint32_t rspreg1; // _RESPONSE_R2_R3_0 CMD RESP 63:32 |
| uint32_t rspreg2; // _RESPONSE_R4_R5_0 CMD RESP 95:64 |
| uint32_t rspreg3; // _RESPONSE_R6_R7_0 CMD RESP 127:96 |
| uint32_t bdata; // _BUFFER_DATA_PORT_0 |
| uint32_t prnsts; // _PRESENT_STATE_0 |
| uint8_t hostctl; // _POWER_CONTROL_HOST_0 7:00 |
| uint8_t pwrcon; // _POWER_CONTROL_HOST_0 15:8 |
| uint8_t blkgap; // _POWER_CONTROL_HOST_9 23:16 |
| uint8_t wakcon; // _POWER_CONTROL_HOST_0 31:24 |
| uint16_t clkcon; // _CLOCK_CONTROL_0 15:00 |
| uint8_t timeoutcon; // _TIMEOUT_CTRL 23:16 |
| uint8_t swrst; // _SW_RESET_ 31:24 |
| uint32_t norintsts; // _INTERRUPT_STATUS_0 |
| uint32_t norintstsen; // _INTERRUPT_STATUS_ENABLE_0 |
| uint32_t norintsigen; // _INTERRUPT_SIGNAL_ENABLE_0 |
| uint16_t acmd12errsts; // _AUTO_CMD12_ERR_STATUS_0 15:00 |
| uint8_t res1[2]; // _RESERVED 31:16 |
| uint32_t capareg; // _CAPABILITIES_0 |
| uint8_t res2[4]; // RESERVED, offset 44h-47h |
| uint32_t maxcurr; // _MAXIMUM_CURRENT_0 |
| uint8_t res3[4]; // RESERVED, offset 4Ch-4Fh |
| uint16_t setacmd12err; // offset 50h |
| uint16_t setinterr; // offset 52h |
| uint8_t admaerr; // offset 54h |
| uint8_t res4[3]; // RESERVED, offset 55h-57h |
| unsigned long admaaddr; // offset 58h-5Fh |
| uint8_t res5[0xa0]; // RESERVED, offset 60h-FBh |
| uint16_t slotintstatus; // offset FCh |
| uint16_t hcver; // HOST Version |
| uint32_t venclkctl; // _VENDOR_CLOCK_CNTRL_0, 100h |
| uint32_t venspictl; // _VENDOR_SPI_CNTRL_0, 104h |
| uint32_t venspiintsts; // _VENDOR_SPI_INT_STATUS_0, 108h |
| uint32_t venceatactl; // _VENDOR_CEATA_CNTRL_0, 10Ch |
| uint32_t venbootctl; // _VENDOR_BOOT_CNTRL_0, 110h |
| uint32_t venbootacktout; // _VENDOR_BOOT_ACK_TIMEOUT, 114h |
| uint32_t venbootdattout; // _VENDOR_BOOT_DAT_TIMEOUT, 118h |
| uint32_t vendebouncecnt; // _VENDOR_DEBOUNCE_COUNT_0, 11Ch |
| uint32_t venmiscctl; // _VENDOR_MISC_CNTRL_0, 120h |
| uint32_t res6[47]; // 0x124 ~ 0x1DC |
| uint32_t sdmemcmppadctl; // _SDMEMCOMPPADCTRL_0, 1E0h |
| uint32_t autocalcfg; // _AUTO_CAL_CONFIG_0, 1E4h |
| uint32_t autocalintval; // _AUTO_CAL_INTERVAL_0, 1E8h |
| uint32_t autocalsts; // _AUTO_CAL_STATUS_0, 1ECh |
| } TegraMmcReg; |
| |
| enum { |
| TEGRA_MMC_PWRCTL_SD_BUS_POWER = (1 << 0), |
| TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8 = (5 << 1), |
| TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_0 = (6 << 1), |
| TEGRA_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3 = (7 << 1), |
| |
| TEGRA_MMC_HOSTCTL_DMASEL_MASK = (3 << 3), |
| TEGRA_MMC_HOSTCTL_DMASEL_SDMA = (0 << 3), |
| TEGRA_MMC_HOSTCTL_DMASEL_ADMA2_32BIT = (2 << 3), |
| TEGRA_MMC_HOSTCTL_DMASEL_ADMA2_64BIT = (3 << 3), |
| |
| TEGRA_MMC_TRNMOD_DMA_ENABLE = (1 << 0), |
| TEGRA_MMC_TRNMOD_BLOCK_COUNT_ENABLE = (1 << 1), |
| TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_WRITE = (0 << 4), |
| TEGRA_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ = (1 << 4), |
| TEGRA_MMC_TRNMOD_MULTI_BLOCK_SELECT = (1 << 5), |
| |
| TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_MASK = (3 << 0), |
| TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_NO_RESPONSE = (0 << 0), |
| TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136 = (1 << 0), |
| TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48 = (2 << 0), |
| TEGRA_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY = (3 << 0), |
| |
| TEGRA_MMC_TRNMOD_CMD_CRC_CHECK = (1 << 3), |
| TEGRA_MMC_TRNMOD_CMD_INDEX_CHECK = (1 << 4), |
| TEGRA_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_TRANSFER = (1 << 5), |
| |
| TEGRA_MMC_PRNSTS_CMD_INHIBIT_CMD = (1 << 0), |
| TEGRA_MMC_PRNSTS_CMD_INHIBIT_DAT = (1 << 1), |
| |
| TEGRA_MMC_CLKCON_INTERNAL_CLOCK_ENABLE = (1 << 0), |
| TEGRA_MMC_CLKCON_INTERNAL_CLOCK_STABLE = (1 << 1), |
| TEGRA_MMC_CLKCON_SD_CLOCK_ENABLE = (1 << 2), |
| |
| TEGRA_MMC_CLKCON_SDCLK_FREQ_SEL_SHIFT = 8, |
| TEGRA_MMC_CLKCON_SDCLK_FREQ_SEL_MASK = (0xff << 8), |
| |
| TEGRA_MMC_SWRST_SW_RESET_FOR_ALL = (1 << 0), |
| TEGRA_MMC_SWRST_SW_RESET_FOR_CMD_LINE = (1 << 1), |
| TEGRA_MMC_SWRST_SW_RESET_FOR_DAT_LINE = (1 << 2), |
| |
| TEGRA_MMC_NORINTSTS_CMD_COMPLETE = (1 << 0), |
| TEGRA_MMC_NORINTSTS_XFER_COMPLETE = (1 << 1), |
| TEGRA_MMC_NORINTSTS_DMA_INTERRUPT = (1 << 3), |
| TEGRA_MMC_NORINTSTS_ERR_INTERRUPT = (1 << 15), |
| TEGRA_MMC_NORINTSTS_CMD_TIMEOUT = (1 << 16), |
| |
| TEGRA_MMC_NORINTSTSEN_CMD_COMPLETE = (1 << 0), |
| TEGRA_MMC_NORINTSTSEN_XFER_COMPLETE = (1 << 1), |
| TEGRA_MMC_NORINTSTSEN_DMA_INTERRUPT = (1 << 3), |
| TEGRA_MMC_NORINTSTSEN_BUFFER_WRITE_READY = (1 << 4), |
| TEGRA_MMC_NORINTSTSEN_BUFFER_READ_READY = (1 << 5), |
| |
| TEGRA_MMC_NORINTSIGEN_XFER_COMPLETE = (1 << 1), |
| |
| // SDMMC1/3 settings from section 24.6 of T30 TRM |
| MEMCOMP_PADCTRL_VREF = 7, |
| AUTO_CAL_ENABLED = (1 << 29), |
| AUTO_CAL_PD_OFFSET = (0x70 << 8), |
| AUTO_CAL_PU_OFFSET = (0x62 << 0), |
| }; |
| |
| typedef struct { |
| MmcCtrlr mmc; |
| |
| TegraMmcReg *reg; |
| uint32_t clock; // Current clock (MHz) |
| uint32_t src_hz; // Source clock (hz) |
| |
| GpioOps *cd_gpio; // Change Detect GPIO |
| GpioOps *power_gpio; // Enable Power GPIO |
| |
| int initialized; |
| int removable; |
| } TegraMmcHost; |
| |
| TegraMmcHost *new_tegra_mmc_host(uintptr_t ioaddr, int bus_width, |
| int removable, GpioOps *card_detect, |
| GpioOps *enable_power); |
| |
| #endif // __DRIVERS_BLOCKDEV_TEGRA_MMC_H_ |