mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-17 22:49:02 +00:00
mmc: Add MMC controller driver for OcteonTX / TX2
Adds support for MMC controllers found on OcteonTX or OcteonTX2 SoC platforms. Signed-off-by: Aaron Williams <awilliams@marvell.com> Signed-off-by: Suneel Garapati <sgarapati@marvell.com> Cc: Peng Fan <peng.fan@nxp.com>
This commit is contained in:
parent
638d705a54
commit
708598997d
4 changed files with 4114 additions and 0 deletions
|
@ -305,6 +305,15 @@ config MMC_PCI
|
|||
This selects PCI-based MMC controllers.
|
||||
If you have an MMC controller on a PCI bus, say Y here.
|
||||
|
||||
config MMC_OCTEONTX
|
||||
bool "Marvell OcteonTX Multimedia Card Interface support"
|
||||
depends on (ARCH_OCTEONTX || ARCH_OCTEONTX2)
|
||||
depends on DM_MMC
|
||||
help
|
||||
This selects the OcteonTX Multimedia card Interface.
|
||||
If you have an OcteonTX/TX2 board with a Multimedia Card slot,
|
||||
say Y here.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PXA_MMC_GENERIC
|
||||
|
|
|
@ -36,6 +36,7 @@ obj-$(CONFIG_MVEBU_MMC) += mvebu_mmc.o
|
|||
obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o
|
||||
obj-$(CONFIG_MMC_MXC) += mxcmmc.o
|
||||
obj-$(CONFIG_MMC_MXS) += mxsmmc.o
|
||||
obj-$(CONFIG_MMC_OCTEONTX) += octeontx_hsmmc.o
|
||||
obj-$(CONFIG_MMC_PCI) += pci_mmc.o
|
||||
obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)SUPPORT_EMMC_RPMB) += rpmb.o
|
||||
|
|
3897
drivers/mmc/octeontx_hsmmc.c
Normal file
3897
drivers/mmc/octeontx_hsmmc.c
Normal file
File diff suppressed because it is too large
Load diff
207
drivers/mmc/octeontx_hsmmc.h
Normal file
207
drivers/mmc/octeontx_hsmmc.h
Normal file
|
@ -0,0 +1,207 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Copyright (C) 2019 Marvell International Ltd.
|
||||
*
|
||||
* https://spdx.org/licenses
|
||||
*/
|
||||
#ifndef __OCTEONTX_HSMMC_H__
|
||||
#define __OCTEONTX_HSMMC_H__
|
||||
#include <asm/gpio.h>
|
||||
|
||||
/** Name of our driver */
|
||||
#define OCTEONTX_MMC_DRIVER_NAME "octeontx-hsmmc"
|
||||
|
||||
/** Maximum supported MMC slots */
|
||||
#define OCTEONTX_MAX_MMC_SLOT 3
|
||||
|
||||
#define POWER_ON_TIME 40 /** See SD 4.1 spec figure 6-5 */
|
||||
|
||||
/**
|
||||
* Timeout used when waiting for commands to complete. We need to keep this
|
||||
* above the hardware watchdog timeout which is usually limited to 1000ms
|
||||
*/
|
||||
#define WATCHDOG_COUNT (1100) /* in msecs */
|
||||
|
||||
/**
|
||||
* Long timeout for commands which might take a while to complete.
|
||||
*/
|
||||
#define MMC_TIMEOUT_LONG 1000
|
||||
|
||||
/**
|
||||
* Short timeout used for most commands in msecs
|
||||
*/
|
||||
#define MMC_TIMEOUT_SHORT 20
|
||||
|
||||
#define NSEC_PER_SEC 1000000000L
|
||||
|
||||
#define MAX_NO_OF_TAPS 64
|
||||
|
||||
#define EXT_CSD_POWER_CLASS 187 /* R/W */
|
||||
|
||||
/* default HS400 tuning block number */
|
||||
#define DEFAULT_HS400_TUNING_BLOCK 1
|
||||
|
||||
struct octeontx_mmc_host;
|
||||
|
||||
/** MMC/SD slot data structure */
|
||||
struct octeontx_mmc_slot {
|
||||
struct mmc mmc;
|
||||
struct mmc_config cfg;
|
||||
struct octeontx_mmc_host *host;
|
||||
struct udevice *dev;
|
||||
void *base_addr; /** Same as host base_addr */
|
||||
u64 clock;
|
||||
int bus_id; /** slot number */
|
||||
uint bus_width;
|
||||
uint max_width;
|
||||
int hs200_tap_adj;
|
||||
int hs400_tap_adj;
|
||||
int hs400_tuning_block;
|
||||
struct gpio_desc cd_gpio;
|
||||
struct gpio_desc wp_gpio;
|
||||
struct gpio_desc power_gpio;
|
||||
enum bus_mode mode;
|
||||
union mio_emm_switch cached_switch;
|
||||
union mio_emm_switch want_switch;
|
||||
union mio_emm_rca cached_rca;
|
||||
union mio_emm_timing taps; /* otx2: MIO_EMM_TIMING */
|
||||
union mio_emm_timing hs200_taps;
|
||||
union mio_emm_timing hs400_taps;
|
||||
/* These are used to see if our tuning is still valid or not */
|
||||
enum bus_mode last_mode;
|
||||
u32 last_clock;
|
||||
u32 block_len;
|
||||
u32 block_count;
|
||||
int cmd_clk_skew;
|
||||
int dat_clk_skew;
|
||||
uint cmd_cnt; /* otx: sample cmd in delay */
|
||||
uint dat_cnt; /* otx: sample data in delay */
|
||||
uint drive; /* Current drive */
|
||||
uint slew; /* clock skew */
|
||||
uint cmd_out_hs200_delay;
|
||||
uint data_out_hs200_delay;
|
||||
uint cmd_out_hs400_delay;
|
||||
uint data_out_hs400_delay;
|
||||
uint clk_period;
|
||||
bool valid:1;
|
||||
bool is_acmd:1;
|
||||
bool tuned:1;
|
||||
bool hs200_tuned:1;
|
||||
bool hs400_tuned:1;
|
||||
bool is_1_8v:1;
|
||||
bool is_3_3v:1;
|
||||
bool is_ddr:1;
|
||||
bool is_asim:1;
|
||||
bool is_emul:1;
|
||||
bool cd_inverted:1;
|
||||
bool wp_inverted:1;
|
||||
bool disable_ddr:1;
|
||||
bool non_removable:1;
|
||||
};
|
||||
|
||||
struct octeontx_mmc_cr_mods {
|
||||
u8 ctype_xor;
|
||||
u8 rtype_xor;
|
||||
};
|
||||
|
||||
struct octeontx_mmc_cr {
|
||||
u8 c;
|
||||
u8 r;
|
||||
};
|
||||
|
||||
struct octeontx_sd_mods {
|
||||
struct octeontx_mmc_cr mmc;
|
||||
struct octeontx_mmc_cr sd;
|
||||
struct octeontx_mmc_cr sdacmd;
|
||||
};
|
||||
|
||||
/** Host controller data structure */
|
||||
struct octeontx_mmc_host {
|
||||
struct udevice *dev;
|
||||
void *base_addr;
|
||||
struct octeontx_mmc_slot slots[OCTEONTX_MAX_MMC_SLOT + 1];
|
||||
pci_dev_t pdev;
|
||||
u64 sys_freq;
|
||||
union mio_emm_cfg emm_cfg;
|
||||
u64 timing_taps;
|
||||
struct mmc *last_mmc; /** Last mmc used */
|
||||
ofnode node;
|
||||
int cur_slotid;
|
||||
int last_slotid;
|
||||
int max_width;
|
||||
uint per_tap_delay;
|
||||
uint num_slots;
|
||||
uint dma_wait_delay; /* Delay before polling DMA in usecs */
|
||||
bool initialized:1;
|
||||
bool timing_calibrated:1;
|
||||
bool is_asim:1;
|
||||
bool is_emul:1;
|
||||
bool calibrate_glitch:1;
|
||||
bool cond_clock_glitch:1;
|
||||
bool tap_requires_noclk:1;
|
||||
bool hs400_skew_needed:1;
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: This was copied from the Linux kernel.
|
||||
*
|
||||
* MMC status in R1, for native mode (SPI bits are different)
|
||||
* Type
|
||||
* e:error bit
|
||||
* s:status bit
|
||||
* r:detected and set for the actual command response
|
||||
* x:detected and set during command execution. the host must poll
|
||||
* the card by sending status command in order to read these bits.
|
||||
* Clear condition
|
||||
* a:according to the card state
|
||||
* b:always related to the previous command. Reception of
|
||||
* a valid command will clear it (with a delay of one command)
|
||||
* c:clear by read
|
||||
*/
|
||||
#define R1_OUT_OF_RANGE BIT(31) /* er, c */
|
||||
#define R1_ADDRESS_ERROR BIT(30) /* erx, c */
|
||||
#define R1_BLOCK_LEN_ERROR BIT(29) /* er, c */
|
||||
#define R1_ERASE_SEQ_ERROR BIT(28) /* er, c */
|
||||
#define R1_ERASE_PARAM BIT(27) /* ex, c */
|
||||
#define R1_WP_VIOLATION BIT(26) /* erx, c */
|
||||
#define R1_CARD_IS_LOCKED BIT(25) /* sx, a */
|
||||
#define R1_LOCK_UNLOCK_FAILED BIT(24) /* erx, c */
|
||||
#define R1_COM_CRC_ERROR BIT(23) /* er, b */
|
||||
/*#define R1_ILLEGAL_COMMAND BIT(22)*/ /* er, b */
|
||||
#define R1_CARD_ECC_FAILED BIT(21) /* ex, c */
|
||||
#define R1_CC_ERROR BIT(20) /* erx, c */
|
||||
#define R1_ERROR BIT(19) /* erx, c */
|
||||
#define R1_UNDERRUN BIT(18) /* ex, c */
|
||||
#define R1_OVERRUN BIT(17) /* ex, c */
|
||||
#define R1_CID_CSD_OVERWRITE BIT(16) /* erx, c, CID/CSD overwrite */
|
||||
#define R1_WP_ERASE_SKIP BIT(15) /* sx, c */
|
||||
#define R1_CARD_ECC_DISABLED BIT(14) /* sx, a */
|
||||
#define R1_ERASE_RESET BIT(13) /* sr, c */
|
||||
#define R1_STATUS(x) ((x) & 0xFFFFE000)
|
||||
#define R1_CURRENT_STATE(x) (((x) & 0x00001E00) >> 9) /* sx, b (4 bits) */
|
||||
#define R1_READY_FOR_DATA BIT(8) /* sx, a */
|
||||
#define R1_SWITCH_ERROR BIT(7) /* sx, c */
|
||||
|
||||
#define R1_BLOCK_READ_MASK R1_OUT_OF_RANGE | \
|
||||
R1_ADDRESS_ERROR | \
|
||||
R1_BLOCK_LEN_ERROR | \
|
||||
R1_CARD_IS_LOCKED | \
|
||||
R1_COM_CRC_ERROR | \
|
||||
R1_ILLEGAL_COMMAND | \
|
||||
R1_CARD_ECC_FAILED | \
|
||||
R1_CC_ERROR | \
|
||||
R1_ERROR
|
||||
#define R1_BLOCK_WRITE_MASK R1_OUT_OF_RANGE | \
|
||||
R1_ADDRESS_ERROR | \
|
||||
R1_BLOCK_LEN_ERROR | \
|
||||
R1_WP_VIOLATION | \
|
||||
R1_CARD_IS_LOCKED | \
|
||||
R1_COM_CRC_ERROR | \
|
||||
R1_ILLEGAL_COMMAND | \
|
||||
R1_CARD_ECC_FAILED | \
|
||||
R1_CC_ERROR | \
|
||||
R1_ERROR | \
|
||||
R1_UNDERRUN | \
|
||||
R1_OVERRUN
|
||||
|
||||
#endif /* __OCTEONTX_HSMMC_H__ */
|
Loading…
Add table
Reference in a new issue