blob: aeb5ad28ac12160dedf83ca5d6526b71dc41cbb2 [file] [log] [blame]
/*
* (C) Copyright 2009 SAMSUNG Electronics
* Minkyu Kang <mk7.kang@samsung.com>
* Portions Copyright (C) 2011-2012 NVIDIA Corporation
* Portions Copyright (C) 2016 Marvell Corporation
*
* 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.
*/
#ifndef __DRIVERS_STORAGE_MVMAP2315_MMC_H_
#define __DRIVERS_STORAGE_MVMAP2315_MMC_H_
#include <arch/io.h>
#include <stddef.h>
#include "drivers/gpio/gpio.h"
#include "drivers/storage/blockdev.h"
#include "drivers/storage/mmc.h"
#define MVMAP2315_PAD_CTRL_0 0x0730F000
#define MVMAP2315_PAD_CTRL_1 0x01FF0000
#define MVMAP2315_PAD_CTRL_2 0x00000F0F
#define MVMAP2315_SWRST_CMD 0x02000000
#define MVMAP2315_SWRST_DAT 0x04000000
#define MVMAP2315_PHY_EN 0x80000000
#define MVMAP2315_MMC_VOLTAGES (MMC_VDD_32_33 | MMC_VDD_33_34)
#define BIT(x) (1 << (x))
/* MVMAP2315 PHY reset settings */
#define MVMAP2315_CMD_ASYNC_MODE (BIT(5))
#define MVMAP2315_DQ_ASYNC_MODE (BIT(4))
#define MVMAP2315_FC_WRST_SEL (0 | BIT(0))
#define MVMAP2315_RESET_SETTING (MVMAP2315_CMD_ASYNC_MODE | \
MVMAP2315_DQ_ASYNC_MODE | \
MVMAP2315_FC_WRST_SEL)
#define MVMAP2315_QSP_AFTER_RDRST (0 | 0 | 0 | BIT(24))
#define MVMAP2315_WAIT_CYCLE_BEFORE (0 | BIT(14) | 0 | BIT(12))
#define MVMAP2315_FC_SYNC_EN_DUR (0 | BIT(10) | 0 | BIT(8))
#define MVMAP2315_FC_SYNC_RST_EN_DUR (0 | 0 | BIT(5) | 0)
#define MVMAP2315_FC_SYNC_RST_DUR (0 | 0 | BIT(1) | 0)
#define MVMAP2315_RESET_SETTINGS (MVMAP2315_QSP_AFTER_RDRST | \
MVMAP2315_WAIT_CYCLE_BEFORE | \
MVMAP2315_FC_SYNC_EN_DUR | \
MVMAP2315_FC_SYNC_RST_EN_DUR | \
MVMAP2315_FC_SYNC_RST_DUR)
#define MVMAP2315_PHY_INIT_BIT (BIT(31))
#define MVMAP2315_AUTO_REC_EN_BIT (BIT(30))
#define MVMAP2315_PHY_SLOW_MODE (BIT(29))
#define MVMAP2315_OUTJPUT_QSN_EN_BIT (BIT(28))
/* MSB of the mmc.voltages. Current value is made by MMC_VDD_33_34. */
#define MVMAP2315_MMC_VOLTAGES_MSB 22
typedef struct mvmap2315mmcreg {
u16 SD_SYS_ADDR_LOW0;
u16 SD_SYS_ADDR_HIGH0;
u16 SD_BLOCK_SIZE0;
u16 SD_BLOCK_COUNT0;
u16 SD_ARG_LOW0;
u16 SD_ARG_HIGH0;
u16 SD_TRANSFER_MODE0;
u16 SD_CMD0;
u16 SD_RESP_00;
u16 SD_RESP_10;
u16 SD_RESP_20;
u16 SD_RESP_30;
u16 SD_RESP_40;
u16 SD_RESP_50;
u16 SD_RESP_60;
u16 SD_RESP_70;
u16 SD_BUFFER_DATA_PORT_00;
u16 SD_BUFFER_DATA_PORT_10;
u16 SD_PRESENT_STATE_00;
u16 SD_PRESENT_STATE_10;
u16 SD_HOST_CTRL0;
u16 SD_BLOCK_GAP_CTRL0;
u16 SD_CLOCK_CTRL0;
u16 SD_TIMEOUT_CTRL_SW_RESET0;
u16 SD_NORMAL_INT_STATUS0;
u16 SD_ERROR_INT_STATUS0;
u16 SD_NORMAL_INT_STATUS_EN0;
u16 SD_ERROR_INT_STATUS_EN0;
u16 SD_NORMAL_INT_STATUS_SIG_EN0;
u16 SD_ERROR_INT_STATUS_SIG_EN0;
u16 SD_AUTO_CMD12_ERROR_STATUS0;
u16 SD_HOST_CTRL20;
u16 SD_CAPABILITIES_00;
u16 SD_CAPABILITIES_10;
u16 SD_CAPABILITIES_20;
u16 SD_CAPABILITIES_30;
u16 SD_MAX_CURRENT_00;
u16 SD_MAX_CURRENT_10;
u16 SD_MAX_CURRENT_20;
u16 SD_MAX_CURRENT_30;
u16 SD_FORCE_EVENT_AUTO_CMD12_ERROR0;
u16 SD_FORCE_EVENT_FOR_ERROR_STATUS0;
u16 SD_ADMA_ERROR_STATUS0;
u16 reserved0;
u16 SD_ADMA_SYS_ADDR_00;
u16 SD_ADMA_SYS_ADDR_10;
u16 SD_ADMA_SYS_ADDR_20;
u16 SD_ADMA_SYS_ADDR_30;
u16 SD_PRESET_VALUE_FOR_INIT0;
u16 SD_PRESET_VALUE_FOR_DS0;
u16 SD_PRESET_VALUE_FOR_HS0;
u16 SD_PRESET_VALUE_FOR_SDR120;
u16 SD_PRESET_VALUE_FOR_SDR250;
u16 SD_PRESET_VALUE_FOR_SDR500;
u16 SD_PRESET_VALUE_FOR_SDR1040;
u16 SD_PRESET_VALUE_FOR_DDR500;
u16 reserved1[56];
u16 SD_SHARED_BUS_CTRL_LOW0;
u16 SD_SHARED_BUS_CTRL_HIGH0;
u16 reserved2[12];
u16 SD_SLOT_INT_STATUS0;
u16 SD_HOST_CTRL_VER0;
u16 SDHC_IPID_00;
u16 SDHC_IPID_10;
u16 SDHC_SYS_CFG_INFO_00;
u16 SDHC_SYS_CFG_INFO_10;
u16 SDHC_SYS_OP_CTRL_00;
u16 SDHC_SYS_OP_CTRL_10;
u16 SDHC_SYS_EXT_OP_CTRL_00;
u16 SDHC_SYS_EXT_OP_CTRL_10;
u16 SDHC_TEST_OUT_00;
u16 SDHC_TEST_OUT_10;
u16 SDHC_TESTOUT_MUXSEL;
u16 reserved3[5];
u16 SDHC_SLOT_EXT_INT_STATUS;
u16 SDHC_SLOT_EXT_ERR_STATUS;
u16 SDHC_SLOT_EXT_INT_STATUS_EN;
u16 SDHC_SLOT_EXT_ERR_STATUS_EN;
u16 SDHC_SLOT_OP_STATUS_CTRL_00;
u16 SDHC_SLOT_OP_STATUS_CTRL_10;
u16 SDHC_SLOT_FIFO_CTRL_00;
u16 SDHC_SLOT_FIFO_CTRL_10;
u16 SDHC_SLOT_eMMC_CTRL;
u16 reserved4[9];
u16 SDHC_SLOT_RETUNING_REQ_CTRL;
u16 reserved5[3];
u16 SDHC_SLOT_EXT_PRESENT_STATE_00;
u16 SDHC_SLOT_EXT_PRESENT_STATE_10;
u16 SDHC_SLOT_DLL_CUR_DLY_VAL_00;
u16 SDHC_SLOT_DLL_CUR_DLY_VAL_10;
u16 SDHC_SLOT_TUNING_CUR_DLY_VAL_00;
u16 SDHC_SLOT_TUNING_CUR_DLY_VAL_10;
u16 SDHC_SLOT_STROBE_CUR_DLY_VAL_00;
u16 SDHC_SLOT_STROBE_CUR_DLY_VAL_10;
u16 SDHC_SLOT_SUB_CMD_CTRL_00;
u16 SDHC_SLOT_SUB_CMD_CTRL_10;
u16 SDHC_SLOT_CQ_TASK_INFO;
u16 reserved6[7];
u16 EMMC_PHY_TIMING_ADJUST_00;
u16 EMMC_PHY_TIMING_ADJUST_10;
u16 EMMC_PHY_FUNC_CONTROL_00;
u16 EMMC_PHY_FUNC_CONTROL_10;
u16 EMMC_PHY_PAD_CONTROL_00;
u16 EMMC_PHY_PAD_CONTROL_10;
u16 EMMC_PHY_PAD_CONTROL1_00;
u16 EMMC_PHY_PAD_CONTROL1_10;
u16 EMMC_PHY_PAD_CONTROL2_00;
u16 EMMC_PHY_PAD_CONTROL2_10;
u16 EMMC_PHY_DLL_CONTROL_00;
u16 EMMC_PHY_DLL_CONTROL_10;
u16 EMMC_LOGIC_TIMING_ADJUST_00;
u16 EMMC_LOGIC_TIMING_ADJUST_10;
u16 EMMC_LOGIC_TIMING_ADJUST_LOW_00;
u16 EMMC_LOGIC_TIMING_ADJUST_LOW_10;
u16 PHY_LB_FUNC_CONFIG_00;
u16 PHY_LB_FUNC_CONFIG_10;
u16 PHY_LB_DATA_PATTERN_00;
u16 PHY_LB_DATA_PATTERN_10;
u16 PHY_LB_FUNC_CONTROL_00;
u16 PHY_LB_FUNC_CONTROL_10;
u16 PHY_LB_ERR_STATUS_00;
u16 PHY_LB_ERR_STATUS_10;
u16 PHY_LB_COMP_CNT;
u16 reserved7[23];
u16 FLC_RUN_CONFIG;
u16 reserved8[7];
u16 TP_CONTROL_00;
u16 TP_CONTROL_10;
u16 TP_MONITOR;
u16 reserved9[5];
u16 SDHC_SLOT_TUNING_DEBUG_INFO_00;
u16 SDHC_SLOT_TUNING_DEBUG_INFO_10;
u16 SDHC_SLOT_DATAIN_DEBUG_INFO_00;
u16 SDHC_SLOT_DATAIN_DEBUG_INFO_10;
u16 SDHC_SLOT_CQE_DEBUG_INFO_00;
u16 SDHC_SLOT_CQE_DEBUG_INFO_10;
u16 SDHC_SLOT_CQE_DEBUG_INFO_CTRL_00;
u16 SDHC_SLOT_CQE_DEBUG_INFO_CTRL_10;
u16 CQ_VER_00;
u16 CQ_VER_10;
u16 CQ_CAP_00;
u16 CQ_CAP_10;
u16 CQ_CONFIG_00;
u16 CQ_CONFIG_10;
u16 CQ_CONTROL_00;
u16 CQ_CONTROL_10;
u16 CQ_INT_STATUS_00;
u16 CQ_INT_STATUS_10;
u16 CQ_INT_STATUS_EN_00;
u16 CQ_INT_STATUS_EN_10;
u16 CQ_INT_SIGNAL_EN_00;
u16 CQ_INT_SIGNAL_EN_10;
u16 CQ_INT_COALESCING_00;
u16 CQ_INT_COALESCING_10;
u16 CQ_TDL_BASE_00;
u16 CQ_TDL_BASE_10;
u16 CQ_TDL_BASE_UP_00;
u16 CQ_TDL_BASE_UP_10;
u16 CQ_DOORBELL_00;
u16 CQ_DOORBELL_10;
u16 CQ_TCN_00;
u16 CQ_TCN_10;
u16 CQ_QUEUE_STATUS_00;
u16 CQ_QUEUE_STATUS_10;
u16 CQ_PENDING_TASKS_00;
u16 CQ_PENDING_TASKS_10;
u16 CQ_TASK_CLEAR_00;
u16 CQ_TASK_CLEAR_10;
u16 CQ_SQS_CONF1_00;
u16 CQ_SQS_CONF1_10;
u16 CQ_SQS_CONF2_00;
u16 CQ_SQS_CONF2_10;
u16 CQ_DCMD_RESP_00;
u16 CQ_DCMD_RESP_10;
u16 CQ_RESP_ERR_MASK_00;
u16 CQ_RESP_ERR_MASK_10;
u16 CQ_TASK_ERR_INFO_00;
u16 CQ_TASK_ERR_INFO_10;
u16 CQ_CMD_RESP_INDEX_00;
u16 CQ_CMD_RESP_INDEX_10;
u16 CQ_CMD_RESP_ARG;
} Mvmap2315MmcReg;
check_member(mvmap2315mmcreg, EMMC_PHY_TIMING_ADJUST_00, 0x170);
enum {
MVMAP2315_MMC_PWRCTL_SD_BUS_POWER = (1 << 8),
MVMAP2315_MMC_PWRCTL_SD_BUS_VOLTAGE_V1_8 = (5 << 9),
MVMAP2315_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_0 = (6 << 9),
MVMAP2315_MMC_PWRCTL_SD_BUS_VOLTAGE_V3_3 = (7 << 9),
MVMAP2315_MMC_HOSTCTL_DMASEL_MASK = (3 << 3),
MVMAP2315_MMC_HOSTCTL_DMASEL_SDMA = (0 << 3),
MVMAP2315_MMC_HOSTCTL_DMASEL_ADMA2_32BIT = (2 << 3),
MVMAP2315_MMC_HOSTCTL_DMASEL_ADMA2_64BIT = (3 << 3),
MVMAP2315_MMC_TRNMOD_DMA_ENABLE = (1 << 0),
MVMAP2315_MMC_TRNMOD_BLOCK_COUNT_ENABLE = (1 << 1),
MVMAP2315_MMC_TRNMOD_DATA_XFER_DIR_SEL_WRITE = (0 << 4),
MVMAP2315_MMC_TRNMOD_DATA_XFER_DIR_SEL_READ = (1 << 4),
MVMAP2315_MMC_TRNMOD_MULTI_BLOCK_SELECT = (1 << 5),
MVMAP2315_MMC_CMDREG_RESP_TYPE_SELECT_MASK = (3 << 0),
MVMAP2315_MMC_CMDREG_RESP_TYPE_SELECT_NO_RESPONSE = (0 << 0),
MVMAP2315_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_136 = (1 << 0),
MVMAP2315_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48 = (2 << 0),
MVMAP2315_MMC_CMDREG_RESP_TYPE_SELECT_LENGTH_48_BUSY = (3 << 0),
MVMAP2315_MMC_TRNMOD_CMD_CRC_CHECK = (1 << 3),
MVMAP2315_MMC_TRNMOD_CMD_INDEX_CHECK = (1 << 4),
MVMAP2315_MMC_TRNMOD_DATA_PRESENT_SELECT_DATA_XFER = (1 << 5),
MVMAP2315_MMC_PRNSTS_CMD_INHIBIT_CMD = (1 << 0),
MVMAP2315_MMC_PRNSTS_CMD_INHIBIT_DAT = (1 << 1),
MVMAP2315_MMC_CLKCON_INTERNAL_CLOCK_ENABLE = (1 << 0),
MVMAP2315_MMC_CLKCON_INTERNAL_CLOCK_STABLE = (1 << 1),
MVMAP2315_MMC_CLKCON_SD_CLOCK_ENABLE = (1 << 2),
MVMAP2315_MMC_CLKCON_SDCLK_FREQ_SEL_SHIFT = 8,
MVMAP2315_MMC_CLKCON_SDCLK_FREQ_SEL_MASK = (0xff << 8),
MVMAP2315_MMC_SWRST_SW_RESET_FOR_ALL = (1 << 8),
MVMAP2315_MMC_SWRST_SW_RESET_FOR_CMD_LINE = (1 << 9),
MVMAP2315_MMC_SWRST_SW_RESET_FOR_DAT_LINE = (1 << 10),
MVMAP2315_MMC_NORINTSTS_CMD_COMPLETE = (1 << 0),
MVMAP2315_MMC_NORINTSTS_XFER_COMPLETE = (1 << 1),
MVMAP2315_MMC_NORINTSTS_DMA_INTERRUPT = (1 << 3),
MVMAP2315_MMC_NORINTSTS_ERR_INTERRUPT = (1 << 15),
MVMAP2315_MMC_NORINTSTS_CMD_TIMEOUT = (1 << 16),
MVMAP2315_MMC_NORINTSTSEN_CMD_COMPLETE = (1 << 0),
MVMAP2315_MMC_NORINTSTSEN_XFER_COMPLETE = (1 << 1),
MVMAP2315_MMC_NORINTSTSEN_DMA_INTERRUPT = (1 << 3),
MVMAP2315_MMC_NORINTSTSEN_BUFFER_WRITE_READY = (1 << 4),
MVMAP2315_MMC_NORINTSTSEN_BUFFER_READ_READY = (1 << 5),
MVMAP2315_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 mvmap2315MmcHost {
MmcCtrlr mmc;
Mvmap2315MmcReg *reg;
u32 clock;
u32 src_hz;
int initialized;
int removable;
} Mvmap2315MmcHost;
Mvmap2315MmcHost *new_mvmap2315_mmc_host(uintptr_t ioaddr,
int bus_width,
u32 min_freq_hz,
u32 max_freq_hz,
u32 src_freq_hz);
#endif /* __DRIVERS_STORAGE_MVMAP2315_MMC_H_ */