aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/cavium.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/cavium.h')
-rw-r--r--drivers/mmc/host/cavium.h137
1 files changed, 131 insertions, 6 deletions
diff --git a/drivers/mmc/host/cavium.h b/drivers/mmc/host/cavium.h
index f3eea5eaa678..f38353171678 100644
--- a/drivers/mmc/host/cavium.h
+++ b/drivers/mmc/host/cavium.h
@@ -19,8 +19,42 @@
#include <linux/of.h>
#include <linux/scatterlist.h>
#include <linux/semaphore.h>
+#include <linux/pci.h>
#define CAVIUM_MAX_MMC 4
+#define BLKSZ_EXT_CSD 512
+#define MRVL_OCTEONTX2_96XX_PARTNUM 0xB2
+
+/* Subsystem Device ID */
+#define PCI_SUBSYS_DEVID_8XXX 0xA
+#define PCI_SUBSYS_DEVID_9XXX 0xB
+#define PCI_SUBSYS_DEVID_95XX 0xB3
+
+#define KHZ_400 (400000)
+#define MHZ_26 (26000000)
+#define MHZ_52 (52000000)
+#define MHZ_100 (100000000)
+#define MHZ_200 (200000000)
+
+/* octtx2: emmc interface io current drive strength */
+#define MILLI_AMP_2 (0x0)
+#define MILLI_AMP_4 (0x1)
+#define MILLI_AMP_8 (0x2)
+#define MILLI_AMP_16 (0x3)
+
+/* octtx2: emmc interface io clk skew */
+#define LOW_SLEW_RATE (0x0)
+#define HIGH_SLEW_RATE (0x1)
+
+/* octtx2: emmc interface calibration */
+#define START_CALIBRATION (0x1)
+#define TOTAL_NO_OF_TAPS (512)
+#define PS_10000 (10 * 1000)
+#define PS_5000 (5000)
+#define PS_2500 (2500)
+#define PS_400 (400)
+#define MAX_NO_OF_TAPS 64
+
/* DMA register addresses */
#define MIO_EMM_DMA_FIFO_CFG(x) (0x00 + x->reg_off_dma)
@@ -33,8 +67,17 @@
#define MIO_EMM_DMA_INT_ENA_W1S(x) (0x40 + x->reg_off_dma)
#define MIO_EMM_DMA_INT_ENA_W1C(x) (0x48 + x->reg_off_dma)
+/* octtx2 specific registers */
+#define MIO_EMM_CALB(x) (0xC0 + x->reg_off)
+#define MIO_EMM_TAP(x) (0xC8 + x->reg_off)
+#define MIO_EMM_TIMING(x) (0xD0 + x->reg_off)
+#define MIO_EMM_DEBUG(x) (0xF8 + x->reg_off)
+
/* register addresses */
#define MIO_EMM_CFG(x) (0x00 + x->reg_off)
+#define MIO_EMM_MODE(x, s) (0x08 + 8*(s) + (x)->reg_off)
+/* octtx2 specific register */
+#define MIO_EMM_IO_CTL(x) (0x40 + x->reg_off)
#define MIO_EMM_SWITCH(x) (0x48 + x->reg_off)
#define MIO_EMM_DMA(x) (0x50 + x->reg_off)
#define MIO_EMM_CMD(x) (0x58 + x->reg_off)
@@ -56,6 +99,7 @@ struct cvm_mmc_host {
struct device *dev;
void __iomem *base;
void __iomem *dma_base;
+ struct pci_dev *pdev;
int reg_off;
int reg_off_dma;
u64 emm_cfg;
@@ -64,12 +108,10 @@ struct cvm_mmc_host {
struct clk *clk;
int sys_freq;
- struct mmc_request *current_req;
- struct sg_mapping_iter smi;
- bool dma_active;
bool use_sg;
-
bool has_ciu3;
+ bool powered;
+ bool use_vqmmc; /* must disable slots over switch */
bool big_dma_addr;
bool need_irq_handler_lock;
spinlock_t irq_handler_lock;
@@ -80,6 +122,9 @@ struct cvm_mmc_host {
struct cvm_mmc_slot *slot[CAVIUM_MAX_MMC];
struct platform_device *slot_pdev[CAVIUM_MAX_MMC];
+ /* octtx2 specific */
+ unsigned int per_tap_delay; /* per tap delay in pico second */
+ unsigned long delay_logged; /* per-ios.timing bitmask */
void (*set_shared_power)(struct cvm_mmc_host *, int);
void (*acquire_bus)(struct cvm_mmc_host *);
@@ -94,16 +139,27 @@ struct cvm_mmc_host {
struct cvm_mmc_slot {
struct mmc_host *mmc; /* slot-level mmc_core object */
struct cvm_mmc_host *host; /* common hw for all slots */
+ struct mmc_request *current_req;
u64 clock;
+ u32 ecount, gcount;
u64 cached_switch;
u64 cached_rca;
- unsigned int cmd_cnt; /* sample delay */
- unsigned int dat_cnt; /* sample delay */
+ struct sg_mapping_iter smi;
+ bool dma_active;
+
+ u64 taps; /* otx2: MIO_EMM_TIMING */
+ unsigned int cmd_cnt; /* otx: sample cmd in delay */
+ unsigned int data_cnt; /* otx: sample data in delay */
+
+ int drive; /* Current drive */
+ int slew; /* clock skew */
int bus_id;
+ bool cmd6_pending;
+ u64 want_switch;
};
struct cvm_mmc_cr_type {
@@ -161,6 +217,21 @@ struct cvm_mmc_cr_mods {
#define MIO_EMM_DMA_CFG_SIZE GENMASK_ULL(55, 36)
#define MIO_EMM_DMA_CFG_ADR GENMASK_ULL(35, 0)
+#define MIO_EMM_CFG_BUS_ENA GENMASK_ULL(3, 0)
+
+#define MIO_EMM_IO_CTL_DRIVE GENMASK_ULL(3, 2)
+#define MIO_EMM_IO_CTL_SLEW BIT_ULL(0)
+
+#define MIO_EMM_CALB_START BIT_ULL(0)
+#define MIO_EMM_TAP_DELAY GENMASK_ULL(7, 0)
+
+#define MIO_EMM_TIMING_CMD_IN GENMASK_ULL(53, 48)
+#define MIO_EMM_TIMING_CMD_OUT GENMASK_ULL(37, 32)
+#define MIO_EMM_TIMING_DATA_IN GENMASK_ULL(21, 16)
+#define MIO_EMM_TIMING_DATA_OUT GENMASK_ULL(5, 0)
+
+#define MIO_EMM_INT_NCB_RAS BIT_ULL(8)
+#define MIO_EMM_INT_NCB_FLT BIT_ULL(7)
#define MIO_EMM_INT_SWITCH_ERR BIT_ULL(6)
#define MIO_EMM_INT_SWITCH_DONE BIT_ULL(5)
#define MIO_EMM_INT_DMA_ERR BIT_ULL(4)
@@ -169,6 +240,9 @@ struct cvm_mmc_cr_mods {
#define MIO_EMM_INT_CMD_DONE BIT_ULL(1)
#define MIO_EMM_INT_BUF_DONE BIT_ULL(0)
+#define MIO_EMM_DMA_INT_FIFO BIT_ULL(1)
+#define MIO_EMM_DMA_INT_DMA BIT_ULL(0)
+
#define MIO_EMM_RSP_STS_BUS_ID GENMASK_ULL(61, 60)
#define MIO_EMM_RSP_STS_CMD_VAL BIT_ULL(59)
#define MIO_EMM_RSP_STS_SWITCH_VAL BIT_ULL(58)
@@ -200,9 +274,14 @@ struct cvm_mmc_cr_mods {
#define MIO_EMM_SWITCH_ERR0 BIT_ULL(58)
#define MIO_EMM_SWITCH_ERR1 BIT_ULL(57)
#define MIO_EMM_SWITCH_ERR2 BIT_ULL(56)
+#define MIO_EMM_SWITCH_ERRS GENMASK_ULL(58, 56)
+#define MIO_EMM_SWITCH_HS400_TIMING BIT_ULL(50)
+#define MIO_EMM_SWITCH_HS200_TIMING BIT_ULL(49)
#define MIO_EMM_SWITCH_HS_TIMING BIT_ULL(48)
+#define MIO_EMM_SWITCH_TIMING GENMASK_ULL(50, 48)
#define MIO_EMM_SWITCH_BUS_WIDTH GENMASK_ULL(42, 40)
#define MIO_EMM_SWITCH_POWER_CLASS GENMASK_ULL(35, 32)
+#define MIO_EMM_SWITCH_CLK GENMASK_ULL(31, 0)
#define MIO_EMM_SWITCH_CLK_HI GENMASK_ULL(31, 16)
#define MIO_EMM_SWITCH_CLK_LO GENMASK_ULL(15, 0)
@@ -210,6 +289,52 @@ struct cvm_mmc_cr_mods {
irqreturn_t cvm_mmc_interrupt(int irq, void *dev_id);
int cvm_mmc_of_slot_probe(struct device *dev, struct cvm_mmc_host *host);
int cvm_mmc_of_slot_remove(struct cvm_mmc_slot *slot);
+
extern const char *cvm_mmc_irq_names[];
+static inline bool is_mmc_8xxx(struct cvm_mmc_host *host)
+{
+#ifdef CONFIG_ARM64
+ struct pci_dev *pdev = host->pdev;
+ u32 chip_id = (pdev->subsystem_device >> 12) & 0xF;
+
+ return (chip_id == PCI_SUBSYS_DEVID_8XXX);
+#else
+ return false;
+#endif
+}
+
+static inline bool is_mmc_otx2(struct cvm_mmc_host *host)
+{
+#ifdef CONFIG_ARM64
+ struct pci_dev *pdev = host->pdev;
+ u32 chip_id = (pdev->subsystem_device >> 12) & 0xF;
+
+ return (chip_id == PCI_SUBSYS_DEVID_9XXX);
+#else
+ return false;
+#endif
+}
+
+static inline bool is_mmc_otx2_A0(struct cvm_mmc_host *host)
+{
+#ifdef CONFIG_ARM64
+ struct pci_dev *pdev = host->pdev;
+ u32 chip_id = (pdev->subsystem_device >> 8) & 0xFF;
+
+ return (pdev->revision == 0x00) &&
+ (chip_id == MRVL_OCTEONTX2_96XX_PARTNUM);
+#else
+ return false;
+#endif
+}
+
+static inline bool is_mmc_95xx(struct cvm_mmc_host *host)
+{
+ struct pci_dev *pdev = host->pdev;
+ u32 chip_id = (pdev->subsystem_device >> 8) & 0xFF;
+
+ return (chip_id == PCI_SUBSYS_DEVID_95XX);
+}
+
#endif