diff options
Diffstat (limited to 'drivers/mmc/host/cavium.h')
-rw-r--r-- | drivers/mmc/host/cavium.h | 158 |
1 files changed, 151 insertions, 7 deletions
diff --git a/drivers/mmc/host/cavium.h b/drivers/mmc/host/cavium.h index f3eea5eaa678..4725804d72bb 100644 --- a/drivers/mmc/host/cavium.h +++ b/drivers/mmc/host/cavium.h @@ -19,8 +19,59 @@ #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_98XX 0xB1 +#define PCI_SUBSYS_DEVID_96XX 0xB2 +#define PCI_SUBSYS_DEVID_95XX 0xB3 +#define PCI_SUBSYS_DEVID_LOKI 0xB4 +#define PCI_SUBSYS_DEVID_95XXMM 0xB5 + +/* Chip revision Id */ +#define REV_ID_0 0 +#define REV_ID_1 1 +#define REV_ID_2 2 + +#define KHZ_400 (400000) +#define MHZ_26 (26000000) +#define MHZ_52 (52000000) +#define MHZ_100 (100000000) +#define MHZ_112_5 (112500000) +#define MHZ_150 (150000000) +#define MHZ_167 (167000000) +#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_800 (800) +#define PS_400 (400) +#define MAX_NO_OF_TAPS 64 + +/* Macros to enable/disable clks */ +#define CLK_ON 0 +#define CLK_OFF 1 + /* DMA register addresses */ #define MIO_EMM_DMA_FIFO_CFG(x) (0x00 + x->reg_off_dma) @@ -33,8 +84,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 +116,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; @@ -63,23 +124,30 @@ struct cvm_mmc_host { int last_slot; struct clk *clk; int sys_freq; - - struct mmc_request *current_req; - struct sg_mapping_iter smi; - bool dma_active; + int max_freq; 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; + bool tap_requires_noclk; + bool calibrate_glitch; + bool cond_clock_glitch; spinlock_t irq_handler_lock; struct semaphore mmc_serializer; +#if IS_ENABLED(CONFIG_MMC_PSTORE) + bool pstore; +#endif struct gpio_desc *global_pwr_gpiod; atomic_t shared_power_users; 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 +162,42 @@ 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; + u32 hs400_tuning_block; /* Block number used for tuning */ + bool hs400_tuning_block_present; + +#define MMC_TIMINGS_COUNT ((MMC_TIMING_MMC_HS400) + 1) + u32 data_out_taps_dly[MMC_TIMINGS_COUNT]; + u32 cmd_out_taps_dly[MMC_TIMINGS_COUNT]; + u32 cmd_in_taps_dly[MMC_TIMINGS_COUNT]; + u32 data_in_taps_dly[MMC_TIMINGS_COUNT]; + /* + * Flags indicate input timings modified by user. + * Flag is set when cmd-in-XXX or data-in-XXX value is set for given + * mode in DT. They can be used to control behavior of the timings + * tuning alorithm. + */ + u32 in_timings_ctl; }; struct cvm_mmc_cr_type { @@ -161,6 +255,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 +278,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,16 +312,48 @@ 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) +#define MIO_EMM_DEBUG_CLK_DIS BIT_ULL(20) +#define MIO_EMM_DEBUG_RDSYNC BIT_ULL(21) /* Protoypes */ 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 +} + #endif |